
FLV協(xié)議簡(jiǎn)介
FLV(Flash Video)是一種流媒體格式,因其體積小、協(xié)議相對(duì)簡(jiǎn)單,很快便流行開來,并得到廣泛的支持。
常見的HTTP-FLV直播協(xié)議,就是使用HTTP流式傳輸通過FLV封裝的音視頻數(shù)據(jù)。對(duì)想要了解HTTP-FLV的同學(xué)來說,了解FLV協(xié)議很有必要。
概括地說,F(xiàn)LV 由 FLV header 跟 FLV file body 兩部分組成,而 FLV file body 又由多個(gè) FLV tag組成。
FLV = FLV header + FLV file body FLV file body = PreviousTagSize0 + Tag1 + PreviousTagSize1 + Tag2 + ... + PreviousTagSizeN-1 + TagN
FLV tag又分為3種類型:
- Video Tag:存放視頻相關(guān)數(shù)據(jù);
- Audio Tag:存放音頻相關(guān)數(shù)據(jù);
- Script Tag:存放音視頻元數(shù)據(jù);
在實(shí)際講解FLV協(xié)議前,首先對(duì)單位進(jìn)行約定:
類型定義0x...16進(jìn)制數(shù)據(jù)SI8有符號(hào)8位整數(shù)SI16有符號(hào)16位整數(shù)SI24有符號(hào)24位整數(shù)SI32有符號(hào)32位整數(shù)STRINGSequence of Unicode 8-bit characters (UTF-8), terminated with 0x00 (unless otherwise specified)UI8無符號(hào)8位整數(shù)UI16無符號(hào)16位整數(shù)UI24無符號(hào)24位整數(shù)UI32無符號(hào)32位整數(shù)xxx [ ]類型為xxx的數(shù)組xxx [n]類型為xxx的數(shù)組,數(shù)組長度為n
FLV header
FLV header由如下字段組成,其中:
- 前三個(gè)字節(jié)內(nèi)容固定是FLV
- 最后4個(gè)字節(jié)內(nèi)容固定是9(對(duì)FLV版本1來說)
字段字段類型字段含義SignatureUI8簽名,固定為'F' (0x46)SignatureUI8簽名,固定為'L' (0x4c)SignatureUI8簽名,固定為'V' (0x56)VersionUI8版本,比如 0x01 表示 FLV 版本 1TypeFlagsReservedUB[5]全為0TypeFlagsAudioUB[1]1表示有audio tag,0表示沒有TypeFlagsReservedUB[1]全為0TypeFlagsVideoUB[1]1表示有video tag,0表示沒有DataOffsetUI32FLV header的大小,單位是字節(jié)
FLV file body
FLV file body很有規(guī)律,由一系列的TagSize和Tag組成,其中:
- PreviousTagSize0 總是為0;
- tag 由tag header、tag body組成;
- 對(duì)FLV版本1,tag header固定為11個(gè)字節(jié),因此,PreviousTagSize(除第1個(gè))的值為 11 + 前一個(gè)tag 的 tag body的大小;
字段字段類型字段含義PreviousTagSize0UI32總是0Tag1FLVTAG第1個(gè)tagPreviousTagSize1UI32前一個(gè)tag的大小,包括tag headerTag2FLVTAG第2個(gè)tag.........PreviousTagSizeN-1UI32第N-1個(gè)tag的大小TagNFLVTAG第N個(gè)tagPreviousTagSizeNUI32第N個(gè)tag的大小,包含tag header
FLV tags
FLV tag由 tag header + tag body組成。
tag header如下,總共占據(jù)11個(gè)字節(jié):
字段字段類型字段含義TagTypeUI8tag類型
8:audio
9:video
18:script data
其他:保留DataSizeUI24tag body的大小TimestampUI24相對(duì)于第一個(gè)tag的時(shí)間戳(單位是毫秒)
第一個(gè)tag的Timestamp為0TimestampExtendedUI8時(shí)間戳的擴(kuò)展字段,當(dāng) Timestamp 3個(gè)字節(jié)不夠時(shí),會(huì)啟用這個(gè)字段,代表高8位StreamIDUI24總是0Data取決于根據(jù)TagTypeTagType=8,則為AUDIODATA
TagType=9,則為VIDEODATA
TagType=18,則為SCRIPTDATAOBJECT
In playback, the time sequencing of FLV tags depends on the FLV timestamps only. Any timing mechanisms built into the payload data format are ignored.
Audio tags
定義如下所示:
字段字段類型字段含義SoundFormatUB[4]音頻格式,重點(diǎn)關(guān)注 **10 = AAC **
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
SoundRateUB[2]采樣率,對(duì)AAC來說,永遠(yuǎn)等于3
0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHzSoundSizeUB[1]采樣精度,對(duì)于壓縮過的音頻,永遠(yuǎn)是16位
0 = snd8Bit
1 = snd16BitSoundTypeUB[1]聲道類型,對(duì)Nellymoser來說,永遠(yuǎn)是單聲道;對(duì)AAC來說,永遠(yuǎn)是雙聲道;
0 = sndMono 單聲道
1 = sndStereo 雙聲道SoundDataUI8[size of sound data]如果是AAC,則為 AACAUDIODATA;
其他請(qǐng)參考規(guī)范;
備注:
If the SoundFormat indicates AAC, the SoundType should be set to 1 (stereo) and the SoundRate should be set to 3 (44 kHz). However, this does not mean that AAC audio in FLV is always stereo, 44 kHz data. Instead, the Flash Player ignores these values and extracts the channel and sample rate data is encoded in the AAC bitstream.
AACAUDIODATA
當(dāng) SoundFormat 為10時(shí),表示音頻采AAC進(jìn)行編碼,此時(shí),SoundData的定義如下:
字段字段類型字段含義AACPacketTypeUI80: AAC sequence header
1: AAC rawDataUI8[n]如果AACPacketType為0,則為AudIOSpecificConfig
如果AACPacketType為1,則為AAC幀數(shù)據(jù)
The AudioSpecificConfig is explained in ISO 14496-3. Note that it is not the same as the contents of the esds box from an MP4/F4V file. This structure is more deeply embedded.
關(guān)于AudioSpecificConfig
偽代碼如下:參考這里
5 bits: object type if (object type == 31) 6 bits + 32: object type 4 bits: frequency index if (frequency index == 15) 24 bits: frequency 4 bits: channel configuration var bits: AOT Specific Config 復(fù)制代碼
定義如下:
字段字段類型字段含義AudioObjectTypeUB[5]編碼器類型,比如2表示AAC-LCSamplingFrequencyIndexUB[4]采樣率索引值,比如4表示44100SamplingFrequencyIndexUB[4]采樣率索引值,比如4表示44100ChannelConfigurationUB[4]聲道配置,比如2代表雙聲道,front-left, front-right
Video tags
定義如下:
字段字段類型字段含義FrameTypeUB[4]重點(diǎn)關(guān)注1、2:
1: keyframe (for AVC, a seekable frame) —— 即H.264的IDR幀;
2: inter frame (for AVC, a non- seekable frame) —— H.264的普通I幀;
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frameCodecIDUB[4]編解碼器,主要關(guān)注 7(AVC)
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: AVCVideoData取決于CodecID實(shí)際的媒體類型,主要關(guān)注 7:AVCVIDEOPACKE
2: H263VIDEOPACKET
3: SCREENVIDEOPACKET
4: VP6FLVVIDEOPACKET
5: VP6FLVALPHAVIDEOPACKET
6: SCREENV2VIDEOPACKET
7: AVCVIDEOPACKE
AVCVIDEOPACKE
當(dāng) CodecID 為 7 時(shí),VideoData 為 AVCVIDEOPACKE,也即 H.264媒體數(shù)據(jù)。
AVCVIDEOPACKE 的定義如下:
字段字段類型字段含義AVCPacketTypeUI80: AVC sequence header
1: AVC NALU
2: AVC end of sequenceCompositionTimeSI24如果AVCPacketType=1,則為時(shí)間cts偏移量;否則,為0DataUI8[n]1、如果如果AVCPacketType=1,則為AVCDecoderConfigurationRecord
2、如果AVCPacketType=1=2,則為NALU(一個(gè)或多個(gè))
3、如果AVCPacketType=2,則為空
這里有幾點(diǎn)稍微解釋下:
- NALU:H.264中,將數(shù)據(jù)按照特定規(guī)則格式化后得到的抽象邏輯單元,稱為NALU。這里的數(shù)據(jù)既包括了編碼后的視頻數(shù)據(jù),也包括視頻解碼需要用到的參數(shù)集(PPS、SPS)。
- AVCDecoderConfigurationRecord:H.264 視頻解碼所需要的參數(shù)集(SPS、PPS)
- CTS:當(dāng)B幀的存在時(shí),視頻解碼呈現(xiàn)過程中,dts、pts可能不同,cts的計(jì)算公式為 pts - dts/90,單位為毫秒;如果B幀不存在,則cts固定為0;
PPS、SPS這里先不展開。
Script Data Tags
Script Data Tags通常用來存放跟FLV中音視頻相關(guān)的元數(shù)據(jù)信息(onMetaData),比如時(shí)長、長度、寬度等。它的定義相對(duì)復(fù)雜些,采用AMF(Action Message Format)封裝了一系列數(shù)據(jù)類型,比如字符串、數(shù)值、數(shù)組等。
字段字段類型字段含義ObjectsSCRIPTDATAOBJECT[]任意數(shù)目的 SCRIPTDATAOBJECTSCRIPTDATAOBJECTENDUI24永遠(yuǎn)是9,標(biāo)識(shí)著Script Data的結(jié)束
SCRIPTDATAOBJECT 定義如下:
字段字段類型字段含義ObjectNameSCRIPTDATASTRING對(duì)象的名字ObjectDataSCRIPTDATAVALUE對(duì)象的值
SCRIPTDATAVALUE 的定義如下:
字段字段類型字段含義TypeSCRIPTDATASTRING變量類型:
0 = Number type
1 = Boolean type
2 = String type
3 = Object type
4 = MovieClip type
5 = Null type
6 = Undefined type
7 = Reference type 8 = ECMA array type 10 = Strict array type 11 = Date type
12 = Long string typeECMAArrayLength如果Type為8(數(shù)組),則為UI32數(shù)組長度ScriptDataValueIf Type == 0 DOUBLE
If Type == 1 UI8
If Type == 2 SCRIPTDATASTRING
...(有點(diǎn)長,可以參考規(guī)范)變量的值ScriptDataValueTerminator如果Type==3,則為SCRIPTDATAOBJECTEND
如果 Type==8,則為SCRIPTDATAVARIABLEENDObject、Array的結(jié)束符
可以看到,Script Data Tag 的定義相對(duì)復(fù)雜,下面通過onMetaData進(jìn)行進(jìn)一步講解。
onMetaData
onMetaData中包含了音視頻相關(guān)的元數(shù)據(jù),封裝在Script Data Tag中,它包含了兩個(gè)AMF。
第一個(gè)AMF:
- 第1個(gè)字節(jié):0x02,表示字符串類型
- 第2-3個(gè)字節(jié):UI16類型,值為0x000A,表示字符串的長度為10(onMetaData的長度);
- 第4-13個(gè)字節(jié):字符串onMetaData對(duì)應(yīng)的16進(jìn)制數(shù)字(0x6F 0x6E 0x4D 0x65 0x74 0x61 0x44 0x61 0x74 0x61);
第二個(gè)AMF:
- 第1個(gè)字節(jié):0x08,表示數(shù)組類型;
- 第2-5個(gè)字節(jié):UI32類型,表示數(shù)組的長度,onMetaData中具體包含哪些屬性是不固定的。
- 第6個(gè)字節(jié)+:比如duration,則:
- 第6-9個(gè)字節(jié):0x0008,表示長度為8個(gè)字節(jié);
- 第10-17個(gè)字節(jié):0x6475 7261 7469,表示 duration 這個(gè)字符串;
- 第18個(gè)字節(jié):0x00,表示為數(shù)值類型;
- 第19-26個(gè)字節(jié):0x...,表示具體的時(shí)長;
更多onMetaData字段的定義:
字段字段類型字段含義durationDOUBLE文件的時(shí)長widthDOUBLE視頻寬度(px)heightDOUBLE視頻高度(px)videodatarateDOUBLE視頻比特率(kb/s)framerateDOUBLE視頻幀率(幀/s)videocodecidDOUBLE視頻編解碼器ID(參考Video Tag)audiosamplerateDOUBLE音頻采樣率audiosamplesizeDOUBLE音頻采樣精度(參考Audio Tag)stereoBOOL是否立體聲audiocodecidDOUBLE音頻編解碼器ID(參考Audio Tag)filesizeDOUBLE文件總得大小(字節(jié))
寫在后面
FLV協(xié)議本身不算復(fù)雜,理解上的困難,更多時(shí)候來自音視頻編解碼相關(guān)的知識(shí),比如H.264、AAC相關(guān)知識(shí),建議不懂的時(shí)候自行查下。此外,F(xiàn)LV的字節(jié)序?yàn)榇蠖诵颍谧鰠f(xié)議解析的時(shí)候一定要注意。
本文為講解方便,部分內(nèi)容可能不夠嚴(yán)謹(jǐn),如有錯(cuò)漏敬請(qǐng)指出。
相關(guān)鏈接
video_file_format_spec_v10.pdf www.adobe.com/content/dam…
MPEG-4 Part 3 en.wikipedia.org/wiki/MPEG-4…
flv文件分析 www.jianshu.com/p/e290dca02…
H.264再學(xué)習(xí) -- 詳解 H.264 NALU語法結(jié)構(gòu) blog.csdn.net/qq_29350001…






