如何用ffmpeg输出碎片化的mp4?

Posted

技术标签:

【中文标题】如何用ffmpeg输出碎片化的mp4?【英文标题】:How to output fragmented mp4 with ffmpeg? 【发布时间】:2012-01-26 20:39:28 【问题描述】:

ffmpeg -i infile.avi out.mp4 输出非分段 MP4。

如何获取碎片化的mp4?

更新 一个分段的 mp4 文件在内部被分成几个背靠背的块或 MPEG-4 电影片段。每个块都有自己的 moof atom - 因此文件中有几个 moof atom 交错,而不是像未分段的 mp4 那样在末尾有一个 moov。这使得在涉及缓冲的慢速网络上流式传输变得更容易

有几种工具,如mp4box,可以将普通的 mp4 转换为碎片化的。不幸的是,我们不能使用这样的东西

ffmpeg <options to output mp4> | mp4box

因为 ffmpeg 在生成 mp4 容器时不会生成可搜索的输出。

【问题讨论】:

您可能想要添加一些关于什么是“碎片化 mp4”的信息,以使可能熟悉 ffmpeg 但不了解碎片化 mp4 的人更容易理解这个问题。 好点!我已经编辑了我的问题 @SaptarshiBiswas 您是否在不使用 mp3box 的情况下解决了这个问题?你能分享解决方案吗?谢谢 【参考方案1】:

ffmpeg -h(但不是手册页)具有以下内容:

mp4 muxer AVOptions:  
-movflags          <flags> E.... MOV muxer flags
   rtphint                 E.... Add RTP hint tracks
-moov_size         <int>   E.... maximum moov size so it can be placed at the
                                 beginning
-frag_size         <int>   E.... maximum fragment size
-frag_duration     <int>   E.... maximum fragment duration
-rtpflags          <flags> E.... RTP muxer flags
   latm                    E.... Use MP4A-LATM packetization instead of
                                 MPEG4-GENERIC for AAC
-skip_iods          <int>   E.... Skip writing iods atom.
-iods_audio_profile <int>   E.... iods audio profile atom.
-iods_video_profile <int>   E.... iods video profile atom.

如果我看到一个碎片化的 mp4,我不知道如何识别它,但看起来 ffmpeg 确实对它们有一些(记录不充分的)支持。

【讨论】:

re:“如果我看到一个片段的 mp4,我不知道如何识别它”:) 它们看起来确实很相似。 :) 在“moov”的前面有一个“mvex”原子,让你知道它会被碎片化。在各种轨道子原子中将有相当少的实际数据信息。将有***“moof”“mdat”对,这是实际数据所在的位置。最后可能有一个“mfra”原子。 mp4box -info file 将指示 MP4 是否分片。【参考方案2】:

这应该可以解决问题:

ffmpeg -re -i infile.ext -g 52 \
-c:a aac -b:a 64k -c:v libx264 -b:v 448k \
-f mp4 -movflags frag_keyframe+empty_moov \
output.mp4
frag_keyframe 导致输出碎片化, empty_moov 会导致输出 100% 碎片化;如果没有这个,第一个片段将被混合为一个短片(使用moov),然后是片段中的其余媒体, -re 在直播时很有用(使用输入媒体帧率),如果您正在创建文件,请不要使用它, -g 52 强制(至少)每 52 帧为关键帧

要计算健康的关键帧间隔,请参阅我的流媒体服务器文档中有关 fragment sizes 的段落。 - 您也可以考虑使用 WebM,它是 H.264 的免费替代品(在某些平台上比碎片化 mp4 有更好的支持)。

重要提示:FFMpeg 的多路复用器会将每个轨道的 tkhdmdhd 原子中的 Duration 设置为 0xffffffff。这会导致某些播放器出现问题(例如 Quicktime 不会播放此类文件)。您应该找到一个工具并将其更改为零(0x00000000)。

【讨论】:

如果您对上述命令有疑问,您可能需要重新安装 ffmpeg。通过 brew 安装所有选项: brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-frei0r --with-libass --with-libvo-aacenc -- with-libvorbis --with-libvpx --with-opencore-amr --with-openjpeg --with-opus --with-rtmpdump --with-schroedinger --with-speex --with-theora --with-tools 是否可以将输出流式传输到 html5 而不是将其保存到文件中?使用http协议? @astralmaster AFAIK FFmpeg 没有 http 服务器套接字输出(只有客户端)。您必须将媒体从 VLC 等其他软件中反弹,或者如果您想为多个客户端提供服务,则 FFserver。 @vbence 不幸的是,FFServer 只有 linux 版本,我正在寻找 Windows 解决方案。 WebM 不是 H.264 的替代品。 WebM 是 mp4(容器)的替代品,因为 VP9 是 H.264(编解码器)的替代品【参考方案3】:

更新:将分段的 MP4 视为 ISMV(平滑流)文件。自 2012 年 1 月 27 日起,新版本 FFMPEG 0.10 能够复用到这种格式。

$ ffmpeg -h muxer=ismv
ismv muxer AVOptions:
-movflags          <flags> E.... MOV muxer flags
   rtphint                 E.... Add RTP hint tracks
   empty_moov              E.... Make the initial moov atom empty (not supported by QuickTime)
   frag_keyframe           E.... Fragment at video keyframes
   separate_moof           E.... Write separate moof/mdat atoms for each track
   frag_custom             E.... Flush fragments on caller requests
   isml                    E.... Create a live smooth streaming feed (for pushing to a publishing point)
-moov_size         <int>   E.... maximum moov size so it can be placed at the begin
-rtpflags          <flags> E.... RTP muxer flags
   latm                    E.... Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC
   rfc2190                 E.... Use RFC 2190 packetization instead of RFC 4629 for H.263
   skip_rtcp               E.... Don't send RTCP sender reports
-skip_iods         <int>   E.... Skip writing iods atom.
-iods_audio_profile <int>  E.... iods audio profile atom.
-iods_video_profile <int>  E.... iods video profile atom.
-frag_duration     <int>   E.... Maximum fragment duration
-min_frag_duration <int>   E.... Minimum fragment duration
-frag_size         <int>   E.... Maximum fragment size
-ism_lookahead     <int>   E.... Number of lookahead entries for ISM files

【讨论】:

【参考方案4】:

也许这会有所帮助。在下面的示例中,ffmpeg 获取 RTMP 提要的副本,然后使用 ffmpeg,它在 fMP4 中创建一个 HTTP 输出,可以被 IIS 或 Azure 入口点接受。

注意:原始编码器设置为2秒的关键帧间隔。

ffmpeg -i rtmp://ip of server:1935/name/streamkey -vcodec copy -acodec copy -nal-hrd cbr -movflags isml+frag_keyframe+separate_moof -f ismv http://url of entry point/entry-point.isml/Streams(feed1)

【讨论】:

以上是关于如何用ffmpeg输出碎片化的mp4?的主要内容,如果未能解决你的问题,请参考以下文章

物联网碎片化的一些思考

设计和编码一个非碎片化的静态内存池

智造参考|从碎片化到模块化:智能制造企业的共赢之路

给大家推荐两门课程,利用碎片化的时间去提升自己

在碎片MP4中运行的轨道是否必须以关键帧开始?

利用碎片化的时间逆袭进百度,我的面试经历你敢听吗?