FLV 格式解析

簡介

FLV(Flash Video)是現(xiàn)在非常流行的流媒體格式,由于其視頻文件體積輕巧、封裝播放簡單等特點,使其很適合在網(wǎng)絡(luò)上進行應(yīng)用,目前主流的視頻網(wǎng)站無一例外地使用了FLV格式。另外由于當前瀏覽器與Flash Player緊密的結(jié)合,使得網(wǎng)頁播放FLV視頻輕而易舉,也是FLV流行的原因之一。

FLV是流媒體封裝格式,我們可以將其數(shù)據(jù)看為二進制字節(jié)流??傮w上看,F(xiàn)LV包括文件頭(File Header)和文件體(File Body)兩部分,其中文件體由一系列的Tag及Tag Size對組成。


截屏2025-02-08 13.45.45.png

FLV格式解析

先來一張圖,這是一個FLV視頻,使用的是UltraEdit的二進制查看工具。


截屏2025-02-08 13.48.22.png

FLV Header

header部分 = Signature(3 Byte) + Version(1 Byte) + Flags(1 Bypte) + DataOffset(4 Byte)

  • signature 占3個字節(jié) 固定FLV三個字符作為標示。一般發(fā)現(xiàn)前三個字符為FLV時就認為他是flv文件。圖中0x46 0x4C 0x56,代表FLV
  • Version 占1個字節(jié) 標示FLV的版本號。這里我們看到是1
  • Flags 占1個字節(jié) 內(nèi)容標示。二進制數(shù)據(jù)的第0位和第2位,分別表示 video 與 audio 存在的情況.(1表示存在,0表示不存在)。截圖看到是0x05,也就是00000101,代表既有視頻,也有音頻。
  • DataOffset 4個字節(jié) 表示FLV的header長度。這里可以看到固定是 9

FLV Body

FLV的body部分是一系列的back-pointers+tag構(gòu)成的

  • back-pointers固定4個字節(jié),表示前一個tag的size
  • tag分三種類型:video,audio,scripts.

tag組成

tag type+tag data size+Timestamp+TimestampExtended+stream id+ tag data

  • type 1個字節(jié)。8為Audio,9為Video,18為scripts
  • tag data size 3個字節(jié)。表示tag data的長度。從streamd id 后算起。
  • Timestreamp 3個字節(jié)。時間戳
  • TimestampExtended 1個字節(jié)。時間戳擴展字段
  • stream id 3個字節(jié)??偸?
  • tag data 數(shù)據(jù)部分

圖上第一個tag:

  • type=0x12=18,表示是一個scripts,FLV中,header后的第一個tag是script tag,script tag內(nèi)容是amf格式數(shù)據(jù),包含兩個amf.
  • size=0x00 0x01 0x74 = 372
  • timpestreamp = 0x00 0x00 0x00
  • TimestampExtended=0x00
  • streamid=0x00 0x00 0x00
  • tag data部分:
    截屏2025-02-08 13.55.34.png

tag的劃分

圖中紅色部分是我標出"("與")"前后的的兩個back-pointers,都是4個字節(jié)。而括號中間就是第一個TAG。那是怎么計算的呢?我們就以這個做個示例。

  • 首先第一個back-pointers是0x00000000,那是因為后面是第一個TAG。所以他為0。
  • 然后根據(jù)我們我們前面格式獲取到size是0x00 0x01 0x74 = 372。也就是說從stream id后面再加上372個字節(jié)就到了第一個TAG的末尾,我們數(shù)一下。tag header有11個字節(jié)。那么到第一個TAG,總共有372+11=383=0x17f。
  • 接下來我們找到0x17f的地址,從工具上很容易找到,正好就是后括號")"的前面。紅0x00 0x00 0x01 0x7F=372,這代表的是上一個TAG的大小。
  • 最后我們計算一下,上一個TAG數(shù)據(jù)部分是372個字節(jié),前面type、stream id等字段占了11個字節(jié)。正好是匹配的。
    上面我們已經(jīng)知道了怎么取劃分每個TAG。接下來我們就看TAG的具體內(nèi)容:

tag的內(nèi)容

前面已經(jīng)提到tag分3種: script、Audio 和 video。我們一個個看

script

腳本Tag一般只有一個,是flv的第一個Tag,用于存放flv的信息,比如duration、audiodatarate、creator、width等。
首先介紹下腳本的數(shù)據(jù)類型。所有數(shù)據(jù)都是以數(shù)據(jù)類型+(數(shù)據(jù)長度)+數(shù)據(jù)的格式出現(xiàn)的,數(shù)據(jù)類型占1byte,數(shù)據(jù)長度看數(shù)據(jù)類型是否存在,后面才是數(shù)據(jù)。
一般來說,該Tag Data結(jié)構(gòu)包含兩個AMF包。AMF(Action Message Format)是Adobe設(shè)計的一種通用數(shù)據(jù)封裝格式,在Adobe的很多產(chǎn)品中應(yīng)用,簡單來說,AMF將不同類型的數(shù)據(jù)用統(tǒng)一的格式來描述。第一個AMF包封裝字符串類型數(shù)據(jù),用來裝入一個“onMetaData”標志,這個標志與Adobe的一些API調(diào)用有,在此不細述。第二個AMF包封裝一個數(shù)組類型(srs返回為object類型),這個數(shù)組中包含了音視頻信息項的名稱和值。具體說明如下

