FLV(ACC+H264)文件格式分析

最近自己動手將H264視頻流和AAC音頻流合成flv文件,但是沒有采用開源的ffmpeg的api來處理音視頻流。方法就是模仿ffmpeg中libavformat/flvenc.c 文件寫代碼來完成音視頻的flv格式封裝。在這個封裝過程中,需要非常清楚flv文件格式。網上有關flv文件格式的資料非常多,不過大部分資料是互相轉載或者缺乏足夠詳細的信息(例如:AVDecoderConfigurationRecord和 AudioSpecificConfig的生成)。

因此我就以ffmpeg中libavformat/flvenc.c爲基礎分析flv文件的構成,詳細分析flv文件中每個字節的含義。以下每個方格代表一個字節。其中的數字都是16進製表示(省略0x),格中的字符也可以用相應的16進制數字替代,用字符表示有時候更爲直觀。假定flv文件同時含有視頻和音頻。

接下來就是Metadata的具體數據,由兩個AMF包組成。

Metadata元素個數暫定爲12個 = 音頻5個 + 視頻5個 + 2個(duration和filesize)。 後面還可能會加入其它元素,因此會返回來修改此值。metadata元素的順序不固定,此處採用ffmpeg中的順序。

第二個AMF包中各數組元素封裝形式爲:前兩個字節是元素名稱的長度;後面跟着長度爲L的字符串;第L+3個字節表示元素值的類型;後面跟着是對應值,佔用的字節數取決於值的類型。

以下的(tag->key,tag->value)不一定在所有flv文件中出現,依據不同版本有所不同。

    Remark:以上將flv官方文檔的metadata信息寫入了Script Tag中。但是在做flv文件合成的時候,發現網上有的flv文件將keyframes信息隱藏在Script Tag中。後來通過網絡查一些資料,發現keyframes幾乎是一個非官方的標準,也就是民間標準。 

    兩個常用的操作metadata的工具是flvtool2和FLVMDI, 都是把keyframes作爲一個默認的元信息項目。在FLVMDI的主頁(http://www.buraks.com/flvmdi/)上有描述:

keyframes: (Object) This object is added only if you specify the /k switch. 'keyframes' is known to FLVMDI and if /k switch is not specified, 'keyframes' object will be deleted.

'keyframes' object has 2 arrays: 'filepositions' and 'times'. Both arrays have the same number of elements, which is equal to the number of key frames in the FLV. Values in times array are in 'seconds'. Each correspond to the timestamp of the n'th key frame. Values in filepositions array are in 'bytes'. Each correspond to the fileposition of the nth key frame video tag (which starts with byte tag type 9).

也就是說keyframes中包含着2個內容 'filepositions' and 'times'分別指的是關鍵幀的文件位置和關鍵幀的PTS。通過keyframes可以建立起自己的Index,然後再seek和快進快退的操作中,快速有效的跳轉到你想要找的關鍵幀位置進行處理。

 

到此爲止已經介紹完flv文件格式,flv格式還是比較簡單的,header部分很簡潔,body部分都是由一個個tag組成,tag的話也就三種,腳本tag一般只有一個。最後用一個簡單的圖來概括flv文件格式,以結束本文檔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章