FLV格式解析

簡介

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

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


image

FLV格式解析

先來一張圖,這是《科比退役演講》下載)的一個(gè)FLV視頻。我使用的是UltraEdit的二進(jìn)制查看工具氮帐。


flv-head

header

頭部分由一下幾部分組成
Signature(3 Byte)+Version(1 Byte)+Flags(1 Bypte)+DataOffset(4 Byte)

  • signature 占3個(gè)字節(jié) 固定FLV三個(gè)字符作為標(biāo)示嗅虏。一般發(fā)現(xiàn)前三個(gè)字符為FLV時(shí)就認(rèn)為他是flv文件。圖中0x46 0x4C 0x56,代表FLV
  • Version 占1個(gè)字節(jié) 標(biāo)示FLV的版本號(hào)揪漩。這里我們看到是1
  • Flags 占1個(gè)字節(jié) 內(nèi)容標(biāo)示旋恼。第0位和第2位,分別表示 video 與 audio 存在的情況.(1表示存在,0表示不存在)。截圖看到是0x05奄容,也就是00000101冰更,代表既有視頻,也有音頻昂勒。
  • DataOffset 4個(gè)字節(jié) 表示FLV的header長度蜀细。這里可以看到固定是9

Body

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

  • back-pointers固定4個(gè)字節(jié),表示前一個(gè)tag的size
  • tag分三種類型:video,audio,scripts.
tag組成
tag type+tag data size+Timestamp+TimestampExtended+stream id+ tag data
  • type 1個(gè)字節(jié)。8為Audio,9為Video,18為scripts
  • tag data size 3個(gè)字節(jié)戈盈。表示tag data的長度奠衔。從streamd id 后算起。
  • Timestreamp 3個(gè)字節(jié)塘娶。時(shí)間戳
  • TimestampExtended 1個(gè)字節(jié)归斤。時(shí)間戳擴(kuò)展字段
  • stream id 3個(gè)字節(jié)〉蟀叮總是0
  • tag data 數(shù)據(jù)部分

圖上第一個(gè)tag:

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


    FLV-TAG
tag的劃分

圖中紅色部分是我標(biāo)出"("與")"前后的的兩個(gè)back-pointers脏里,都是4個(gè)字節(jié)。而括號(hào)中間就是第一個(gè)TAG虹曙。那是怎么計(jì)算的呢迫横?我們就以這個(gè)做個(gè)示例。

  • 首先第一個(gè)back-pointers是0x00000000酝碳,那是因?yàn)楹竺媸堑谝粋€(gè)TAG矾踱。所以他為0。
  • 然后根據(jù)我們我們前面格式獲取到size是0x00 0x01 0x74 = 372疏哗。也就是說從stream id后面再加上372個(gè)字節(jié)就到了第一個(gè)TAG的末尾呛讲,我們數(shù)一下。tag header有11個(gè)字節(jié)沃斤。那么到第一個(gè)TAG圣蝎,總共有372+11=383=0x17f。
  • 接下來我們找到0x17f的地址衡瓶,從工具上很容易找到徘公,正好就是后括號(hào)")"的前面。紅0x00 0x00 0x01 0x7F=372哮针,這代表的是上一個(gè)TAG的大小关面。
  • 最后我們計(jì)算一下坦袍,上一個(gè)TAG數(shù)據(jù)部分是372個(gè)字節(jié),前面type等太、stream id等字段占了11個(gè)字節(jié)捂齐。正好是匹配的。
    上面我們已經(jīng)知道了怎么取劃分每個(gè)TAG缩抡。接下來我們就看TAG的具體內(nèi)容:
tag的內(nèi)容

前面已經(jīng)提到tag分3種奠宜。我們一個(gè)個(gè)看

script

