FLV格式解析

簡介

FLV(Flash Video)是如今很是流行的流媒體格式,因爲其視頻文件體積輕巧、封裝播放簡單等特色,使其很適合在網絡上進行應用,目前主流的視頻網站無一例外地使用了FLV格式。另外因爲當前瀏覽器與Flash Player緊密的結合,使得網頁播放FLV視頻垂手可得,也是FLV流行的緣由之一。html

FLV是流媒體封裝格式,咱們能夠將其數據看爲二進制字節流。整體上看,FLV包括文件頭(File Header)和文件體(File Body)兩部分,其中文件體由一系列的Tag及Tag Size對組成。 git

用到資源文件:github

FLV格式解析

先來一張圖,這是《科比退役演講》下載)的一個FLV視頻。我使用的是UltraEdit的二進制查看工具。 數組

flv-head

header

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

  • signature 佔3個字節 固定FLV三個字符做爲標示。通常發現前三個字符爲FLV時就認爲他是flv文件。圖中0x46 0x4C 0x56,表明FLV
  • Version 佔1個字節 標示FLV的版本號。這裏咱們看到是1
  • Flags 佔1個字節 內容標示。第0位和第2位,分別表示 video 與 audio 存在的狀況.(1表示存在,0表示不存在)。截圖看到是0x05,也就是00000101,表明既有視頻,也有音頻。
  • DataOffset 4個字節 表示FLV的header長度。這裏能夠看到固定是9

Body

FLV的body部分是一系列的back-pointers+tag構成的bash

  • back-pointers固定4個字節,表示前一個tag的size
  • tag分三種類型:video,audio,scripts.
tag組成
tag type+tag data size+Timestamp+TimestampExtended+stream id+ tag data
複製代碼
  • type 1個字節。8爲Audio,9爲Video,18爲scripts
  • tag data size 3個字節。表示tag data的長度。從streamd id 後算起。
  • Timestreamp 3個字節。時間戳
  • TimestampExtended 1個字節。時間戳擴展字段
  • stream id 3個字節。老是0
  • tag data 數據部分

圖上第一個tag:markdown

  • type=0x12=18,表示是一個scripts,FLV中,header後的第一個tag是script tag,script tag內容是amf格式數據,包含兩個amf.
  • size=0x00 0x01 0x74 = 372
  • timpestreamp = 0x00 0x00 0x00
  • TimestampExtended=0x00
  • streamid=0x00 0x00 0x00
  • tag data部分:
    FLV-TAG
tag的劃分

圖中紅色部分是我標出"("與")"先後的的兩個back-pointers,都是4個字節。而括號中間就是第一個TAG。那是怎麼計算的呢?咱們就以這個作個示例。網絡

  • 首先第一個back-pointers是0x00000000,那是由於後面是第一個TAG。因此他爲0。
  • 而後根據咱們咱們前面格式獲取到size是0x00 0x01 0x74 = 372。也就是說從stream id後面再加上372個字節就到了第一個TAG的末尾,咱們數一下。tag header有11個字節。那麼到第一個TAG,總共有372+11=383=0x17f。
  • 接下來咱們找到0x17f的地址,從工具上很容易找到,正好就是後括號")"的前面。紅0x00 0x00 0x01 0x7F=372,這表明的是上一個TAG的大小。
  • 最後咱們計算一下,上一個TAG數據部分是372個字節,前面type、stream id等字段佔了11個字節。正好是匹配的。 上面咱們已經知道了怎麼取劃分每一個TAG。接下來咱們就看TAG的具體內容:
tag的內容

前面已經提到tag分3種。咱們一個個看ide

script

腳本Tag通常只有一個,是flv的第一個Tag,用於存放flv的信息,好比duration、audiodatarate、creator、width等。 首先介紹下腳本的數據類型。全部數據都是以數據類型+(數據長度)+數據的格式出現的,數據類型佔1byte,數據長度看數據類型是否存在,後面纔是數據。工具

