1. 程式人生 > >多媒體文件格式(一):MP4 格式

多媒體文件格式(一):MP4 格式

可視化 可能 不能 -c ovf alt fps ng- mda

在互聯網常見的格式中,跨平臺最好的應該就屬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排列方式

技術分享圖片

(圖內容有點多,看不清楚的,可以保存圖片到本地後放大查看)

也可以到本人的github上下載原圖:https://github.com/renhui/Thinking-in-AV/tree/master/多媒體格式/MP4

介紹了MP4的格式標準後,下面我們來介紹是三個MP4分析工具,為後續理解MP4文件一些關鍵信息做輔助工具。

二、MP4分析工具

可以用來分析MP4封裝格式的工具比較多,除了FFmpeg、FFprobe之外,還有一些常用的工具,如Elecard StreamEye、mp4box、mp4info等;下面簡單介紹一下這幾款常用的工具:

1. Elecard StreamEye

Elecard StreamEye是一款非常強大的視頻信息查看工具,能夠查看幀的排列信息,將I幀、P幀、B幀以不同顏色的柱狀展現出來,而且柱的長短將根據幀的大小展示。還能夠通過Elecard StreamEye分析MP4的封裝的內容信息,包括流信息、宏塊的信息、文件頭頂額信息、圖像的信息以及文件的信息等。還能根據每一幀的順序逐幀查看,可以看到每一幀的詳細信息與狀態。

示例如圖:

技術分享圖片

2. mp4box

mp4box 是GPAC項目中的一個組件,可以通過mp4box針對媒體文件進行合成、拆解等操作。

官網地址:https://gpac.wp.imt.fr/mp4box/。

其使用時的常用命令如下:

    1) mp4box -h
       查看mp4box中的所有幫助信息

    2) mp4box -h general
       查看mp4box中的通用幫助信息

    3) mp4box -info test.mp4 
       查看test.mp4文件是否有問題

    4) mp4box   -add    test.mp4   test-new.mp4
       修復test.mp4文件格式不標準的問題,並把新文件保存在test-new.mp4中

    5) mp4box  -inter  10000 test-new.mp4 
       解決開始播放test-new.mp4卡一下的問題,為HTTP下載快速播放有效,10000ms

    6) mp4box -add file.avi new_file.mp4
       把avi文件轉換為mp4文件

    7) mp4box -hint file.mp4 
       為RTP準備,此指令將為文件創建RTP提示跟蹤信息。這使得經典的流媒體服務器像darwinstreamingserver或QuickTime的流媒體服務器通過RTSP/RTP傳輸文件

    8) mp4box -cat test1.mp4 -cat test2.mp4 -new test.mp4 
       把test1.mp4和test2.mp4合並到一個新的文件test.mp4中,要求編碼參數一致

    9) mp4box -force-cat test1.mp4 -force-cat test2.mp4 -new test.mp4 
       把test1.mp4和test2.mp4強制合並到一個新的文件test.mp4中,有可能不能播放

    10) mp4box -add video1.264 -cat video2.264 -cat video3.264 -add audio1.aac -cat audio2.aac -cat audio3.aac -new muxed.mp4 -fps 24 
        合並多段音視頻並保持同步 

    11) mp4box -split *time_sec* test.mp4
        切取test.mp4中的前面time_sec秒的視頻文件

    12) mp4box -split-size *size *test.mp4 
        切取前面大小為size KB的視頻文件

    13) mp4box -split-chunk *S:E* test.mp4 
        切取起始為S少,結束為E秒的視頻文件

    14) mp4box -add 1.mp4#video -add 2.mp4#audio -new test.mp4
        test.mp4由1.mp4中的視頻與2.mp4中的音頻合並生成

而通過mp4box也可以查看mp4的信息,其輸出內容格式非常類似ffprobe查看的信息,不過想對ffprobe更完善。

3. mp4info

mp4info是一個不錯的MP4分析工具,而且是可視化的工具,可以將MP4中的各個Box解析出來,並將其中的數據展現出來。分析MP4文件內容時使用mp4info將會更方便。

技術分享圖片

結合著此工具,理解MP4的Box會更方便,更直觀。

三、MP4格式重要Box

1. ftyp(File Type Box

該Box有且只有1個,並且只能被包含在文件層,而不能被其他Box包含。該Box應該被放在文件的最開始,指示該MP4文件應用的相關信息。

“ftyp” body依次包括1個32位的major brand(4個字符),1個32位的minor version(整數)和1個以32位(4個字符)為單位元素的數組Compatible Brands。

2. moov(Movie Box)

該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。

3. trak(Track 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。

4. mdat(Meida Data Box)

該box包含於文件層,可以有多個,也可以沒有(當媒體數據全部為外部文件引用時),用來存儲媒體數據。數據直接跟在box type字段後面,具體數據結構的意義需要參考metadata(主要在sample table中描述)。

5. free或skip(Free Space Box

free”中的內容是無關緊要的,可以被忽略。該box被刪除後,不會對播放產生任何影響。

6. stbl(Sample Table Box)

stbl”幾乎是普通的MP4文件中最復雜的一個box了,首先需要回憶一下sample的概念。sample是媒體數據存儲的單位,存儲在media的chunk中,chunk和sample的長度均可互不相同,如下圖所示。

技術分享圖片

普通MP4文件的結構重要的部分就講完了,理解起來可能比較亂,下面這張圖是常見的box的樹結構圖,可以用來大致了解MP4文件的構造。

技術分享圖片

在MP4文件中,Box的結構與上圖中所描述的一般沒太大的差別。

四、MP4格式 與 FFmpeg實戰

1. 在FFmpeg中的輸出MP4的Demuxer信息

使用命令行 ffmpeg -h demuxder=mp4 查看MP4文件的Demuxer信息:

Demuxer mov,mp4,m4a,3gp,3g2,mj2 [QuickTime / MOV]:
Common extensions: mov,mp4,m4a,3gp,3g2,mj2.

2. 通過FFmepg faststart參數的使用,來理解mdat和moov的順序的意義

正常情況下,ffmpeg生成的moov是在mdat寫完成後再寫入的。

下面是一個例子:

ffmpeg -i 好漢歌.flv -c copy -f mp4 好漢歌.mp4

使用mp4info查看容器出現的順序,如圖:

技術分享圖片

可以看出moov box是在mdat的下面。這時,我們可以使用faststart將上圖的moov移動到mdat前面。

使用如下命令行:

ffmpeg -i 好漢歌.flv -c copy -f mp4 -movflags faststart 好漢歌.mp4

然後使用mp4info查看MP4的容器順序,就可以看到moov被移動到mdat前面了。如下圖所示:

技術分享圖片

因為MP4的標準中描述的moov與mdat的存放位置前後並沒有強制要求,所有有些時候moov這個Box在mdat的後面,有時候在mdat的前面。

在互聯網的視頻點播中,如果希望MP4文件被快速打開,則需要moov存放在mdat的前面;如果放在後面,則需要將MP4文件下載完成後才可以進行播放。

多媒體文件格式(一):MP4 格式