在網際網路常見的格式中,跨平台最好的應該就屬MP4檔案了。因為MP4檔案既可以在PC平台的Flashplayer中播放,又可以在移動平台的Android、iOS等平台中進行播放,而且使用系統預設的播放器即可以播放。
MP4格式是最常見的多媒體檔案格式。
一、MP4 格式标準介紹
MP4格式标準為ISO-14496 Part 12、ISO-14496 Part 14,标準内容不是很多,下面我們來介紹一下格式标準中一些重要的資訊。
MP4是一種描述較為全面的容器格式,被認為可以在其中嵌入任何形式的資料,各種編碼的視訊、音頻等都不在話下,常見的大部分的MP4檔案存放的AVC(H.264)或MPEG-4(Part 2)編碼的視訊和AAC編碼的音頻。MP4格式的官方檔案字尾名是“.mp4”,還有其他的以mp4為基礎進行的擴充或者是閹割版的格式,如:M4V, 3GP, F4V等。
MP4是由一個個“Box”組成的,大Box中存放小Box,一級嵌套一級來存放媒體資訊。下面我們來楚關于Box的幾個概念:
MP4檔案由許多個Box與FullBox組成。
每個Box由Header和Data兩部分組成。
FullBox是Box的擴充,其在Box結構的基礎上,在Header中增加8位version标志和24的flags标志。
Header包含了整個Box的長度的大小(size)和類型(type),當size等于0時,代表這個Box是檔案的最後一個Box。當size等于1時,說明Box長度需要更多的位來描述,在後面會自定義一個64位的largesize用來描述Box的長度。當type等于uuid時,說明這個Box中的資料是使用者自定義擴充類型。
Data為Box的實際資料,可以是純資料,也可以是更多的子Box。
當一個Box中Data是一系列的子Box時,這個Box又可以稱為Container(容器)Box。
MP4常用參考标準Box排列方式:https://github.com/renhui/Thinking-in-AV/tree/master/多媒體格式/MP4。
介紹了MP4的格式标準後,下面我們來介紹是三個MP4分析工具,為後續了解MP4檔案一些關鍵資訊做輔助工具。
二、MP4分析工具
可以用來分析MP4封裝格式的工具比較多,除了FFmpeg、FFprobe之外,還有一些常用的工具,如Elecard StreamEye、mp4box、mp4info等;下面簡單介紹一下這幾款常用的工具:
Elecard StreamEye是一款非常強大的視訊資訊檢視工具,能夠檢視幀的排列資訊,将I幀、P幀、B幀以不同顔色的柱狀展現出來,而且柱的長短将根據幀的大小展示。還能夠通過Elecard StreamEye分析MP4的封裝的内容資訊,包括流資訊、宏塊的資訊、檔案頭頂額資訊、圖像的資訊以及檔案的資訊等。還能根據每一幀的順序逐幀檢視,可以看到每一幀的詳細資訊與狀态。
示例如圖:

mp4box 是GPAC項目中的一個元件,可以通過mp4box針對媒體檔案進行合成、拆解等操作。
官網位址:https://gpac.wp.imt.fr/mp4box/。
其使用時的常用指令如下:
而通過mp4box也可以檢視mp4的資訊,其輸出内容格式非常類似ffprobe檢視的資訊,不過想對ffprobe更完善。
mp4info是一個不錯的MP4分析工具,而且是可視化的工具,可以将MP4中的各個Box解析出來,并将其中的資料展現出來。分析MP4檔案内容時使用mp4info将會更友善。
結合着此工具,了解MP4的Box會更友善,更直覺。
三、MP4格式重要Box
該Box有且隻有1個,并且隻能被包含在檔案層,而不能被其他Box包含。該Box應該被放在檔案的最開始,訓示該MP4檔案應用的相關資訊。
“ftyp” body依次包括1個32位的major brand(4個字元),1個32位的minor version(整數)和1個以32位(4個字元)為機關元素的數組Compatible Brands。
該box包含了檔案媒體的metadata資訊,“moov”是一個container box,具體内容資訊由子box诠釋。同File Type Box一樣,該box有且隻有一個,且隻被包含在檔案層。一般情況下,“moov”會緊随“ftyp”出現。
moov定義了一個MP4檔案中的資料資訊,類型是moov,是一個容器Atom,其至少必須包含一下三種Atom中的一種:mvhd标簽、cmov标簽、rmra标簽。
mvhd标簽:Movie Header Atom,存放未壓縮過的影片資訊的頭容器。
cmov标簽:Compressed Movie Atom,壓縮鬼哦的電影資訊容器,此容器不常用。
rmra标簽:Reference Movie Atom,參考電影資訊容器,此容器不常用。
一般情況下,“moov”中會包含1個“mvhd”和若幹個“trak”。其中“mvhd”為Header Box,一般作為“moov”的第一個子Box出現(對于其他Container Box來說,Header Box都應作為首個子box出現)。“trak”包含了一個track的相關資訊,是一個Container Box。
“trak”也是一個container box,其子box包含了該track的媒體資料引用和描述(hint track除外)。一個MP4檔案中的媒體可以包含多個track,且至少有一個track,這些track之間彼此獨立,有自己的時間和空間資訊。“trak”必須包含一個“tkhd”和一個“mdia”,此外還有很多可選的box(略)。其中“tkhd”為track header box,“mdia”為media box,該box是一個包含一些track媒體資料資訊box的container box。
該box包含于檔案層,可以有多個,也可以沒有(當媒體資料全部為外部檔案引用時),用來存儲媒體資料。資料直接跟在box type字段後面,具體資料結構的意義需要參考metadata(主要在sample table中描述)。
“free”中的内容是無關緊要的,可以被忽略。該box被删除後,不會對播放産生任何影響。
“stbl”幾乎是普通的MP4檔案中最複雜的一個box了,首先需要回憶一下sample的概念。sample是媒體資料存儲的機關,存儲在media的chunk中,chunk和sample的長度均可互不相同,如下圖所示。
普通MP4檔案的結構重要的部分就講完了,了解起來可能比較亂,下面這張圖是常見的box的樹結構圖,可以用來大緻了解MP4檔案的構造。
在MP4檔案中,Box的結構與上圖中所描述的一般沒太大的差别。
四、MP4格式 與 FFmpeg實戰
使用指令行 ffmpeg -h demuxder=mp4 檢視MP4檔案的Demuxer資訊:
正常情況下,ffmpeg生成的moov是在mdat寫完成後再寫入的。
下面是一個例子:
使用mp4info檢視容器出現的順序,如圖:
可以看出moov box是在mdat的下面。這時,我們可以使用faststart将上圖的moov移動到mdat前面。
使用如下指令行:
然後使用mp4info檢視MP4的容器順序,就可以看到moov被移動到mdat前面了。如下圖所示:
因為MP4的标準中描述的moov與mdat的存放位置前後并沒有強制要求,所有有些時候moov這個Box在mdat的後面,有時候在mdat的前面。
在網際網路的視訊點播中,如果希望MP4檔案被快速打開,則需要moov存放在mdat的前面;如果放在後面,則需要将MP4檔案下載下傳完成後才可以進行播放。