我正在尝试创建一个可以在当前状态下播放的 mp4 文件,即使编码器中的所有位都没有进入磁盘。这可能是由于将文件存储在网络文件系统上失败,或者是由于进行编码的机器突然发生故障(例如,电源断开)。我正在使用 ffmpeg 直接从实时视频源中读取并创建 mp4 文件。但是,我注意到的是,如果出现中断并且 ffmpeg 无法在最后正确关闭文件,那么我尝试过的任何播放器都会使其无法播放。
用于模拟失败的方法是将文件存储在本地,然后将其 rsync 到新文件并尝试播放。通过这种方式,文件在特定时间点的当前状态用于模拟在编码中断时文件将处于的状态。另一种更简单的方法是在文件被编码时直接尝试播放文件。这些方法都不能成功播放文件。
我尝试使用该-movflags +faststart
选项(我也尝试过不使用+
),因为此选项将 moov atom 移动到视频的开头;没有它,在编码完成之前无法播放文件。当我尝试此选项时,我注意到视频文件不是以小块的形式写入磁盘,而是以 256kB 的块开始更新。但是,除非且直到 ffmpeg 正确终止写入,否则视频仍然不会播放。其他研究表明,此选项要求视频文件已完成录制。
运行ffmpeg -h full
我还看到有一个isml
选项应该用于“创建实时流畅的流媒体源”,但这也不能解决问题。
如果录制因故障中断,我如何才能真正使视频能够容忍不完整的录制并继续播放?
这对于常规MP4是不可能的,因为播放文件需要元数据,并且在构建文件时元数据保存在内存中。处理完所有媒体后,元数据将最终确定并写入磁盘。所做的是
faststart
将此元数据写入文件的头部而不是尾部。但是写入仍然发生在操作结束时。但是,即使 ffmpeg 在中途被杀,碎片化的 MP4 也可以使用 -大多数书面媒体都是可见的。
大多数现代播放器支持分段 MP4,但有些可能无法正确显示搜索栏上的持续时间或进度状态。
您可以通过重新混合将碎片化的 MP4 转换为常规 MP4。