Rtmp 分析參見:https://blog.csdn.net/fdsafwagdagadg6576/article/details/109462544
本文主要內容來自:FLV格式詳解 https://blog.csdn.net/weixin_42462202/article/details/88661883
該文一層一層介紹了FLV格式.本文對其內容增加了思維導圖并補充了實例.
1 定義:
FLV是一種文件格式.類似的還有Mp4.
作用:
將H264,Aac裸流封裝成文件格式.
為什么要對裸流做文件格式封裝?即FLV文件和原始文件區別?
1 文件播放. 原始文件播放讀一幀解析一幀. 沒有整體時長,不能拖拽,倍速播放等音視頻控制了.
FLV文件因為有FLV tag保存音視頻信息。所以可以顯示視頻時長,播放進度,拖拽,倍速播放等.
2 是協議支持,rtmp協議要求,數據必須Flv格式. rtc協議數據才是裸流。
關鍵字:tag
****2 整體介紹:****
Flv由 “Flv header” 和 “Flv Body”組成。
Flv Body由一系列的Tag組成,每個Tag又有一個preTagSize字段,標記著前面一個Tag的大小
2.1 Flv Header
Header長度一般都是固定的9個字節:
2.2 Flv Body
Flv Body由一個一個Tag組成,每個Tag都有一個preTagSize字段,標記著前面一個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是不同的.
下面這張圖歸納一下上面講的內容,看完后對flv應該有個總體的了解了
一般一個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,那么音頻數據就是AAC AUDIO DATA。
notes:音頻參數只有一個字節
- **AAC ** AUDIO DATA 格式如下:
2)、Video Tag Data
a) 視頻參數:
對于H.264數據來說,CodecID = 7。
當CodecID = 7時,視頻數據就是AVCVIDEOPACKET格式。
b) 視頻數據:
下面講解一下AVCVIDEOPACKET。
- 如果 AVCPacketType = 0,那么Data就是AVCDecoderConfigurationRecord格式。
以下是AVCDecoderConfigurationRecord的結構
notes: SPS/PPS 說明
- 如果 AVCPacketType = 1,那么Data結構就簡單多了。
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 部分的大小)
Timestamp:00 00 00(時間戳)
Timestamp_ex:00(時間戳的擴展部分)
StreamID:00 00 00(總是0)
ii) Tag data:
FrameType | CodecID:17(keyframe | AVC)(視頻tag的參數)
因為CodecID=7,所以視頻數據就是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的個數,計算方法為: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的個數)
pictureParameterSetLength:00 06(PPS的長度)
pictureParameterSetNALUnits:68 eb e3 cb 22 c0(PPS)
previousTagSize:00 00 00 39
3) Script Tag Data
該類型Tag又通常被稱為MetadataTag,會放一些關于FLV視頻和音頻的元數據信息如:duration、width、height等。通常該類型Tag會跟在FileHeader后面作為第一個Tag出現,而且只有一個。
notes:用amf語法實現metadata數據key-value存儲.amf 數據的都是"類型+[長度]+值"的形式.
結構如下圖所示
AMF包:第一個字節表示AMF包的類型
第一個AMF包:
第一個字節一般為0x02,表示字符串,第2-3個字節表示字符串的長度,一般為0x000A,后面跟的就是字符串,一般為"onMetaData"。
第二AMF包:
第一個字節為0x08,表示數組,第2-5個字節表示數組元素個數,后面跟著就是數組的元素,格式為:元素名長度(UI16) + 元素名(UI8[n]) + 元素的值(double),最后以“009”結尾。
常見的數組元素
補充: Nginx-rtmp之 AMF0 的處理 https://www.cnblogs.com/jimodetiantang/p/8975945.html
這篇blog:有具體的抓包實例分析. 對script tag data論述更詳細.
notes: amf0和amf3有什么區別?:通常都是amf0, amf3是它的特殊補充.
參見 https://blog.csdn.net/HandSome696/article/details/72518927
總結:
圖片說明:此圖沒有對script tag,video tag,audio tag做區分和具體介紹.
其他參考:多媒體文件格式之FLV: https://www.cnblogs.com/jimodetiantang/p/8992425.html
(有audio,video各個域的詳細說明)