理解 MP4 moov atom
在上一篇关于 Html5 流播放器 的文章中提到,边下载边播放这个功能需要媒体文件的支持。为了能进一步理解这句话的意思,查阅了一些相关资料,整理成文。
MP4 moov atom
atom 是 MP4 文件里的一个数据单元,它可以包含关于视频文件的各种信息。
moov atom,即 movie atom,定义了 timescale、duration 以及其它子 atom 信息。
可以想见,若要在视频文件未能被完整下载前即开始播放,并能跳转到指定位置,肯定要首先获知其 moov atom 信息。这也是 moov atom 存在的意义。
解析 MP4 文件中的 moov atom
- FFmpeg 命令行
Linux 下:
1 | ffmpeg -v trace -i videofile.mp4 2>&1 | grep -e 'moov' |
Windows PowerShell:
1 | .\ffmpeg.exe -v trace -i videofile.mp4 2>&1 | Select-String 'moov' |
输出如下信息:
1 | [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fffd6030080] type:'moov' parent:'root' sz: 620709 229758438 230379139 |
第一列数字为 atom 字节数,第二列为文件中起始字节数,第三列为结束位置。
如果文件里没有 moov atom,输出为空。
- 其它工具
添加 moov atom / 调整 moov atom 位置
像上边示例输出显示的那样,一些 MP4 的 moov atom 是放在文件末尾位置的,这起不到想要的作用,必须把它调整到文件开始位置。更甚者,一些 MP4 文件根本没有 moov atom 信息。可以以同样的方法添加。
- FFmpeg 命令行
1 | .\ffmpeg.exe -i input.mp4 -c copy -map 0 -movflags faststart output.mp4 |
- 其它工具
疑问
实测发现,moov atom 在文件末尾的时候,也是能达到边下载边播放效果的。(PC Chrome 93.0.4577.82) 但是会触发三次请求。
第一次:
Request:Range: bytes=0-
Response:Content-Range: bytes 0-230379138/230379139
第二次:
Request:Range: bytes=229736448-
Response:Content-Range: bytes 229736448-230379138/230379139
第三次:
Request:Range: bytes=32768-
Response:Content-Range: bytes 32768-230379138/230379139
神奇的纠错能力,不知道是 Chrome 还是 Video.js 做出的贡献。
参考
Movie Atoms:https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html
Understanding the MPEG-4 moov atom: Pseudo-Streaming in Mp4:https://sanjeev-pandey.medium.com/understanding-the-mpeg-4-moov-atom-pseudo-streaming-in-mp4-93935e1b9e9a
Problems with playback:https://docs.videojs.com/tutorial-troubleshooting.html#problems-with-playback
4.22 mov, mp4, ismv:https://ffmpeg.org/ffmpeg-formats.html#mov_002c-mp4_002c-ismv