在互聯網常見的格式中,跨平臺最好的應該就屬MP4文件了。由於MP4文件既能夠在PC平臺的Flashplayer中播放,又能夠在移動平臺的Android、iOS等平臺中進行播放,並且使用系統默認的播放器便可以播放。git
MP4格式是最多見的多媒體文件格式。github
MP4格式標準爲ISO-14496 Part 十二、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排列方式:https://github.com/renhui/Thinking-in-AV/tree/master/多媒體格式/MP4。ide
介紹了MP4的格式標準後,下面咱們來介紹是三個MP4分析工具,爲後續理解MP4文件一些關鍵信息作輔助工具。工具
能夠用來分析MP4封裝格式的工具比較多,除了FFmpeg、FFprobe以外,還有一些經常使用的工具,如Elecard StreamEye、mp4box、mp4info等;下面簡單介紹一下這幾款經常使用的工具:ui
Elecard StreamEye是一款很是強大的視頻信息查看工具,可以查看幀的排列信息,將I幀、P幀、B幀以不一樣顏色的柱狀展示出來,並且柱的長短將根據幀的大小展現。還可以經過Elecard StreamEye分析MP4的封裝的內容信息,包括流信息、宏塊的信息、文件頭頂額信息、圖像的信息以及文件的信息等。還能根據每一幀的順序逐幀查看,能夠看到每一幀的詳細信息與狀態。編碼
示例如圖:spa
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更完善。
mp4info是一個不錯的MP4分析工具,並且是可視化的工具,能夠將MP4中的各個Box解析出來,並將其中的數據展示出來。分析MP4文件內容時使用mp4info將會更方便。
結合着此工具,理解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標籤。
通常狀況下,「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的結構與上圖中所描述的通常沒太大的差異。
使用命令行 ffmpeg -h demuxder=mp4 查看MP4文件的Demuxer信息:
Demuxer mov,mp4,m4a,3gp,3g2,mj2 [QuickTime / MOV]:
Common extensions: mov,mp4,m4a,3gp,3g2,mj2.
正常狀況下,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文件下載完成後才能夠進行播放。