音视频封装-FLV

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
字段类型说明
SignatureUI8[3]签名,总是’FLV’
VersionUI8文件版本,0x01表示FLV1
TypeFlagsReservedUB[5]保留,总是0
TypeFlagsAudioUB[1]为1表示文件中存在Audio Tag
TypeFlagsReservedUB[1]保留,总是0
TypeFlagsVideoUB[1]为1表示文件中存在Video Tag
DataOffsetUI32FLV Header的长度,当FLV版本为FLV1时,DataOffset总是9

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

 

2. FLV File Boby
字段类型说明
PreviousTagSize0UI32总是0
Tag1FLVTAG第一个FLV Tag
PreviousTagSize1UI32前一个FLV Tag的长度,FLV1版本中,大小为FLV Tag Header(11字节) + FLV Tag Boby
Tag2FLVTAG第二个FLV Tag
PreviousTagSizeN-1UI32倒数第二个PreviousTagSize
TagNFLVTAG倒数第一个Tag
PreviousTagSizeNUI32倒数第一个PreviousTagSize

 

3. FLV Tag
字段类型说明
ReservedUB[2]保留给FMS,应该为0
FilterUB[1]一般用不到,未加密的文件应为0,加密的标签应为1
TagTypeUB[5]Tag类型
8为Audio Tag
9为Video Tag
18为Script Tag
DataSizeUI24FLV Tag Body的长度,也就是FLV Tag Size - FLV Tag Header
TimestampUI24Tag的毫秒时间戳,是相对于第一个Tag的相对时间戳,第一个Tag时间戳总为0
TimestampExtendedUI8TimestampExtended表示时间戳的高8位,而Timestamp表示时间戳的低24位,扩展时间戳为SI32类型。
StreamIDUI24总为0
AudioTagHeaderif TagType=8
AudioTagHeader
当TagType=8,包含AudioTagHeader
VideoTagHeaderif TagType=9
VideoTagHeader
当TagType=9,包含VideoTagHeader
EncryptionTagHeaderif Filter=1
EncryptionTagHeader
当Filter=1,包含EncryptionTagHeader,一般无用
FilterParamsif Filter=1
FilterParams
当Filter=1,包含FilterParams,一般无用
DataAudioData/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包含音频的元信息。

字段类型说明
SoundFormatUB[4]音频编码格式
2=MP3
3=Linear PCM, little endian
7=G711A
8=G711U
10=AAC
11=Speex
14=MP3(8KHZ)
SoundRateUB[2]音频采样率
0 = 5.5 kHz
1 = 11 kHz
2 = 22 kHz
3 = 44 kHz
SoundSizeUB[1]采样深度
0 = 8-bit samples
1 = 16-bit samples
SoundTypeUB[1]声道数
0 = Mono sound
1 = Stereo sound
AACPacketTypeif 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 的文件中,一般情况下 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 TypeUB[4]视频帧的类型
1=关键帧
2=非关键帧
3~5不常用
CodecIDUB[4]视频编码格式
2 = Sorenson H.263
3 = Screen video
4 = On2 VP6
5 = On2 VP6 with alpha channel
6 = Screen video version 2
7 = AVC
AVCPacketTypeif CodecID=7
UI8
AVCPacket类型
0 = AVC sequence header
1 = AVC NALU
2 = AVC end of sequence
CompostionTimeif 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
字段类型说明
VideoTagBobyIF 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
字段类型说明
DataIF 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 编码

在这里插入图片描述

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

  • Name

一个string类型的SCRIPTDATAVALUE

  • Value

一个ECMA Array类型的SCRIPTDATAVALUE

在这里插入图片描述

SCRIPTDATA:

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

 

6.2 onMetadata

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

在这里插入图片描述

flv格式解析:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值