音视频封装-FLV

文章目录

      • FLV格式
        • 1. FLV Header
        • 2. FLV File Boby
        • 3. FLV Tag
        • 4. AudioTag
          • 4.1 AudioTag Header
          • 4.2 AudioTagBody
            • 4.3 AACAUDIODATA
        • 5. VideoTag
          • 5.1 VideoTag Header
          • 5.2 VideoTag Boby
            • 5.2.1 AVCVIDEOPACKET
          • 5.3 AVCDecoderConfigurationRecord
          • 5.4 NALUs
        • 6. ScriptTag
          • 6.1 ScriptTagBody
          • 6.2 onMetadata

FLV格式

FLV = FLV Header + FLV File Boby

类型说明

UI8:1字节

UI24:2字节

UI32:4字节

UB:1bit

UI8[n]:n 字节

UB[n]:n bit

 

1. FLV Header
字段 类型 说明
Signature UI8[3] 签名,总是’FLV’
Version UI8 文件版本,0x01表示FLV1
TypeFlagsReserved UB[5] 保留,总是0
TypeFlagsAudio UB[1] 为1表示文件中存在Audio Tag
TypeFlagsReserved UB[1] 保留,总是0
TypeFlagsVideo UB[1] 为1表示文件中存在Video Tag
DataOffset UI32 FLV Header的长度,当FLV版本为FLV1时,DataOffset总是9

注:DataOffset将用来表示更大的FLV Header在之后版本中。

 

2. FLV File Boby
字段 类型 说明
PreviousTagSize0 UI32 总是0
Tag1 FLVTAG 第一个FLV Tag
PreviousTagSize1 UI32 前一个FLV Tag的长度,FLV1版本中,大小为FLV Tag Header(11字节) + FLV Tag Boby
Tag2 FLVTAG 第二个FLV Tag
PreviousTagSizeN-1 UI32 倒数第二个PreviousTagSize
TagN FLVTAG 倒数第一个Tag
PreviousTagSizeN UI32 倒数第一个PreviousTagSize

 

3. FLV Tag
字段 类型 说明
Reserved UB[2] 保留给FMS,应该为0
Filter UB[1] 一般用不到,未加密的文件应为0,加密的标签应为1
TagType UB[5] Tag类型
8为Audio Tag
9为Video Tag
18为Script Tag
DataSize UI24 FLV Tag Body的长度,也就是FLV Tag Size - FLV Tag Header
Timestamp UI24 Tag的毫秒时间戳,是相对于第一个Tag的相对时间戳,第一个Tag时间戳总为0
TimestampExtended UI8 TimestampExtended表示时间戳的高8位,而Timestamp表示时间戳的低24位,扩展时间戳为SI32类型。
StreamID UI24 总为0
AudioTagHeader if TagType=8
AudioTagHeader
当TagType=8,包含AudioTagHeader
VideoTagHeader if TagType=9
VideoTagHeader
当TagType=9,包含VideoTagHeader
EncryptionTagHeader if Filter=1
EncryptionTagHeader
当Filter=1,包含EncryptionTagHeader,一般无用
FilterParams if Filter=1
FilterParams
当Filter=1,包含FilterParams,一般无用
Data AudioData/VideoData/ScriptData 当TagType=8,Data为AudioData。
当TagType=9,Data为VideoData。
当TagType=18,Data为ScriptData。

注:

数据的时间戳信息dts,dts = TimeStamp(3bytes) | TimeStampExtended(1bytes)<< 24 。

总结:

FLV File = FLV File Header(9字节) + FLV File Boby

FLV File Boby = PreTagSize0(4字节) + Tag1 + PreTagSize1 + … + PreTagSize(N-1) + TagN + PreTagSizeN

FLVTag = TagHeader(11字节) + TagBoby

TagBoby = VideoTag/AudioTag/ScriptTag = VideoTag/AudioTag/ScriptTag Header + VideoTag/AudioTag/ScriptTag Data

 

4. AudioTag
4.1 AudioTag Header

AudioTagHeader包含音频的元信息。

字段 类型 说明
SoundFormat UB[4] 音频编码格式
2=MP3
3=Linear PCM, little endian
7=G711A
8=G711U
10=AAC
11=Speex
14=MP3(8KHZ)
SoundRate UB[2] 音频采样率
0 = 5.5 kHz
1 = 11 kHz
2 = 22 kHz
3 = 44 kHz
SoundSize UB[1] 采样深度
0 = 8-bit samples
1 = 16-bit samples
SoundType UB[1] 声道数
0 = Mono sound
1 = Stereo sound
AACPacketType if SoundFormat=10
UI8
只有SoundFormat=10时,才有AACPakcetType。
0 = AAC sequence header
1 = AAC raw
4.2 AudioTagBody
字段 类型 说明
SoundData 如果SoundFormat == 10,此字段为AACAUDIODATA
否则为Varies by format
4.3 AACAUDIODATA
字段 类型 说明
Data 如果AACPacketType=0,此字段为AudioSpecificConfig
或者AACPacketType=1,此字段为Raw AAC Frame Data UI8[]

