FLV 是FLASH VIDEO的簡(jiǎn)稱,F(xiàn)LV流媒體格式是隨著Flash MX的推出發(fā)展而來(lái)的視頻格式。由于它形成的文件極小、加載速度極快,使得網(wǎng)絡(luò)觀看視頻文件成為可能,它的出現(xiàn)有效地解決了視頻文件導(dǎo)入Flash后,使導(dǎo)出的SWF文件體積龐大,不能在網(wǎng)絡(luò)上很好的使用等問(wèn)題。
目前網(wǎng)絡(luò)上用flv格式的有哪些網(wǎng)站?
由于flv已經(jīng)成為當(dāng)前視頻文件的主流格式。所以,目前許多在線視頻網(wǎng)站都采用此視頻格式。如優(yōu)酷、搜狐視頻、新浪播客、六間房、56、、酷6等。
為什么一定要是flv格式?
有時(shí)在網(wǎng)站上觀看視頻的時(shí)候是不是打不開(kāi),要安裝什么flash插件?這就是flv格式的好處,在其他網(wǎng)站上觀看視頻也是要安裝flash插件的,而flv格式更是flash下載的格式,所以占很大優(yōu)勢(shì),而且flv格式文件極小、加載速度快,。比如在優(yōu)酷上上傳視頻分享時(shí),你上傳成功之后,里面是不是開(kāi)始顯示進(jìn)行在轉(zhuǎn)碼中了。
目前哪些網(wǎng)站可以下載flv格式的視頻文件?
上面所說(shuō)的flv格式網(wǎng)站上有介紹,這些網(wǎng)站在上傳之后,進(jìn)行轉(zhuǎn)碼都是變成了flv格式,所以在這些網(wǎng)站上下載的視頻都是flv格式的。如:優(yōu)酷、新浪播客、酷6等等。
flv格式的播放器和播放?
flv播放器是一個(gè)類型的媒體播放器是用來(lái)播放Flash視頻從PC ,以及從互聯(lián)網(wǎng)網(wǎng)站。一般的FLV播放器,可以單獨(dú)使用,而不需要使用Adobe Flash創(chuàng)作或發(fā)展工具。
現(xiàn)在在網(wǎng)上下載的很多格式flv播放,除了在專業(yè)的flv格式播放器之外,你還可以了解知道在普通的播放器上也是可以播放的,比如:暴風(fēng)影音、快播、QQ影音等等。
FLV是流媒體封裝格式,我們可以將其數(shù)據(jù)看為二進(jìn)制字節(jié)流。總體上看,F(xiàn)LV包括文件頭(File Header)和文件體(File Body)兩部分,其中文件體由一系列的Tag及Tag Size對(duì)組成。
flv.jpg
先來(lái)一張圖,這是《東風(fēng)破》——周杰倫(下載)的一個(gè)MV視頻。我使用的是Binary Viewer的二進(jìn)制查看工具。
1.png
頭部分由一下幾部分組成
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文件。
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長(zhǎng)度。這里可以看到固定是9
FLV的body部分是由一系列的back-pointers + tag構(gòu)成
back-pointers 固定4個(gè)字節(jié),表示前一個(gè)tag的size。
tag 分三種類型,video、audio、scripts。
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的長(zhǎng)度。從streamd id 后算起。
Timestreamp 3個(gè)字節(jié)。時(shí)間戳
TimestampExtended 1個(gè)字節(jié)。時(shí)間戳擴(kuò)展字段
stream id 3個(gè)字節(jié)??偸?
tag data 數(shù)據(jù)部分
我們根據(jù)實(shí)例來(lái)分析:
看到第一個(gè)TAG
type=0x12
=18。這里應(yīng)該是一個(gè)scripts。
size=0x000125
=293。長(zhǎng)度為293。
timestreamp=0x000000
。這里是scripts,所以為0
TimestampExtended =0x00
。
stream id =0x000000
我們看一下TAG的data部分:
3.png
圖中紅色部分是我標(biāo)出的兩個(gè)back-pointers,都是4個(gè)字節(jié)。而中間就是第一個(gè)TAG。那是怎么計(jì)算的呢?我們就以這個(gè)做個(gè)示例。
首先第一個(gè)back-pointers是0x00000000
,那是因?yàn)楹竺媸堑谝粋€(gè)TAG。所以他為0。
然后根據(jù)我們我們前面格式獲取到size是0x000125
。也就是說(shuō)從stream id后面再加上293個(gè)字節(jié)就到了第一個(gè)TAG的末尾,我們數(shù)一下一下。stream id以前總共有24個(gè)字節(jié)。那么到第一個(gè)TAG結(jié)束,總共有293+24=137=0x13D
。
接下來(lái)我們找到0x13D
的地址,從工具上很容易找到,正好就是紅色下劃線的前面。紅色部分是0x00000130
=304,這代表的是上一個(gè)TAG的大小。
最后我們計(jì)算一下,上一個(gè)TAG數(shù)據(jù)部分是293個(gè)字節(jié),前面type、stream id等字段占了11個(gè)字節(jié)。正好是匹配的。
上面我們已經(jīng)知道了怎么取劃分每個(gè)TAG。接下來(lái)我們就看TAG的具體內(nèi)容
前面已經(jīng)提到tag分3種。我們一個(gè)個(gè)看
腳本Tag一般只有一個(gè),是flv的第一個(gè)Tag,用于存放flv的信息,比如duration、audiodatarate、creator、width等。
首先介紹下腳本的數(shù)據(jù)類型。所有數(shù)據(jù)都是以數(shù)據(jù)類型+(數(shù)據(jù)長(zhǎng)度)+數(shù)據(jù)的格式出現(xiàn)的,數(shù)據(jù)類型占1byte,數(shù)據(jù)長(zhǎng)度看數(shù)據(jù)類型是否存在,后面才是數(shù)據(jù)。
一般來(lái)說(shuō),該Tag Data結(jié)構(gòu)包含兩個(gè)AMF包。AMF(Action Message Format)是Adobe設(shè)計(jì)的一種通用數(shù)據(jù)封裝格式,在Adobe的很多產(chǎn)品中應(yīng)用,簡(jiǎn)單來(lái)說(shuō),AMF將不同類型的數(shù)據(jù)用統(tǒng)一的格式來(lái)描述。第一個(gè)AMF包封裝字符串類型數(shù)據(jù),用來(lái)裝入一個(gè)“onMetaData”標(biāo)志,這個(gè)標(biāo)志與Adobe的一些API調(diào)用有,在此不細(xì)述。第二個(gè)AMF包封裝一個(gè)數(shù)組類型,這個(gè)數(shù)組中包含了音視頻信息項(xiàng)的名稱和值。具體說(shuō)明如下,大家可以參照?qǐng)D片上的數(shù)據(jù)進(jìn)行理解。
值 | 類型 | 說(shuō)明 |
---|---|---|
0 | Number type | 8 Bypte Double |
1 | Boolean type | 1 Bypte bool |
2 | String type | 后面2個(gè)字節(jié)為長(zhǎng)度 |
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é)為長(zhǎng)度 |
4.png
上圖為第一個(gè)AMF包
type=0x02
對(duì)應(yīng)String
size=0A
=10
value=onMetaData 正好是10個(gè)字節(jié)。
5.png
上圖為第二個(gè)AMF
type=0x08
對(duì)應(yīng)ECMA array type。
表示數(shù)組,類似Map。后面4個(gè)字節(jié)為數(shù)組的個(gè)數(shù)。然后是鍵值對(duì),第一個(gè)為鍵,2個(gè)字節(jié)為長(zhǎng)度。后面跟具體的內(nèi)容。接著3個(gè)字節(jié)表示值的類型,然后根據(jù)類型判斷長(zhǎng)度。
上圖我們可以判斷,總共有13個(gè)鍵值對(duì)。
第一個(gè)長(zhǎng)度為8個(gè)字節(jié)是duration。值類型是0x004073
,第一個(gè)字節(jié)是00,所以是double,8個(gè)字節(jié)。
第二個(gè)長(zhǎng)度5個(gè)字節(jié)是width。值也是double類型,8個(gè)字節(jié)。
依次解析下去...
到處,我們已經(jīng)知道了如何解析FLV中Tag為script的數(shù)據(jù)。
6.png
type=0x09
=9。這里應(yīng)該是一個(gè)video。
size=0x000030
=48。長(zhǎng)度為48。
timestreamp=0x000000
。
TimestampExtended =0x00
。
stream id =0x000000
我們看到數(shù)據(jù)部分:
視頻信息+數(shù)據(jù)
前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,也就是前面那張圖。我們看到AVCPacketType =0。而后面三個(gè)字節(jié)也是0。說(shuō)明這個(gè)tag記錄的是AVCDecoderConfigurationRecord。包含sps和pps數(shù)據(jù)。
再看到第二個(gè)video tag
8.png
我們看到 AVCPacketType =1,而后面三個(gè)字節(jié)為000043
。這是一個(gè)視頻幀數(shù)據(jù)。
解析到的數(shù)據(jù)完全符合上面的理論。
前面我們提到第一個(gè)video 一般存放的是sps和pps。這里我們具體解析下sps和pps內(nèi)容。先看下存儲(chǔ)的格式(圖6):0x01
+sps[1]
+sps[2]
+sps[3]
+0xFF
+0xE1
+sps size
+sps
+01
+pps size
+pps
我們看到圖7 。
sps[1]=0x64
sps[2]=00
sps[3]=0D
sps size=0x001B
=27
跳過(guò)27個(gè)字節(jié)后,是0x01
pps size=0x0005
=118
跳過(guò)5個(gè)字節(jié),就到了back-pointers。
解析出sps和pps tag后,后面的video tag就是真正的視頻數(shù)據(jù)內(nèi)容了
9.png
這是第二個(gè)video tag其實(shí)和圖8一樣,只是我圈出來(lái)關(guān)鍵信息。先看下格式
frametype=0x17
=00010111
AVCPacketType =1
Composition Time=0x000043
后面就是NALU DATA
與視頻格式類似
前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位為采樣率
值 | 類型 |
---|---|
0 | 5.5-kHz |
1 | 11-kHz |
2 | 22-kHz |
3 | 44-kHz |
對(duì)于AAC總是3
接著1位為采樣的長(zhǎng)度
值 | 類型 |
---|---|
0 | snd8Bit |
1 | snd16Bit |
壓縮過(guò)的音頻都是16bit
接著1位為音頻類型
值 | 類型 |
---|---|
0 | sndMono |
1 | sndStereo |
對(duì)于AAC總是1
我們看到第三個(gè)TAG
7.png
這個(gè)留給大家自己來(lái)解析吧。
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答?。?點(diǎn)擊進(jìn)入論壇