MP4文件quick start探究

谢唯
2023-12-01

最近在Flash上实现MP4文件点播时,发现部分MP4文件在原有的播放器上无法播放,经过定位发现,原来是MP4 BOX搞的鬼!

什么是MP4 BOX?

对于一般的MP4文件,BOX顺序为:ftyp-moov-free-mdat.
而对于部分经过视频软件处理后的MP4文件,BOX顺序发生了改变:ftyp-free-mdat-moov.
对于这种顺序的MP4文件,在完整下载文件之前,无法获取moov信息,因此是无法实现边下载边播放的。

解决方案

  1. 对源文件进行重新编码
    既然BOX顺序有问题,可以从源头上进行处理:调整BOX顺序。工具qt-faststart即是实现该功能的利器。
    qt-faststart主页

    下载了qt-faststart.exe binary for Windows之后,通过cmd对def.mp4文件进行转化: qt-faststart.exe def.mp4 def_new.mp4
    转化后,box顺序果然发生了变化,播放正常。

使用AtomicParsley对MP4文件进行解析:

Atom ftyp @ 0 of size: 32, ends @ 32
Atom free @ 32 of size: 8, ends @ 40
Atom mdat @ 40 of size: 1025668, ends @ 1025708
Atom moov @ 1025708 of size: 13925, ends @ 1039633
     Atom mvhd @ 1025716 of size: 108, ends @ 1025824
     Atom trak @ 1025824 of size: 6608, ends @ 1032432
         Atom tkhd @ 1025832 of size: 92, ends @ 1025924
         Atom edts @ 1025924 of size: 36, ends @ 1025960
             Atom elst @ 1025932 of size: 28, ends @ 1025960
         Atom mdia @ 1025960 of size: 6472, ends @ 1032432
             Atom mdhd @ 1025968 of size: 32, ends @ 1026000
             Atom hdlr @ 1026000 of size: 45, ends @ 1026045
             Atom minf @ 1026045 of size: 6387, ends @ 1032432
                 Atom vmhd @ 1026053 of size: 20, ends @ 1026073
                 Atom dinf @ 1026073 of size: 36, ends @ 1026109
                     Atom dref @ 1026081 of size: 28, ends @ 1026109
                 Atom stbl @ 1026109 of size: 6323, ends @ 1032432
                     Atom stsd @ 1026117 of size: 167, ends @ 1026284
                         Atom avc1 @ 1026133 of size: 151, ends @ 1026284
                             Atom avcC @ 1026219 of size: 49, ends @ 1026268
                             Atom pasp @ 1026268 of size: 16, ends @ 1026284
                 ~
                     Atom stts @ 1026284 of size: 24, ends @ 1026308
                     Atom stss @ 1026308 of size: 24, ends @ 1026332
                     Atom ctts @ 1026332 of size: 3008, ends @ 1029340
                     Atom stsc @ 1029340 of size: 40, ends @ 1029380
                     Atom stsz @ 1029380 of size: 1532, ends @ 1030912
                     Atom stco @ 1030912 of size: 1520, ends @ 1032432
     Atom trak @ 1032432 of size: 7104, ends @ 1039536
         Atom tkhd @ 1032440 of size: 92, ends @ 1032532
         Atom edts @ 1032532 of size: 36, ends @ 1032568
             Atom elst @ 1032540 of size: 28, ends @ 1032568
         Atom mdia @ 1032568 of size: 6968, ends @ 1039536
             Atom mdhd @ 1032576 of size: 32, ends @ 1032608
             Atom hdlr @ 1032608 of size: 45, ends @ 1032653
             Atom minf @ 1032653 of size: 6883, ends @ 1039536
                 Atom smhd @ 1032661 of size: 16, ends @ 1032677
                 Atom dinf @ 1032677 of size: 36, ends @ 1032713
                     Atom dref @ 1032685 of size: 28, ends @ 1032713
                 Atom stbl @ 1032713 of size: 6823, ends @ 1039536
                     Atom stsd @ 1032721 of size: 103, ends @ 1032824
                         Atom mp4a @ 1032737 of size: 87, ends @ 1032824
                             Atom esds @ 1032773 of size: 51, ends @ 1032824
                     Atom stts @ 1032824 of size: 24, ends @ 1032848
                     Atom stsc @ 1032848 of size: 2524, ends @ 1035372
                     Atom stsz @ 1035372 of size: 2644, ends @ 1038016
                     Atom stco @ 1038016 of size: 1520, ends @ 1039536
     Atom udta @ 1039536 of size: 97, ends @ 1039633
         Atom meta @ 1039544 of size: 89, ends @ 1039633
             Atom hdlr @ 1039556 of size: 33, ends @ 1039589
             Atom ilst @ 1039589 of size: 44, ends @ 1039633
                 Atom ?too @ 1039597 of size: 36, ends @ 1039633
                     Atom data @ 1039605 of size: 28, ends @ 1039633

 ~ denotes an unknown atom
