将 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的主要内容,如果未能解决你的问题,请参考以下文章