[圖片上傳中...(截屏2025-02-08 14.09.17.png-306782-1738994960018-0)]

截屏2025-02-08 14.09.29.png

上圖為第一個AMF包

  • type=0x02對應(yīng)String
  • size=0A=10
  • value=onMetaData 正好是10個字節(jié)


    截屏2025-02-08 14.10.09.png

    上圖為第二個AMF

  • type=0x08 對應(yīng)ECMA array type。

表示數(shù)組,類似Map。后面4個字節(jié)為數(shù)組的個數(shù)。然后是鍵值對,第一個為鍵,2個字節(jié)為長度。后面跟具體的內(nèi)容。接著3個字節(jié)表示值的類型,然后根據(jù)類型判斷長度。
上圖我們可以判斷,總共有13個鍵值對。
第一個長度為8個字節(jié)是duration。值類型是0x004073,第一個字節(jié)是00,所以是double,8個字節(jié)。
第二個長度5個字節(jié)是width。值也是double類型,8個字節(jié)。
依次解析下去...

Audio

截屏2025-02-08 14.11.15.png

截屏2025-02-08 14.11.27.png

截屏2025-02-08 14.11.41.png

視頻中第二個tag為音頻tag
stream-id之后:

  • 前4位為音頻格式


    截屏2025-02-08 14.13.01.png
  • 接著2位為采樣率(對于AAC總是3)


    截屏2025-02-08 14.14.15.png
  • 接著1位為采樣的長度(壓縮過的音視頻都是16bit)


    截屏2025-02-08 14.14.43.png
  • 接著1位為音頻類型(對于AAC總是1)


    截屏2025-02-08 14.15.14.png

video

由于kobe視頻音頻編碼是pcm,查找視頻tag太難,使用<<東風破>> mv視頻


截屏2025-02-08 14.21.54.png
  • type=0x09=9。這里應(yīng)該是一個video。
  • size=0x000030=48。長度為48。
  • timestreamp=0x000000。
  • TimestampExtended =0x00。
  • stream id =0x000000

我們看到數(shù)據(jù)部分: 視頻信息+數(shù)據(jù) 視頻信息,1個字節(jié)。

StreamId之后的數(shù)據(jù)就表示是VideoTagHeader,如果是avc,VideoTagHeader會多出4個字節(jié)的信息就是AVCPacketType和CompositionTime

  • 前4位為幀類型Frame Type


    截屏2025-02-08 14.23.01.png
  • 后4位為編碼ID (CodecID)


    截屏2025-02-08 14.23.53.png

    特殊情況 視頻的格式(CodecID)是AVC(H.264)的話,VideoTagHeader會多出4個字節(jié)的信息,AVCPacketType 和CompositionTime。

  • AVCPacketType 占1個字節(jié)


    截屏2025-02-08 14.24.19.png

    AVCDecoderConfigurationRecord.包含著是H.264解碼相關(guān)比較重要的sps和pps信息,再給AVC解碼器送數(shù)據(jù)流之前一定要把sps和pps信息送出,否則的話解碼器不能正常解碼。而且在解碼器stop之后再次start之前,如seek、快進快退狀態(tài)切換等,都需要重新送一遍sps和pps的信息.AVCDecoderConfigurationRecord在FLV文件中一般情況也是出現(xiàn)1次,也就是第一個video tag.


    截屏2025-02-08 14.24.51.png

    我們看到 AVCPacketType =1,而后面三個字節(jié)為000043。這是一個視頻幀數(shù)據(jù)。 解析到的數(shù)據(jù)完全符合上面的理論。
    sps pps 前面我們提到第一個video 一般存放的是sps和pps。這里我們具體解析下sps和pps內(nèi)容。先看下存儲的格):
0x01+sps[1]+sps[2]+sps[3]+0xFF+0xE1+sps size+sps+01+pps size+pps

sps[1]=0x64 sps[2]=00 sps[3]=0D sps size=0x001B=27(占兩個字節(jié)) 跳過27個字節(jié)后,是0x01 pps size=0x0005=118(占兩個字節(jié)) 跳過5個字節(jié),就到了back-pointers。

這是第二個video tag其實和之前圖一樣,只是我圈出來關(guān)鍵信息。先看下格式 frametype=0x17=00010111 AVCPacketType =1 Composition Time=0x000043 后面就是NALU DATA

https://chensi.moe/blog/2015/11/20/flv-format/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 簡介 FLV(Flash Video)是現(xiàn)在非常流行的流媒體格式,由于其視頻文件體積輕巧、封裝播放簡單等特點,使其...
    輕口味閱讀 1,208評論 0 0
  • FLV是一個二進制文件,簡單來說,其是由一個文件頭(FLV header)和很多tag組成(FLV body)。 ...
    zjjcc閱讀 3,216評論 1 3
  • FLV 簡介 FLV(Flash Video) 是 Adobe 公司推出的一種流媒體格式,由于其封裝后的音視頻文件...
    遠方竹葉閱讀 2,908評論 0 0
  • 1.FLV文件格式如下,由flv頭和一系列tag組成,tag又分為script tag、音頻tag、視頻tag。 ...
    水木年華1987閱讀 677評論 0 0
  • 簡介 FLV(Flash Video)是現(xiàn)在非常流行的流媒體格式,由于其視頻文件體積輕巧、封裝播放簡單等特點,使其...
    第八區(qū)閱讀 23,164評論 23 33

友情鏈接更多精彩內(nèi)容