将 FFMPEG 编码为 MPEG-DASH - 或带有关键帧集群的 WebM - 用于 MediaSource API

Posted

技术标签:

【中文标题】将 FFMPEG 编码为 MPEG-DASH - 或带有关键帧集群的 WebM - 用于 MediaSource API【英文标题】:Encoding FFMPEG to MPEG-DASH – or WebM with Keyframe Clusters – for MediaSource API 【发布时间】:2014-07-31 21:55:39 【问题描述】:

我目前正在向 Chrome 发送视频流,以通过 MediaSource API 播放。

据我了解,MediaSource 仅支持使用 MPEG-DASH 编码的 MP4 文件,或具有以关键帧开头的簇的 WebM 文件(否则会引发错误:媒体段未以关键帧开头)。

有没有办法使用 FFMPEG 实时编码 MPEG-DASH 或关键帧 WebM 格式?

编辑:

我刚刚用ffmpeg ... -f webm -vcodec vp8 -g 1 尝试过,这样每一帧都是关键帧。不是理想的解决方案。它现在可以与 MediaStream 一起使用。有什么方法可以将片段与 WebM 中的关键帧同步,这样就不需要每一帧都是关键帧?


关于 WebM / MP4 和 MediaSource 的参考问题:

Media Source Api not working for a custom webm file (Chrome Version 23.0.1271.97 m)

MediaSource API and mp4

【问题讨论】:

【参考方案1】:

目前 FFMPEG 不支持 DASH 编码。您可以使用 FFMPEG (https://www.ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment) 进行分段,但我建议将 FFMPEG 和 MP4Box 结合使用。使用 FFMPEG 对您的直播视频进行转码,然后使用 MP4Box 进行分段并创建 .mpd 索引。

MP4Box 是 GPAC (http://gpac.wp.mines-telecom.fr/) 的一部分。

这是一个使用 h264 的示例:

ffmpeg -threads 4 -f v4l2 -i  /dev/video0 -acodec libfaac -ar 44100 -ab 128k -ac 2 -vcodec libx264 -r 30 -s 1280x720  -f mp4 -y "$movie" > temp1.mp4 && MP4Box -dash 10000 -frag 1000 -rap "$movie"

如果您需要 VP8 (WebM),请使用:-vcodec libvpx-f webm-f ts

【讨论】:

谢谢 Cibráne。 MP4Box 是否能够对实时管道进行编码?我们要进行低延迟的直播。任何进一步的建议将不胜感激!或者有没有办法直接从 FFMPEG 流式传输 WebM,每个集群都有关键帧? 是的,您可以使用 MP4Box 对实时视频进行分段。思路就在这里:slideshare.net/cconcolato/…对于sgementer是同一个工作段VP8或H264。 这仍然是最新的吗?看起来现在至少有一些有限的 DASH 支持。 ffmpeg.org/ffmpeg-formats.html#webm_005fdash_005fmanifest【参考方案2】:

另一位用户运气不错:

ffmpeg ... \
  -f mp4 \
  -reset_timestamps 1 \
  -movflags empty_moov+default_base_moof+frag_keyframe \
  -probesize 200000

请参阅 galbarm 的问题:

Live streaming dash content using mp4box Flush & Latency Issue with Fragmented MP4 Creation in FFMPEG

注意:如果输入视频没有关键帧,可能需要设置:

-frag_duration 100000

...而不是+frag_keyframe

【讨论】:

我认为这个(原始)答案对于一些正在做超低延迟实时蒸汽的人来说可能仍然非常有用,所以我暂时把它留在这里。如果您认为此答案无效,请告诉我,我将其删除。 (或者,如果您有更好的零延迟流媒体解决方案,请发布!)【参考方案3】:

要确保 WebM 中的每个集群都以关键帧开头,请尝试以下操作:

ffmpeg \
  [...inputs] \
  -vcodec libvpx \
  -keyint_min 60 \
  -g 60 \
  -vb 4000k \
  -f webm \
  -cluster_size_limit 10M \
  -cluster_time_limit 2100 \
  [...output]

基本上,在实施时,每个关键帧都必须位于集群的开头,但反之则不然。也就是说,在关键帧上会有一个新的簇,但在新的簇上不一定有一个关键帧。为了解决这个问题,我们只需将集群大小设置为我们永远不会遇到的大值。

在此示例中,我们将每 2 秒有一个关键帧,并且集群时间限制为 2.1 秒,因此我们永远不会命中它。比特率为 4Mbit,集群大小限制为 10M 左右。不确定它是位还是字节,但没关系,因为我们永远不会击中它,因为我将它设置得比它需要的大得多。

【讨论】:

这非常有用,现在应该是公认的答案。 我同意!另外,布拉德对这些东西了解太多了:)【参考方案4】:

我在尝试使用 MediaSource Extensions (MSE) 播放由 MediaRecorder API 录制的 .webm 文件时遇到了同样的情况。 Chrome (51) 录音格式错误,Firefox (46) 似乎还可以。

要使其正常工作,您必须修复 .webm 文件中的提示:

    克隆https://github.com/webmproject/libwebm 确保您的 cmake 版本 >= 3.2 (https://askubuntu.com/questions/610291/how-to-install-cmake-3-2-on-ubuntu-14-04) cmake . make ./sample_muxer -i original.webm -o fixed.webm 将 fixed.webm 加载到 DASH / 您自己的播放器中!

希望它对某人有所帮助。在没有 DASH 关键字的情况下搜索任何信息非常困难(我没有使用 DASH,仅使用相同的底层技术 - MSE):)

【讨论】:

你也可以在Windows下使用Visual Studio编译libwebm。它就像一个魅力。

以上是关于将 FFMPEG 编码为 MPEG-DASH - 或带有关键帧集群的 WebM - 用于 MediaSource API的主要内容,如果未能解决你的问题,请参考以下文章

使用 FFMPEG 播放 MPEG-dash 流[关闭]

如何使用 ffmpeg 为 Chromecast 创建 DASH VOD?

是否可以使用 MPEG-DASH 流式传输多帧率视频?

用于实时流媒体的 MPEG-DASH 编码

具有安全 S3 URL 的 MPEG-Dash

如何将yuv编码为h264,自己编码或者ffmpeg都可以。