通常來講,該Tag Data結構包含兩個AMF包。AMF(Action Message Format)是Adobe設計的一種通用數據封裝格式,在Adobe的不少產品中應用,簡單來講,AMF將不一樣類型的數據用統一的格式來描述。第一個AMF包封裝字符串類型數據,用來裝入一個「onMetaData」標誌,這個標誌與Adobe的一些API調用有,在此不細述。第二個AMF包封裝一個數組類型(srs返回爲object類型),這個數組中包含了音視頻信息項的名稱和值。具體說明以下

類型 說明
0 Number type 8 Bypte Double
1 Boolean type 1 Bypte bool
2 String type 後面2個字節爲長度
3 Object type
4 MovieClip type
5 Null type
6 Undefined type
7 Reference type
8 ECMA array type 數組,相似Map
10 Strict array type
11 Date type
12 Long string type 後面4個字節爲長度

FLV-script-1.png
上圖爲第一個AMF包

  • type=0x02對應String
  • size=0A=10
  • value=onMetaData 正好是10個字節。
    FLV_script-2.png
    上圖爲第二個AMF
  • type=0x08 對應ECMA array type。

表示數組,相似Map。後面4個字節爲數組的個數。而後是鍵值對,第一個爲鍵,2個字節爲長度。後面跟具體的內容。接着3個字節表示值的類型,而後根據類型判斷長度。 上圖咱們能夠判斷,總共有13個鍵值對。 第一個長度爲8個字節是duration。值類型是0x004073,第一個字節是00,因此是double,8個字節。 第二個長度5個字節是width。值也是double類型,8個字節。 依次解析下去...

Audio

flv-audio1
flv-audio2
flv-audio3
flv-audio4
視頻中第二個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太難,使用<<東風破>> mv視頻

flv-video1

  • type=0x09=9。這裏應該是一個video。
  • size=0x000030=48。長度爲48。
  • timestreamp=0x000000。
  • TimestampExtended =0x00。
  • stream id =0x000000

咱們看到數據部分: 視頻信息+數據 視頻信息,1個字節。

StreamId以後的數據就表示是VideoTagHeader,若是是avc,VideoTagHeader會多出4個字節的信息就是AVCPacketType和CompositionTime

  • 前4位爲幀類型Frame Type
類型
1 keyframe (for AVC, a seekable frame) 關鍵幀
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會多出4個字節的信息,AVCPacketType 和CompositionTime。

  • AVCPacketType 佔1個字節
類型
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解碼相關比較重要的sps和pps信息,再給AVC解碼器送數據流以前必定要把sps和pps信息送出,不然的話解碼器不能正常解碼。並且在解碼器stop以後再次start以前,如seek、快進快退狀態切換等,都須要從新送一遍sps和pps的信息.AVCDecoderConfigurationRecord在FLV文件中通常狀況也是出現1次,也就是第一個video tag.

  • CompositionTime 佔3個字節
條件
AVCPacketType ==1 Composition time offset
AVCPacketType !=1 0

再看到第二個video tag

flv-video
咱們看到 AVCPacketType =1,然後面三個字節爲000043。這是一個視頻幀數據。 解析到的數據徹底符合上面的理論。

sps pps 前面咱們提到第一個video 通常存放的是sps和pps。這裏咱們具體解析下sps和pps內容。先看下存儲的格):

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(佔兩個字節) 跳過27個字節後,是0x01 pps size=0x0005=118(佔兩個字節) 跳過5個字節,就到了back-pointers。

視頻幀數據 解析出sps和pps tag後,後面的video tag就是真正的視頻數據內容了

flv-video3
這是第二個video tag其實和以前圖同樣,只是我圈出來關鍵信息。先看下格式 frametype=0x17=00010111 AVCPacketType =1 Composition Time=0x000043 後面就是NALU DATA

引用:

flv格式詳解+實例剖析

FLV視頻封裝格式詳解

【總結】FLV(AAC/AVC)學習筆記

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

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

RTMP協議中的AMF數據

rtmp協議簡單解析以及用其發送h264的flv文件

FLV 文件格式解析

(原)從mp4,flv文件中解析出h264和aac,送解碼器解碼失敗:,avc1與H264區別在這裏其實有人遇到了和我同樣的問題:stackoverflow.com/questions/1…

simplest_mediadata_test

rtmp_relay RtmpMindmap

相關文章
相關標籤/搜索