腳本Tag一般只有一個(gè),是flv的第一個(gè)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)包含兩個(gè)AMF包普碎。AMF(Action Message Format)是Adobe設(shè)計(jì)的一種通用數(shù)據(jù)封裝格式套啤,在Adobe的很多產(chǎn)品中應(yīng)用,簡單來說随常,AMF將不同類型的數(shù)據(jù)用統(tǒng)一的格式來描述。第一個(gè)AMF包封裝字符串類型數(shù)據(jù)萄涯,用來裝入一個(gè)“onMetaData”標(biāo)志绪氛,這個(gè)標(biāo)志與Adobe的一些API調(diào)用有,在此不細(xì)述涝影。第二個(gè)AMF包封裝一個(gè)數(shù)組類型(srs返回為object類型)枣察,這個(gè)數(shù)組中包含了音視頻信息項(xiàng)的名稱和值。具體說明如下

類型 說明
0 Number type 8 Bypte Double
1 Boolean type 1 Bypte bool
2 String type 后面2個(gè)字節(jié)為長度
3 Object type
4 MovieClip type
5 Null type
6 Undefined type
7 Reference type
8 ECMA array type 數(shù)組,類似Map
10 Strict array type
11 Date type
12 Long string type 后面4個(gè)字節(jié)為長度
FLV-script-1.png

上圖為第一個(gè)AMF包

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


    FLV_script-2.png

    上圖為第二個(gè)AMF

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

表示數(shù)組,類似Map伯襟。后面4個(gè)字節(jié)為數(shù)組的個(gè)數(shù)猿涨。然后是鍵值對,第一個(gè)為鍵姆怪,2個(gè)字節(jié)為長度叛赚。后面跟具體的內(nèi)容澡绩。接著3個(gè)字節(jié)表示值的類型,然后根據(jù)類型判斷長度俺附。
上圖我們可以判斷肥卡,總共有13個(gè)鍵值對。
第一個(gè)長度為8個(gè)字節(jié)是duration事镣。值類型是0x004073步鉴,第一個(gè)字節(jié)是00,所以是double璃哟,8個(gè)字節(jié)氛琢。

第二個(gè)長度5個(gè)字節(jié)是width。值也是double類型沮稚,8個(gè)字節(jié)艺沼。
依次解析下去...

Audio
flv-audio1

flv-audio2

flv-audio3

flv-audio4

視頻中第二個(gè)tag為音頻tag

stream-id之后:

  • 前4位為音頻格式
類型
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位為采樣率(對于AAC總是3)
類型
0 5.5-kHz
1 11-kHz
2 22-kHz
3 44-kHz
  • 接著1位為采樣的長度(壓縮過的音視頻都是16bit)
類型
0 snd8Bit
1 snd16Bit
  • 接著1位為音頻類型(對于AAC總是1)
類型
0 sndMono
1 sndStereo
video

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


flv-video1
  • type=0x09=9。這里應(yīng)該是一個(gè)video蕴掏。
  • size=0x000030=48障般。長度為48。
  • timestreamp=0x000000盛杰。
  • TimestampExtended =0x00挽荡。
  • stream id =0x000000

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

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

  • 前4位為幀類型Frame Type
類型
1 keyframe (for AVC, a seekable frame) 關(guān)鍵幀
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
  • 后4位為編碼ID (CodecID)
類型
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

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

  • AVCPacketType 占1個(gè)字節(jié)
類型
0 AVCDecoderConfigurationRecord(AVC sequence header)
1 AVC NALU
2 AVC end of sequence (lower level NALU sequence ender is not required or supported)

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

  • CompositionTime 占3個(gè)字節(jié)
條件
AVCPacketType ==1 Composition time offset
AVCPacketType !=1 0

再看到第二個(gè)video tag


flv-video

我們看到 AVCPacketType =1,而后面三個(gè)字節(jié)為000043伙单。這是一個(gè)視頻幀數(shù)據(jù)获高。
解析到的數(shù)據(jù)完全符合上面的理論。

