RTMP協(xié)議與 FLV 又有什么關(guān)系呢?實(shí)際 上沉唠,F(xiàn)LV文件與 RTMP 之間是“近親”關(guān)系,甚至比“近親”還要近娇掏,親得就好像是“一個(gè)人”似的桶雀。
FLV文件格式
我們先來看一下 FLV 的文件格式,如下圖所示:
閱讀FLV 格式規(guī)范文檔 從圖中我們可以看出改备,F(xiàn)LV 文件格式由 FLV Header 和 FLV Body 兩部分組成控漠。其中,F(xiàn)LV Header 由 9 個(gè)字節(jié)組成悬钳,Body由 Pre TagSize 和 Tag 組 成盐捷。
為使你對(duì)它們有一個(gè)更清楚的認(rèn)知,下面我們就來詳細(xì)介紹一下 FLV Header 和 FLV Body默勾。
1. FLV Header
它由 9 個(gè)字節(jié)組成:3個(gè)字節(jié)的 “F”“L”“V”字母碉渡,用于標(biāo)記該文件是 FLV 文件;1個(gè)字節(jié)的 Version, 指明使用的 FLV 文件格式的版本;1個(gè)字節(jié)的 Type 標(biāo)識(shí)母剥,用于表明該FLV文件中是否包括音頻或視頻; 4個(gè) 字節(jié)的 FLV Header ?度滞诺,由于 FLV 文件格式頭是固定 9 個(gè)字節(jié),這個(gè)字段設(shè)置得有點(diǎn)多余媳搪。
Type 標(biāo)識(shí)(TypeFlag)又可以細(xì)分為: 1bit 用于標(biāo)識(shí)FLV文件中是否有音頻數(shù)據(jù);1bit標(biāo)識(shí)FLV文件中是否有視頻數(shù)據(jù);如果兩個(gè) bit 位同時(shí)置 1铭段,說明該FLV 文件中既有音頻數(shù)據(jù)又有視頻數(shù)據(jù),這也是通常情況下 FLV Header 的設(shè)置;除了兩個(gè) bit 的音視頻數(shù)據(jù)標(biāo)識(shí)外秦爆,其他位都是預(yù)留位序愚,必須全部置0。詳細(xì)的含義可 以參考下面張圖表:
這張圖表清晰地表達(dá)了 FLV Header 中每個(gè)域所占的字節(jié)以及該域的具體含義等限。
2. FLV Body
從“FLV文件格式結(jié)構(gòu)圖”我們可以看出爸吮,F(xiàn)LV Body 是由多個(gè) Previous TagSize 和 Tag 組成的。其含義如 下圖表所示望门,其中PreviousTagSize 占 4個(gè)字節(jié)形娇,表示前一個(gè) Tag 的大小。這里需要注意的是筹误,第一個(gè) Previous TagSize 比較特殊桐早,由于它前面沒有 Tag 數(shù)據(jù),所以它的值必須為 0。
接下來我們?cè)賮砜匆幌?FLV 中的 Tag哄酝,從 FLV文件格式結(jié)構(gòu)圖中我們可以看到 Tag 由兩部分組成友存,即 Tag Header 和 Tag Data 。
Tag Header 各字段的含義如下圖所示:
- TagType陶衅,占1個(gè)字節(jié)屡立,表示該Tag的類型,可以是音頻搀军、視頻和腳本膨俐。如果類型為音頻,說明這個(gè)Tag存 放的是音頻數(shù)據(jù);如果類型是視頻罩句,說明存放的是視頻數(shù)據(jù)焚刺。
- DataSize,占3個(gè)字節(jié)的止,表示音頻/視頻數(shù)據(jù)的?度檩坚。
- Timestamp和擴(kuò)展Timestamp着撩,一共占4個(gè)字節(jié)诅福,表示數(shù)據(jù)生成時(shí)的時(shí)間戳。
- StreamID拖叙,占3個(gè)字節(jié)氓润,總是為 0。
而Tag Data 中存放的數(shù)據(jù)薯鳍,是根據(jù) TagType 中的類型不同而有所區(qū)別的咖气。也就是說,假如 TagType 指定的 是音頻挖滤,那么 Tag Data中存放的就是音頻數(shù)據(jù);如果 TagType 指定的是視頻崩溪,則Tag Data中存放的就是視 頻數(shù)據(jù)。
無論TagData中存放的是音頻數(shù)據(jù)還是視頻數(shù)據(jù)斩松,它們都是由 Header 和 Data 組成伶唯。也就是說,如果該 Tag 是一個(gè)音頻 Tag 惧盹,那么它的數(shù)據(jù)就是由“AudioHeader + AudioData”組成;如果是一個(gè)視頻 Tag乳幸,則它的數(shù)據(jù)是由“VideoHeader + VideoData”組成。
翻看RTMP協(xié)議钧椰,查看它的 6.1.1 小節(jié)粹断,你會(huì)發(fā)現(xiàn)它定義的 RTMP Message Header 與 Tag Header 是一模一樣的。下圖是我從 RTMP 協(xié)議中截取的協(xié)議頭:
因此嫡霞,我們可以說FLV文件就是由“FLV Header + RTMP數(shù)據(jù)”構(gòu)成的瓶埋。這也揭開了 FLV與 RTMP之間的關(guān) 系秘密,即 FLV 是在 RTMP 數(shù)據(jù)之上加了一層“?甲”。