AudioSpecificConfig 结构描述非常复杂,在标准文档中是用伪代码描述的,这里先假定要编码的音频格式,做一下简化。假定音频格式为AAC-LC,音频采样率为44100。

音视频封装-FLV_第1张图片

在 FLV 的文件中,一般情况下 AAC sequence header 这种包只出现1次,而且是第一个 audio tag。为什么需要这种 tag(AAC sequence header):因为在做 FLV demux 的时候,如果是 AAC 的音频,需要在每帧 AAC ES 流(ES流=裸流)前边添加 7 个字节 ADST 头,ADST 是解码器通用的格式,也就是说 AAC 的纯 ES 流要打包成 ADST 格式的 AAC 流,解码器才能正常播放

注:

当SoundFormat等于10时,音频编码为AAC,需要给每帧音频帧加上关键信息头(>=7字节),因为FLV中AAC数据帧不包含关键信息,不能直接用于解码。

 

5. VideoTag
5.1 VideoTag Header
字段 类型 说明
Frame Type UB[4] 视频帧的类型
1=关键帧
2=非关键帧
3~5不常用
CodecID UB[4] 视频编码格式
2 = Sorenson H.263
3 = Screen video
4 = On2 VP6
5 = On2 VP6 with alpha channel
6 = Screen video version 2
7 = AVC
AVCPacketType if CodecID=7
UI8
AVCPacket类型
0 = AVC sequence header
1 = AVC NALU
2 = AVC end of sequence
CompostionTime if CodecID=7
SI24
IF AVCPacketType == 1
Composition time offset
ELSE
0
  • VideoTagHeader的第1个字节包含了视频参数(视频帧类型,视频编码类型)
  • CompostionTime = pts - dts,Flv Tag Header有个TimeStamp(dts)。在存在B帧的情况下,需要计算出pts = dts + CompostionTime。
5.2 VideoTag Boby
字段 类型 说明
VideoTagBoby IF FrameType == 5
UI8
ELSE (
IF CodecID == 2
H263VIDEOPACKET
IF CodecID == 3
SCREENVIDEOPACKET
IF CodecID == 4
VP6FLVVIDEOPACKET
IF CodecID == 5
VP6FLVALPHAVIDEOPACKET
IF CodecID == 6
SCREENV2VIDEOPACKET
IF CodecID == 7
AVCVIDEOPACKET
)
5.2.1 AVCVIDEOPACKET
字段 类型 说明
Data IF AVCPacketType == 0
AVCDecoderConfigurationRecord
IF AVCPacketType == 1
One or more NALUs (Full frames are required)
5.3 AVCDecoderConfigurationRecord

AVCDecoderConfigurationRecord 包含着是 H.264 解码相关比较重要的 SPS 和 PPS 信息,在给 AVC 解码器送数据流之前一定要把 SPS 和 PPS 信息送出,否则的话,解码器不能正常解码。

  • 在解码器 stop 之后再次 start 之前,如 seek,快进快退状态切换等,都需要重新送一遍 SPS 和 PPS 的信息。
  • AVCDecoderConfigurationRecord 在 FLV 文件中一般情况也只出现 1 次,也就是第一个 video tag。

AVCDecoderConfigurationRecord 长度为 sizeof(UI8) * (11 + sps_size + pps_size)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NPpWrLmd-1646361402502)(v2-7d7050429cb47ebc7586cc630ed3bb97_720w.png)]

5.4 NALUs

当Data为Nalu时, Data = NaluLength(指示NaluBoby的长度,4字节) + NaluBoby(不包含起始码00 00 00 01)。

当I帧包含了SPS, PPS等关键信息时,把关键信息和I帧当成一个整体进行解析。

 

6. ScriptTag
6.1 ScriptTagBody

ScriptTagBody 内容用 AMF 编码

音视频封装-FLV_第2张图片

SCRIPTDATAScriptTagBody组成, 主要包括NameValue两部分:

  • Name

一个string类型的SCRIPTDATAVALUE

  • Value

一个ECMA Array类型的SCRIPTDATAVALUE

音视频封装-FLV_第3张图片

SCRIPTDATA:

  • Name : 名为“onMetadata”的String类型。
  • Value:ECMAArray类型,包含音视频相关的信息。

 

6.2 onMetadata

FLV metadata object 保存在 SCRIPTDATA 中, 叫 onMetaData。

音视频封装-FLV_第4张图片

flv格式解析:

https://zhuanlan.zhihu.com/p/28722048

你可能感兴趣的:(流媒体,音视频,视频编解码)