1. 程式人生 > >FLV檔案格式詳解

FLV檔案格式詳解

具體格式可以參看 flv spec。


下面主要介紹上圖中的Tag裡面的欄位,每個Tag由兩部分組成:Tag Header和Tag Data。

1. Tag Header

名稱 長度 介紹
Tag型別 1 bytes 8:音訊
9:視訊
18:meta
其他:保留
資料區長度 3 bytes 在資料區的長度
時間戳 3 bytes 整數,單位是毫秒。對於指令碼型的tag總是0
時間戳擴充套件 1 bytes 將時間戳擴充套件為4bytes,代表高8位。很少用到
StreamsID 3 bytes 總是0
資料區(data) 由資料區長度決定 資料實體

2. Tag Data

Tag的資料區根據Tag型別的不同可以分為三種:音訊資料、視訊資料和meta資料。

2.1 音訊資料

第一個位元組是音訊資訊,格式如下:
名稱 長度 介紹
音訊格式 4 bits 0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
4 = Nellymoser 16-kHz mono
5 = Nellymoser 8-kHz mono
6 = Nellymoser
7 = G.711 A-law logarithmic PCM
8 = G.711 mu-law logarithmic PCM
9 = reserved
10 = AAC
11 = Speex
14 = MP3 8-Khz
15 = Device-specific sound
取樣率 2 bits 0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz
對於AAC總是3
取樣的長度 1 bit 0 = snd8Bit
1 = snd16Bit
壓縮過的音訊都是16bit
音訊型別 1 bit 0 = sndMono
1 = sndStereo
對於AAC總是1
音訊資料         8 bit [n]

如果是AAC格式的情況下,音訊資料的格式如下:

2.2 視訊資料

第一個位元組是視訊資訊,格式如下:
名稱 長度 介紹
幀型別 4 bits 1: keyframe (for AVC, a seekable frame)
2: inter frame (for AVC, a non-seekable frame)
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frame
編碼ID 4 bits 1: JPEG (currently unused)
2: Sorenson H.263
3: Screen video
4: On2 VP6
5: On2 VP6 with alpha channel
6: Screen video version 2
7: AVC

如果幀型別是5,那麼這個tag data的內容不是視訊資料,data裡面是8bits資料,意義如下:
  • 0, Start of client-side seeking video frame sequence 
  • 1,End of client-side seeking video frame sequence 
如果是AVC格式的話,tag data後面的資料格式如下:

2.3 指令碼資料

指令碼Tag一般只有一個,是flv的第一個Tag,用於存放flv的資訊,比如duration、audiodatarate、creator、width等。

首先介紹下指令碼的資料型別。所有資料都是以資料型別+(資料長度)+資料的格式出現的,資料型別佔1byte,資料長度看資料型別是否存在,後面才是資料。

格式如下:



如果型別為String,後面的2bytes為字串的長度(Long String是4bytes),再後面才是字串資料;如果是Number型別,後面的8bytes為Double型別的資料;Boolean型別,後面1byte為Bool型別。

知道了這些後再來看看flv中的指令碼,一般開頭是0x02,表示String型別,後面的2bytes為字串長度,一般是0x000a(“onMetaData”的長度),再後面就是字串“onMetaData”。好像flv格式的檔案都有onMetaData標記,在執行ActionScript的時候會用到它。後面跟的是0x08,表示ECMA Array型別,這個和Map比較相似,一個鍵跟著一個值。鍵都是String型別的,所以開頭的0x02被省略了,直接跟著的是字串的長度,然後是字串,再是值的型別,也就是上面介紹的那些了。

onMetaData標籤中包含的是流的資訊,一般的資訊包括:

  • duration: a DOUBLE indicating the total duration of the file in seconds
  • width: a DOUBLE indicating the width of the video in pixels
  • height: a DOUBLE indicating the height of the video in pixels
  • videodatarate: a DOUBLE indicating the video bit rate in kilobits per second 
  • framerate: a DOUBLE indicating the number of frames per second
  • videocodecid: a DOUBLE indicating the video codec ID used in the file (see “Video tags” on page 8 for available CodecID values)
  • audiosamplerate: a DOUBLE indicating the frequency at which the audio stream is replayed
  • audiosamplesize: a DOUBLE indicating the resolution of a single audio sample
  • stereo: a BOOL indicating whether the data is stereo
  • audiocodecid: a DOUBLE indicating the audio codec ID used in the file (see “Audio tags” on page 6 for available SoundFormat values)
  • filesize: a DOUBLE indicating the total size of the file in bytes 

2.4 keyframes索引資訊

官方的文件中並沒有對 keyframes index 做描述,但是,flv 的這種結構每個 tag 又不像 TS 有同步頭,如果沒有 keyframes index 的話,需要按順序讀取每一個tag, seek 及快進快退的效果會非常差。後來在做 flv 檔案合成的時候,發現網上有的 flv 檔案將 keyframes 資訊隱藏在 Script Tag 中。

keyframes 幾乎是一個非官方的標準, 也就是民間標準。兩個常用的操作 metadata 的工具是 flvtool2 和 FLVMDI,都是把 keyframes 作為一個預設的元資訊專案。在 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” 和 “times”分別指的是關鍵幀的檔案位置和關鍵幀的 PTS。通過 keyframes 可以建立起自己的 Index,然後在 seek 和快進快退的操作中,快速有效地跳轉到你想要找的關鍵幀位置進行處理。

3. FLV分析工具