1. 程式人生 > >視音訊編解碼學習工程:FLV封裝格式分析器

視音訊編解碼學習工程:FLV封裝格式分析器

=====================================================

視音訊編解碼學習工程系列文章列表:

=====================================================

本文介紹一個自己的開源小專案:FLV封裝格式分析器。FLV全稱是Flash Video,是網際網路上使用極為廣泛的視訊封裝格式。像Youtube,優酷這類視訊網站,都使用FLV封裝視訊。我這個專案規模不大,主要可以用來學習FLV封裝格式結構。此外它還支援分離FLV中的視訊流和音訊流。使用VC 2010的MFC開發完成。在對FLV進行視音訊分離的過程中,用到了一個Github開源小工程:flvparse。在此插一句:我發現Github上優秀的東西真的還是挺多的,許多零散的小工程,效果都很不錯。這個flvparse做的就不錯。

軟體的exe以及原始碼已經上傳到了SourceForge上。和之前的H.264碼流分析器一樣,增加了一個英文介面,緊跟國際潮流~


更新記錄==============================

1.1版(2014.7.8)

 * 更換了介面

 * 原工程支援Unicode編碼

 * 支援中英文切換

新版(2016.1.1)

 * 精簡了程式碼,使之更通俗易懂

 * 修改了少量介面UI

 * 修正了少量解析錯誤

 * 添加了對TagData首位元組的解析

已經更新至SourceForge上

軟體使用介紹

軟體的使用相當簡單。軟體執行後,首先開啟一個FLV檔案。單擊“開始”,可以解析出一系列Tag,列表顯示在軟體右側。不同種類的Tag被標記成了不同的顏色。列表中包含了每個Tag的型別、大小、時間戳、StreamID、TagData首位元組。軟體的左側,顯示了FLV檔案頭資訊。


此外軟體做了一個英文介面,如下所示。


注:如果勾選上“輸出視訊”,“輸出音訊”的話,可以輸出分離後的視訊流和音訊流。在這裡要注意的是音訊支援MP3格式,AAC格式貌似有點問題。

軟體原始碼簡析

原始碼方面和普通的MFC程式差不太多,懂得MFC的人應該很快就能看懂。唯一比較特殊的地方,就在於對開源專案flvparse進行了一些改動,在此就不細說了。註釋方面還是很充分的。

FLV封裝原理

FLV格式的封裝原理,貼上來輔助學習之用。

FLV(Flash Video)是Adobe公司設計開發的一種流行的流媒體格式,由於其視訊檔案體積輕巧、封裝簡單等特點,使其很適合在網際網路上進行應用。此外,FLV可以使用Flash Player進行播放,而Flash Player外掛已經安裝在全世界絕大部分瀏覽器上,這使得通過網頁播放FLV視訊十分容易。目前主流的視訊網站如優酷網,土豆網,樂視網等網站無一例外地使用了FLV格式。FLV封裝格式的檔案字尾通常為“.flv”。

總體上看,FLV包括檔案頭(File Header)和檔案體(File Body)兩部分,其中檔案體由一系列的Tag組成。因此一個FLV檔案是如圖1結構。


圖1.檔案結構(簡圖)

其中,每個Tag前面還包含了Previous Tag Size欄位,表示前面一個Tag的大小。Tag的型別可以是視訊、音訊和Script,每個Tag只能包含以上三種類型的資料中的一種。圖2展示了FLV檔案的詳細結構。


圖2.FLV檔案結構(詳圖)

下面詳細介紹一下三種Tag的Tag Data部分的結構。

(a)Audio Tag Data結構(音訊Tag)

音訊Tag開始的第1個位元組包含了音訊資料的引數資訊,從第2個位元組開始為音訊流資料。結構如圖3所示。


圖3.Audio Tag Data結構

第1個位元組的前4位的數值表示了音訊編碼型別。如表1所示。

表1.音訊編碼型別

含義

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

14

 MP3 8-Khz

15

 Device-specific sound

第1個位元組的第5-6位的數值表示音訊取樣率。如表2所示。

表2.音訊取樣率

含義

0

 5.5kHz

1

 11KHz

2

 22 kHz

3

 44 kHz

PS:從上表可以發現,FLV封裝格式並不支援48KHz的取樣率。

第1個位元組的第7位表示音訊取樣精度。如表3所示。

表3.音訊取樣精度

含義

0

 8bits

1

 16bits

第1個位元組的第8位表示音訊型別。

表4. 音訊型別

含義

0

 sndMono

1

 sndStereo

(b)Video Tag Data結構(視訊Tag)

視訊Tag也用開始的第1個位元組包含視訊資料的引數資訊,從第2個位元組為視訊流資料。結構如圖4所示。


圖4.Video Tag Data結構

第1個位元組的前4位的數值表示幀型別。如表5所示。

表5.幀型別

含義

1

 keyframe (for AVC,a seekable frame)

2

 inter frame (for AVC,a nonseekable frame)

3

 disposable inter frame (H.263 only)

4

 generated keyframe (reserved for server use)

5

 video info/command frame

第1個位元組的後4位的數值表示視訊編碼型別。如表6所示。

表6.視訊編碼型別

含義

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

(c)Script Tag Data結構(控制幀)

該型別Tag又通常被稱為Metadata Tag,會放一些關於FLV視訊和音訊的元資料資訊如:duration、width、height等。通常該型別Tag會跟在File Header後面作為第一個Tag出現,而且只有一個。結構如圖5所示。


圖5.Script Tag Data結構

第一個AMF包:

第1個位元組表示AMF包型別,一般總是0x02,表示字串。第2-3個位元組為UI16型別值,標識字串的長度,一般總是0x000A(“onMetaData”長度)。後面位元組為具體的字串,一般總為“onMetaData”(6F,6E,4D,65,74,61,44,61,74,61)。

第二個AMF包:

第1個位元組表示AMF包型別,一般總是0x08,表示陣列。第2-5個位元組為UI32型別值,表示陣列元素的個數。後面即為各陣列元素的封裝,陣列元素為元素名稱和值組成的對。常見的陣列元素如表7所示。

表7.常見MetaData

含義

duration

 時長

width

 視訊寬度

height

 視訊高度

videodatarate

 視訊位元速率

framerate

 視訊幀率

videocodecid

 視訊編碼方式

audiosamplerate

 音訊取樣率

audiosamplesize

 音訊取樣精度

stereo

 是否為立體聲

audiocodecid

 音訊編碼方式

filesize

 檔案大小