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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24152810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:00:55  来源:igfitidea点击:

Encoding FFMPEG to MPEG-DASH – or WebM with Keyframe Clusters – for MediaSource API

htmlvideoffmpegh.264webm

提问by Chris Nolet

I'm currently sending a video stream to Chrome, to play via the MediaSource API.

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

As I understand it, MediaSource only supports MP4 files encoded with MPEG-DASH, or WebM files that have clusters beginning with keyframes (otherwise it raises the error: Media segment did not begin with keyframe).

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

Is there any way to encode in MPEG-DASH or keyframed WebM formats with FFMPEG in real-time?

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

Edit:

编辑:

I just tried it with ffmpeg ... -f webm -vcodec vp8 -g 1so that every frame is a keyframe. Not the ideal solution. It does work with MediaStream now though. Any way to sync up the segments with the keyframes in WebM so not every frame needs to be a keyframe?

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



Reference Questions on WebM / MP4 and MediaSource:

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

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

媒体源 Api 不适用于自定义 webm 文件(Chrome 版本 23.0.1271.97 m)

MediaSource API and mp4

MediaSource API 和 mp4

采纳答案by Brad

To ensure every cluster in your WebM starts with a keyframe, try something like this:

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

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

Basically, as implemented, every keyframe has to be at the beginning of a cluster but the inverse is not true. That is, on key frame there will be a new cluster, but on new cluster there won't necessarily be a keyframe. To get around this issue, we simply set the cluster size to something large that we'll never hit.

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

In this example, we'll have a keyframe every 2 seconds, and the cluster time limit is 2.1 seconds, so we'll never hit it. The bitrate is 4Mbit, and the cluster size limit is 10M-something. Not sure if it's bit or byte there but it doesn't matter as we'll never hit it as I've set it much greater than it needs to be.

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

回答by Cibrán Docampo

At the moment FFMPEG does not support DASH encoding. You can segment with FFMPEG (https://www.ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment), but I recommend combining FFMPEG and MP4Box. Use FFMPEG to transcode your live video, and then MP4Box to segment and create the .mpd index.

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

MP4Box is a part of GPAC (http://gpac.wp.mines-telecom.fr/).

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

Here is an example using h264:

下面是一个使用 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"

If you need VP8 (WebM), use: -vcodec libvpxand -f webmor -f ts.

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

回答by Chris Nolet

Another user has had some luck with:

另一位用户有一些运气:

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

Please see see galbarm's questions at:

请参阅 galbarm 的问题:

Note: If you don't have keyframes on the input video, you may need to set:

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

-frag_duration 100000

... instead of +frag_keyframe.

... 而不是+frag_keyframe.

回答by lukyer

I ran into the same situation when trying to play recorded .webm file by MediaRecorder APIback using Media Source Extensions(MSE). Chrome (51) recordings are malformed, Firefox (46) seems OK.

尝试使用Media Source Extensions(MSE)播放MediaRecorder API录制的 .webm 文件时,我遇到了同样的情况。Chrome (51) 录音格式错误,Firefox (46) 似乎没问题。

To get it working you have to fix cues in .webm file:

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

  1. clone https://github.com/webmproject/libwebm
  2. make sure you have cmake version >= 3.2 (https://askubuntu.com/questions/610291/how-to-install-cmake-3-2-on-ubuntu-14-04)
  3. cmake .
  4. make
  5. ./sample_muxer -i original.webm -o fixed.webm
  6. load fixed.webm into DASH / your own player!
  1. 克隆https://github.com/webmproject/libwebm
  2. 确保你有 cmake 版本 >= 3.2 ( https://askubuntu.com/questions/610291/how-to-install-cmake-3-2-on-ubuntu-14-04)
  3. cmake .
  4. make
  5. ./sample_muxer -i original.webm -o fixed.webm
  6. 将 fixed.webm 加载到 DASH/您自己的播放器中!

Hope it helped someone. It was quite difficult to google any information without the DASH keyword (i am not using DASH, only the same underlying technology - MSE) :)

希望它对某人有所帮助。如果没有 DASH 关键字,谷歌搜索任何信息都非常困难(我没有使用 DASH,只使用相同的底层技术 - MSE):)