掉电安全的mp4文件生成方案

作者:quink
来源:Fun With FFmpeg
原文:https://mp.weixin.qq.com/s/rYwVP0YUsD2t87invJXDCw

1. 传统mp4不是掉电安全的

众所周知,mp4文件生成过程中,如果异常退出,比如程序崩溃,设备异常掉电等,生成的不完整的mp4文件是无法使用的。也许特定条件可以抢救一下,比如只有视频轨,我对通用的修复不完整mp4文件的方案不抱希望。

mp4(超)简化结构如下,mdat是音视频数据,moov是全局描述+索引信息。

掉电安全的mp4文件生成方案

2. fmp4掉电安全

实际上,前一段描述不准确:mp4中的fmp4是掉电安全的。传统的mp4有一个全局的索引信息,丢了全局索引,不知道音视频数据如何分割。全局的索引信息对fmp4来说是可选项,没有全局索引的fmp4也可以播放,只是seek困难。

我们可以用如何方式模拟实时录制成fmp4:

ffmpeg -re -i ~/Movies/cctv.mp4 -c copy -movflags cmaf /tmp/test.mp4

运行过程中kill掉

killall -9 ffmpeg

你会发现生成的mp4可以播放。注意这里是kill -9 SIGKILL,如果你用killall ffmpeg,ffmpeg会捕获signal SIGTERM后正常退出,不能模拟异常退出。

fmp4简化结构示意如下:

掉电安全的mp4文件生成方案

moov里有全局的表述,标记了有几个音频轨、视频轨信息等等,但是不包含音视频数据的位置信息。moof + mdat是一个片段,fmp4可以看成一个moov头加N个片段。moof里描述了对应的mdat的音视频数据信息,有多少个sample(音视频帧)、sample的大小、在文件中的位置等等。尾巴掉了,不影响前面数据正常播放。

这里省略了fmp4的全局索引描述信息。fmp4至少有两种全局索引描述方式:sidx和mfra。和本文无关,不深入探讨了。

3. 我全都要

fmp4虽然有掉电安全的优点,也有缺点,主要是本地播放兼容性不如传统的mp4。如果我既要fmp4的掉电安全,又要传统mp4的兼容性,怎么办呢?

很简单,先生成fmp4,如果正常结束,在结束的时候做个变身,把fmp4变成传统mp4。变身过程示意如下。

先给fmp4加个带全局索引的moov尾巴:

掉电安全的mp4文件生成方案

再调整fmp4原来的moov,把它变成一个大的mdat。虚线部分是原来的moof和mdat,被包在新的mdat里,属于不可见信息了。如此生成的文件,对于播放器来说是传统mp4,只是内部有一些空洞/无效数据(旧的moof等。因为mp4访问音视频数据是靠moov的索引,这些无效数据不影响音视频数据正常读取。

掉电安全的mp4文件生成方案

4. 说说简单,代码呢?

请看FFmpeg:

https://github.com/FFmpeg/FFmpeg/commit/6ec22731ae7

掉电安全的mp4文件生成方案

用法简单,把前面的命令增加一个hybrid_fragmented

./ffmpeg -re -i ~/Movies/cctv.mp4 -c copy -movflags cmaf+hybrid_fragmented /tmp/test.mp4

然后你用killall -9 ffmpeg杀进程,会发现生成了一个fmp4,如果进程正常退出,生成的是传统的mp4。

让我们感谢Martin Storsjö实现的这个功能.

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论