最近自己動手將H264視頻流和AAC音頻流合成flv文件,但是沒有采用開源的ffmpeg的api來處理音視頻流。方法就是模仿ffmpeg中l(wèi)ibavformat/flvenc.c 文件寫代碼來完成音視頻的flv格式封裝。在這個封裝過程中,需要非常清楚flv文件格式。網(wǎng)上有關(guān)flv文件格式的資料非常多,不過大部分資料是互相轉(zhuǎn)載或者缺乏足夠詳細的信息(例如:AVDecoderConfigurationRecord和 AudioSpecificConfig的生成)。
因此我就以ffmpeg中l(wèi)ibavformat/flvenc.c為基礎(chǔ)分析flv文件的構(gòu)成,詳細分析flv文件中每個字節(jié)的含義。以下每個方格代表一個字節(jié)。其中的數(shù)字都是16進制表示(省略0x),格中的字符也可以用相應(yīng)的16進制數(shù)字替代,用字符表示有時候更為直觀。假定flv文件同時含有視頻和音頻。
接下來就是Metadata的具體數(shù)據(jù),由兩個AMF包組成。
Metadata元素個數(shù)暫定為12個 = 音頻5個 + 視頻5個 + 2個(duration和filesize)。 后面還可能會加入其它元素,因此會返回來修改此值。metadata元素的順序不固定,此處采用ffmpeg中的順序。
第二個AMF包中各數(shù)組元素封裝形式為:前兩個字節(jié)是元素名稱的長度;后面跟著長度為L的字符串;第L+3個字節(jié)表示元素值的類型;后面跟著是對應(yīng)值,占用的字節(jié)數(shù)取決于值的類型。
以下的(tag->key,tag->value)不一定在所有flv文件中出現(xiàn),依據(jù)不同版本有所不同。
Remark:以上將flv官方文檔的metadata信息寫入了Script Tag中。但是在做flv文件合成的時候,發(fā)現(xiàn)網(wǎng)上有的flv文件將keyframes信息隱藏在Script Tag中。后來通過網(wǎng)絡(luò)查一些資料,發(fā)現(xiàn)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個內(nèi)容 'filepositions' and 'times'分別指的是關(guān)鍵幀的文件位置和關(guān)鍵幀的PTS。通過keyframes可以建立起自己的Index,然后再seek和快進快退的操作中,快速有效的跳轉(zhuǎn)到你想要找的關(guān)鍵幀位置進行處理。
到此為止已經(jīng)介紹完flv文件格式,flv格式還是比較簡單的,header部分很簡潔,body部分都是由一個個tag組成,tag的話也就三種,腳本tag一般只有一個。最后用一個簡單的圖來概括flv文件格式,以結(jié)束本文檔。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。