------------------------------------------------------
Total size: 1039633 bytes; 51 atoms total. AtomicParsley version: 0.9.0 (utf16)
Media data: 1025668 bytes; 13965 bytes all other atoms (1.343% atom overhead).
Total free atom space: 8 bytes; 0.001% waste.
------------------------------------------------------
修改后:
Atom ftyp @ 0 of size: 32, ends @ 32
Atom moov @ 32 of size: 13925, ends @ 13957
     Atom mvhd @ 40 of size: 108, ends @ 148
     Atom trak @ 148 of size: 6608, ends @ 6756
         Atom tkhd @ 156 of size: 92, ends @ 248
         Atom edts @ 248 of size: 36, ends @ 284
             Atom elst @ 256 of size: 28, ends @ 284
         Atom mdia @ 284 of size: 6472, ends @ 6756
             Atom mdhd @ 292 of size: 32, ends @ 324
             Atom hdlr @ 324 of size: 45, ends @ 369
             Atom minf @ 369 of size: 6387, ends @ 6756
                 Atom vmhd @ 377 of size: 20, ends @ 397
                 Atom dinf @ 397 of size: 36, ends @ 433
                     Atom dref @ 405 of size: 28, ends @ 433
                 Atom stbl @ 433 of size: 6323, ends @ 6756
                     Atom stsd @ 441 of size: 167, ends @ 608
                         Atom avc1 @ 457 of size: 151, ends @ 608
                             Atom avcC @ 543 of size: 49, ends @ 592
                             Atom pasp @ 592 of size: 16, ends @ 608
         ~
                     Atom stts @ 608 of size: 24, ends @ 632
                     Atom stss @ 632 of size: 24, ends @ 656
                     Atom ctts @ 656 of size: 3008, ends @ 3664
                     Atom stsc @ 3664 of size: 40, ends @ 3704
                     Atom stsz @ 3704 of size: 1532, ends @ 5236
                     Atom stco @ 5236 of size: 1520, ends @ 6756
     Atom trak @ 6756 of size: 7104, ends @ 13860
         Atom tkhd @ 6764 of size: 92, ends @ 6856
         Atom edts @ 6856 of size: 36, ends @ 6892
             Atom elst @ 6864 of size: 28, ends @ 6892
         Atom mdia @ 6892 of size: 6968, ends @ 13860
             Atom mdhd @ 6900 of size: 32, ends @ 6932
             Atom hdlr @ 6932 of size: 45, ends @ 6977
             Atom minf @ 6977 of size: 6883, ends @ 13860
                 Atom smhd @ 6985 of size: 16, ends @ 7001
                 Atom dinf @ 7001 of size: 36, ends @ 7037
                     Atom dref @ 7009 of size: 28, ends @ 7037
                 Atom stbl @ 7037 of size: 6823, ends @ 13860
                     Atom stsd @ 7045 of size: 103, ends @ 7148
                         Atom mp4a @ 7061 of size: 87, ends @ 7148
                             Atom esds @ 7097 of size: 51, ends @ 7148
                     Atom stts @ 7148 of size: 24, ends @ 7172
                     Atom stsc @ 7172 of size: 2524, ends @ 9696
                     Atom stsz @ 9696 of size: 2644, ends @ 12340
                     Atom stco @ 12340 of size: 1520, ends @ 13860
     Atom udta @ 13860 of size: 97, ends @ 13957
         Atom meta @ 13868 of size: 89, ends @ 13957
             Atom hdlr @ 13880 of size: 33, ends @ 13913
             Atom ilst @ 13913 of size: 44, ends @ 13957
                 Atom ?too @ 13921 of size: 36, ends @ 13957
                     Atom data @ 13929 of size: 28, ends @ 13957
Atom free @ 13957 of size: 8, ends @ 13965
Atom mdat @ 13965 of size: 1025668, ends @ 1039633

 ~ denotes an unknown atom
------------------------------------------------------
Total size: 1039633 bytes; 51 atoms total. AtomicParsley version: 0.9.0 (utf16)
Media data: 1025668 bytes; 13965 bytes all other atoms (1.343% atom overhead).
Total free atom space: 8 bytes; 0.001% waste. Padding available: 8 bytes.
------------------------------------------------------
  1. 客户端动态加载BOX
    对于自有内容网站来说,对自身视频库进行转码并不麻烦。但是对于第三方公司来说,可能无法去对甲方庞大的视频库进行处理,更理想的方式,是从客户端及时获取moov信息并实现播放。

//TODO

参考文章:

  1. http://blog.zhourunsheng.com/2012/05/android-视频播放之流媒体格式处理/
  2. http://stackoverflow.com/questions/19803458/how-to-download-only-the-moov-atom-from-mp4-file
 类似资料: