FLV视频文件格式分析
FLV視頻文件格式分析
廖雪峰 / 編程 / 2012-2-2 7:02 / 閱讀: 1
FLV視頻格式是Adobe推出的Flash可直接播放的視頻流。需要注意的概念是編碼格式和文件封裝格式。編碼格式是指編碼器輸出的“裸”的視頻流或音頻流,常見的視頻編碼格式就是H.264,常見的音頻編碼格式是AAC和MP3。FLV是一種文件封裝格式,它可以封裝H264和AAC,其他常見的文件封裝格式還有MP4、TS、MKV等等。不同的文件封裝格式可以相互轉換,只要把一種文件封裝格式拆包,解出“裸”的視頻流和音頻流,再按另一種文件封裝格式打包,就可以完成轉換,不需要重新編碼,因此速度非常快。
本文討論FLV的文件封裝格式,FLV的文件格式定義最權威的就是Adobe的官方文檔:
?
該文檔的Annex E列出了FLV的詳細封裝格式。FLV采用網絡字節序(高字節在前),無符號整數。
我們先找一個FLV文件,包含H264視頻和AAC音頻:
464c 5601?0500 0000 0900 0000 0012 0000 3f00 0000 0000 0000 0200 0a6f 6e4d 6574 6144 6174 6108 0000 0002 0008 6475 7261 7469 6f6e 0040 27c8 b439 5810 6200 0c76 6964 656f 636f 6465 6369 6400 4000 0000 0000 0000 0000 0900 0000 4a08 0000 0400 0000 0000 0000 af00 1208?0000 000f?0900 0043 0000 0000 0000 0017 0000 0000 0142 001f 0301 002f 6742 801f 9652 0283 f602 a100 0003 0001 0000 0300 32e0 6003 0d40 0046 30ff 18e3 0300 186a 0002 3187 f8c7 0ed0 a152 4001 0004 68cb 8d48?0000 004e 0900 0d1c 0000 0000 0000 0017 0100 029d 0000 0d13 6588 8040 0db1 185c 0008 2d1f 7893 de24 f789 f785 c2c4 f8a6 d3e2 43fa f177 85ea f377 a930 f991 ea7c 4f2a f0b9FLV的封裝格式比較簡單,文件開頭3個標識字節“FLV”標識文件類型,緊跟一個version字節,當前版本始終是0x01,然后緊跟的一個字節0x05從低位開始第一位表示是否有視頻流,第三位表示是否有音頻流,最高5位保留,因此,判斷是否有視頻和音頻:
has_video = (b & 0x01)==1 has_audio = (b & 0x04)==4上例中0x05說明該文件既含有視頻又含有音頻。隨后4個字節表示FLV文件頭的長度,一般是9,因為從文件頭到此正好是9個字節,表示FLV文件頭結束。
剩下的部分全部是FLV Body內容。FLV Body由一個一個的Tag構成,格式為:
Tag0的長度 | Tag1 | tag1的長度 | tag2 | tag2的長度 | ... | tagN | tagN的長度第0個Tag也就是Tag0不存在,因此長度總是0,然后是Tag1的內容,緊跟Tag1的長度……Tag長度為4字節無符號整數。
tag有3類,ScriptTag = 0x12,又稱Metadata Tag,存放視頻元數據,如高、寬和關鍵幀等信息,VideoTag = 0x09,存放Video,AudioTag = 0x08,存放Audio。
Tag的結構如下:
Field: Type Reseved: UB(2) Filter: UB(1) TagType: UB(5) DataSize: UI24 Timestamp: UI24 TimestampExtended: UI8 StreamID: UI24 if TagType==8:AudioTagHeader: 不定長 if TagType==9:VideoTagHeader: 不定長 if Filter==1:EncryptionTagHeader: 不定長 Data: 不定長Adobe的規范中,UB表示Unsigned Bit,UB(2)表示2個bit,UI表示Unsigned Integer,UI24表示24位整數,也就是3個Byte。
第一個字節的高2位bit保留,filter bit通常為0,低5位表示TagType,判斷TagType的代碼就是:
tagType = b & 0x1f緊跟的3個byte是Tag數據的長度,即StreamID后面的數據長度,正好等于Tag的總長度減去11字節。
緊跟的3個byte是時間戳,后面再接一個byte的擴展時間戳。計算時間按如下公式計算:
擴展時間戳 << 24 + 時間戳單位是毫秒。
緊跟的3個byte是StreamID,當前規范中始終為0。
根據TagType,緊跟的是AudioTagHeader或VideoTagHeader,剩下的就是真正的數據了。
解析FLV的Python代碼如下:
def parse_flv(reader):if reader.read_bytes(3)!='FLV':raise StandardError('Bad FLV header')version = reader.read_byte() # should be 0x01b = reader.read_byte()has_video = (b & 0x01)==0x01has_audio = (b & 0x04)==0x04reader.skip(4) # skip lengthreader.skip(4) # skip tag 0's lengthwhile not reader.eof():tag_type, timestamp, data = parse_tag(reader)if tag_type==0x12:parse_script_tag(timestamp, data)elif tag_type==0x08:parse_audio_tag(timestamp, data)elif tag_type==0x09:parse_video_tag(timestamp, data)else:raise StandardError('Bad tag type')def parse_tag(reader):tag_type = reader.read_byte() & 0x1fdata_size = reader.read_int24()timestamp = reader.read_int24()timestamp_ext = reader.read_int8()reader.skip(3) # skip stream iddata = reader.read(data_size)reader.read_int32() # tag size, should be data_size + 11return tag_type, (timestamp_ext << 24) + timestamp, data總結
以上是生活随笔為你收集整理的FLV视频文件格式分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音视频封装格式、编码格式知识
- 下一篇: 音视频同步(播放)原理