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

时间:2014-06-11 00:13:18

标签: html5 video ffmpeg h.264 webm

我目前正在向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

4 个答案:

答案 0 :(得分:11)

目前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

答案 1 :(得分:9)

另一位用户运气不错:

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

请参阅以下链接查看galbarm的问题:

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

-frag_duration 100000

...而不是+frag_keyframe

答案 2 :(得分:4)

我在尝试使用 MediaRecorder API 播放录制的.webm文件时遇到了相同的情况媒体源扩展程序(MSE)。 Chrome(51)录音格式不正确,Firefox(46)似乎没问题。

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

  1. clone 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 /您自己的播放器中!
  7. 希望它有所帮助。没有DASH关键字谷歌任何信息是很困难的(我不使用DASH,只有相同的基础技术 - MSE):)

答案 3 :(得分:4)

要确保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。不确定它是否有位或字节,但它没关系,因为我们永远不会打它,因为我设置它比它需要的大得多。