sps pps
前面我們提到第一個(gè)video 一般存放的是sps和pps吻育。這里我們具體解析下sps和pps內(nèi)容念秧。先看下存儲(chǔ)的格):

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(占兩個(gè)字節(jié))
跳過27個(gè)字節(jié)后,是0x01
pps size=0x0005=118(占兩個(gè)字節(jié))
跳過5個(gè)字節(jié)扫沼,就到了back-pointers出爹。

視頻幀數(shù)據(jù)
解析出sps和pps tag后庄吼,后面的video tag就是真正的視頻數(shù)據(jù)內(nèi)容了


flv-video3

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

引用:

flv格式詳解+實(shí)例剖析

FLV視頻封裝格式詳解

【總結(jié)】FLV(AAC/AVC)學(xué)習(xí)筆記

將h.264視頻流封裝成flv格式文件(一.flv格式)

將h.264視頻流封裝成flv格式文件(二.開始動(dòng)手)

RTMP協(xié)議中的AMF數(shù)據(jù)

rtmp協(xié)議簡單解析以及用其發(fā)送h264的flv文件

FLV 文件格式解析

(原)從mp4,flv文件中解析出h264和aac,送解碼器解碼失敗:,avc1與H264區(qū)別在這里其實(shí)有人遇到了和我一樣的問題:http://stackoverflow.com/questions/11330764/ffmpeg-cant-decode-h264-stream-frame-data

simplest_mediadata_test

rtmp_relay
RtmpMindmap

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末总寻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子梢为,更是在濱河造成了極大的恐慌渐行,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铸董,死亡現(xiàn)場離奇詭異祟印,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)粟害,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門蕴忆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悲幅,你說我怎么就攤上這事套鹅。” “怎么了汰具?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵卓鹿,是天一觀的道長。 經(jīng)常有香客問我留荔,道長吟孙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任聚蝶,我火速辦了婚禮杰妓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碘勉。我一直安慰自己稚失,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布恰聘。 她就那樣靜靜地躺著,像睡著了一般吸占。 火紅的嫁衣襯著肌膚如雪晴叨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天矾屯,我揣著相機(jī)與錄音兼蕊,去河邊找鬼。 笑死件蚕,一個(gè)胖子當(dāng)著我的面吹牛孙技,可吹牛的內(nèi)容都是我干的产禾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼牵啦,長吁一口氣:“原來是場噩夢啊……” “哼亚情!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起哈雏,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤楞件,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后裳瘪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體土浸,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年彭羹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黄伊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡派殷,死狀恐怖还最,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愈腾,我是刑警寧澤憋活,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站虱黄,受9級特大地震影響悦即,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜橱乱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一辜梳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泳叠,春花似錦作瞄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至种蝶,卻和暖如春契耿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背螃征。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工搪桂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盯滚。 一個(gè)月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓踢械,卻偏偏與公主長得像酗电,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子内列,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容

  • FLV是一個(gè)二進(jìn)制文件撵术,簡單來說,其是由一個(gè)文件頭(FLV header)和很多tag組成(FLV body)德绿。 ...
    zjjcc閱讀 3,057評論 1 3
  • 在如何看待嗶哩嗶哩的開源 HTML5 播放器內(nèi)核 flv.js?中荷荤,flv.js作者有這樣一段回復(fù):一些人問我為什...
    合肥黑閱讀 2,407評論 1 4
  • 簡介 FLV(Flash Video)是現(xiàn)在非常流行的流媒體格式,由于其視頻文件體積輕巧移稳、封裝播放簡單等特點(diǎn)蕴纳,使其...
    第八區(qū)閱讀 22,006評論 22 33
  • FLV封裝格式 FLV(Flash Video)是Adobe公司推出的一種流媒體格式,由于其封裝后的音視頻文件體積...
    _zzbb閱讀 7,926評論 3 11
  • 轉(zhuǎn)眼又要開學(xué)了个粱,這個(gè)暑假最有意義的莫過于在曼大的四周古毛,想著要記錄下些什么。下飛機(jī)已二十余天都许,翻著相冊零散地寫下仍是...
    萊萊_閱讀 359評論 0 3