Rtmp 分析參見:https://blog.csdn.net/fdsafwagdagadg6576/article/details/109462544
本文主要內(nèi)容來自:FLV格式詳解 https://blog.csdn.net/weixin_42462202/article/details/88661883
該文一層一層介紹了FLV格式.本文對其內(nèi)容增加了思維導(dǎo)圖并補充了實例.
1 定義:
FLV是一種文件格式.類似的還有Mp4.
作用:
將H264,Aac裸流封裝成文件格式.
為什么要對裸流做文件格式封裝?即FLV文件和原始文件區(qū)別?
1 文件播放. 原始文件播放讀一幀解析一幀. 沒有整體時長,不能拖拽,倍速播放等音視頻控制了.
FLV文件因為有FLV tag保存音視頻信息。所以可以顯示視頻時長,播放進度,拖拽,倍速播放等.
2 是協(xié)議支持,rtmp協(xié)議要求,數(shù)據(jù)必須Flv格式. rtc協(xié)議數(shù)據(jù)才是裸流。
關(guān)鍵字:tag
****2 整體介紹:****
Flv由 “Flv header” 和 “Flv Body”組成。
Flv Body由一系列的Tag組成,每個Tag又有一個preTagSize字段,標(biāo)記著前面一個Tag的大小
2.1 Flv Header
Header長度一般都是固定的9個字節(jié):

2.2 Flv Body
Flv Body由一個一個Tag組成,每個Tag都有一個preTagSize字段,標(biāo)記著前面一個Tag的大小。

Tag有三種類型,Audio Tag(音頻Tag),Video Tag(視頻Tag),script Tag(又稱Metadata Tag).
每個Tag由“Tag Header”和“Tag Data”組成.Tag=Tag Header+Tag Data.
對于不同類型的Tag,“Tag Header”的格式都是相同的,“Tag Body”的格式就不一樣了.
2.2.1 Tag header:
圖片說明:3種tag的tag header格式一樣,只有Tag type 域的值不同,分別是08(音頻),09(視頻),12(script data).
Notes:注意Flv header和Flv tag header是不同的.
下面這張圖歸納一下上面講的內(nèi)容,看完后對flv應(yīng)該有個總體的了解了
一般一個flv文件由一個頭部信息,一個script Tag,以及若干個video Tag和audio Tag組成。
圖片說明:tag之間是previous tag size
2.2.2 每種類型的Tag Data詳解
Flv有三種tag:“Audio Tag Data”、“Video Tag Data”、“Script Tag Data”
1)、Audio Tag Data
如果SoundFormat=10,那么音頻數(shù)據(jù)就是AAC AUDIO DATA。
notes:音頻參數(shù)只有一個字節(jié)
- **AAC ** AUDIO DATA 格式如下:
2)、Video Tag Data
a) 視頻參數(shù):
對于H.264數(shù)據(jù)來說,CodecID = 7。
當(dāng)CodecID = 7時,視頻數(shù)據(jù)就是AVCVIDEOPACKET格式。
b) 視頻數(shù)據(jù):
下面講解一下AVCVIDEOPACKET。
- 如果 AVCPacketType = 0,那么Data就是AVCDecoderConfigurationRecord格式。
以下是AVCDecoderConfigurationRecord的結(jié)構(gòu)
notes: SPS/PPS 說明
- 如果 AVCPacketType = 1,那么Data結(jié)構(gòu)就簡單多了。
notes: I,P,B幀.h264 沒有start code 0x00 00 00 01
c) 實例分析:

i)Tag Header:
Type:09(Tag的類型,包括音頻(0x08)、視頻(0x09)、script data(0x12))
Datasize:00 00 2e(Tag Data 部分的大?。?br>
Timestamp:00 00 00(時間戳)
Timestamp_ex:00(時間戳的擴展部分)
StreamID:00 00 00(總是0)
ii) Tag data:
FrameType | CodecID:17(keyframe | AVC)(視頻tag的參數(shù))
因為CodecID=7,所以視頻數(shù)據(jù)就是AVCVIDEOPACKET格式
- AVCVIDEOPACKET:
AVCPaketType:00(ACVPacket的類型,0: AVC sequence header;1: AVC NALU;2: AVC end of sequence)
CompositionTime:00 00 00
因為ACVPaketType==0,所以Data=AVCDecoderConfigurationRecord
- AVCDecoderConfigurationRecord:
configurationVersion:01
AVCProfileIndication:64
profile_compatibility:00
AVCLevelIndication:1e
lengthSizeMinusOne:ff (NALUSize的長度,計算方法為:1 + (lengthSizeMinusOne & 3)=4)
numOfSequenceParameterSets:e1(低五位為SPS的個數(shù),計算方法為:numOfSequenceParameterSets & 0x1F=1)
sequenceParameterSetLength:00 18(SPS的長度,24)
sequenceParameterSetNALUnits:67 64 00 1e ac d9 40 a0 33 b0 11 00 00 03 02 47 00 00 6d 34 0f 16 2d 96(SPS)
numOfPictureParameterSets:01(PPS的個數(shù))
pictureParameterSetLength:00 06(PPS的長度)
pictureParameterSetNALUnits:68 eb e3 cb 22 c0(PPS)
previousTagSize:00 00 00 39
3) Script Tag Data
該類型Tag又通常被稱為MetadataTag,會放一些關(guān)于FLV視頻和音頻的元數(shù)據(jù)信息如:duration、width、height等。通常該類型Tag會跟在FileHeader后面作為第一個Tag出現(xiàn),而且只有一個。
notes:用amf語法實現(xiàn)metadata數(shù)據(jù)key-value存儲.amf 數(shù)據(jù)的都是"類型+[長度]+值"的形式.
結(jié)構(gòu)如下圖所示

AMF包:第一個字節(jié)表示AMF包的類型
第一個AMF包:
第一個字節(jié)一般為0x02,表示字符串,第2-3個字節(jié)表示字符串的長度,一般為0x000A,后面跟的就是字符串,一般為"onMetaData"。
第二AMF包:
第一個字節(jié)為0x08,表示數(shù)組,第2-5個字節(jié)表示數(shù)組元素個數(shù),后面跟著就是數(shù)組的元素,格式為:元素名長度(UI16) + 元素名(UI8[n]) + 元素的值(double),最后以“009”結(jié)尾。
常見的數(shù)組元素
補充: Nginx-rtmp之 AMF0 的處理 https://www.cnblogs.com/jimodetiantang/p/8975945.html
這篇blog:有具體的抓包實例分析. 對script tag data論述更詳細.
notes: amf0和amf3有什么區(qū)別?:通常都是amf0, amf3是它的特殊補充.
參見 https://blog.csdn.net/HandSome696/article/details/72518927
總結(jié):
圖片說明:此圖沒有對script tag,video tag,audio tag做區(qū)分和具體介紹.
其他參考:多媒體文件格式之FLV: https://www.cnblogs.com/jimodetiantang/p/8992425.html
(有audio,video各個域的詳細說明)
本文如果對您有幫助,請隨手點個贊,謝謝
