音视频封装:FLV格式详解和打包H264、AAC方案(下)

本文深入剖析FLV文件格式,重点讲解如何将H264视频帧和AAC音频数据封装进FLV的Video Tag和Audio Tag。通过分析Tag头部信息、Video Tag中的AVCDecoderConfigurationRecord以及Audio Tag的AudioSpecificConfig,揭示了FLV中音视频数据的组织结构。此外,还介绍了提取和打包FLV中音视频裸数据的步骤,为理解和处理FLV文件提供了详细指导。

Video Tag 视频Tag: 该Tag类型封装真实的视频裸数据,虽然支持H263、H264等编码 类型的视频,但是现在主流还是H264,所以下面会重点分析如何将 H264视频帧打进Flv方法。 Flv Parse 解析的结果如下:

previous tag1: 十六机制:0x00 00 01 37 十进制:311 因表示了前一个Metadata Tag的长度是311字节,这跟上篇分析结果是一致的; 

Videoag theader:

十六进制:0x09 00 00 2C 00 00 00 00 00 00 00 Tagtype: 十六进制:0x09

二进制:0000 1001 通过前1-2bit即知道非加密,后面4-8bit10010即十进制为9则为Video Tag类型; DataSize: 十六进制:0x 00 00 2C 十进制:44 说明这个Video Tag的data字段长度为44字节; Timestamp: 十六进制:0x 00 00 00 由于是第一个Video Tag该字段一般就是默认为0; TimeStampExtended: 十六进制:0x 00 00 00 时间戳扩展字段也是默认为0; Stream ID: 十六进制:0x 00 00 00 无论那种类型的Tag,一般默认为0; Video Tag Data: 视频头: 在Video tag的Header后面按道理就是视频裸数据了,但是这里我们需要分析下第 一个字节,判断视频数据的编码格式等信息,然后才知道视频裸数据是怎么打包进 Video Tag的Data字段的,第一个Video Tag的Data部分如图所示: 视频头字段格式:

待分析数据第一字节: 十六进制:0x17 我们先分析Video Tag数据部分的第一个字节即视频头 Frame type: 十六进制:0x17 二进制:0001 0111 十进制:1 通过前面1-4bit位发现十进制为1,即认为是key frame; CodeID: 十六进制:0x17 二进制:0001 0111 十进制:7 说明这个Video的编码格式AVC也就是常说的H264; 特别注意: 分析到这里,我们发现这个Video Tag的承载数据是AVC即H264编码格式的数 据,一般情况下Flv承载的数据格式都是这种。那么就需要继续向下面分析后面的 Packet Type字段。 Packet Typ数据格式:

 

对各个字段解释: CTS:这个字段需要结合PTS和DTS一块来理解,至于还不知道PTS和DTS参考以 前的文章,我这里的理解就是编码延时,有更深理解的可以留言交流。 CTS的大小:cts = pts - dts/90,CTS的单位是毫秒,除以90是因为H264的采样 率是90KHz,这里是为了将时间戳单位转化为毫秒;

同时H264编码时有编码级别和规范的说法,一般而言profile级别是没有B帧的, 这就意味着pts等于dts,那cts直接为0即可;如果是profile main级别,说明有B帧 则需要根据公式计算,B帧时双向预测帧,则有编码延时大部分情况不启用这边级 别编码方式; 待分析数据第2-5字节: 十六进制:0x00 00 00 00 Avc packet: 十六进制:0x00 十进制:0 通过说明后面承载的数据是H264的序列头也就是编码器配置SPS PPS而不是裸数 据Nalu; CTS: 十六进制:0x00 00 00 十进制:0 由于Av Packet是0,则这里的cts肯定是0,因为不是真正的视频帧所以没有cts的 概念; 后面我们会分析Avc Packet是Nalu的数据部分,现在先分析Avc Packet是Avc序列 头的数据部分。 AVCDecoderConfigurationRecord部分: 分析完视频数据前五个字节,后面就是Video Tag Data字段对SPS PPS的封装: 待分析数据: 十六机制:0x 01 64 00 28 FF E1 Configuration version: 十六进制:0x01 一般默认固定为0x01; Avc Profile Indication: 十六进制:0x64 这是提取来自SPS的字段值,表示编码级别,表示的profile high这种级别。

Profile compatibility: 十六进制:0x00 Avc Level Indication: 十六进制:0x28 这是也是提取来自SPS的字段值,表示编码能力,跟分辨率、帧率、码率有关 系; Reserved: 十六进制:0xFF 二进制:0x1111 1111 Length size minus one: 十六进制:0xFF 二进制:0x1111 1111 十进制:3,暂时没用字段; Reserved: 十六进制:0xE1 二进制:0x1110 0001 Num sequence parmeter sets: 十六进制:0xE1 二进制:0x1110 0001 紧接着的后面只有一个SPS; 接下来就很容易分析了: 0x00 18表示SPS的开始部分,长度为24; 0x67-0xA8 的24个字节就是SPS数据部分; 0x01 表示PPS的个数 0x00 0x04表示PPS的长度 0x68-0xB0 表示PPS的数据部分; 看到这里大家肯定想知道SPS PPS的具体字段,这里就不详细解释了,会在后面 的文章详细讲解。作用就是初始化播放器,没有这个值播放器拿不到编码器编码 H264数据的参数信息也就没办法进行解码和渲染播放。SPS PPS值很关键,跟首 屏秒开、拖动随机播放等功能有密切功能,后面帮大家分析分析。同样为了交叉 验证,我用程序将这个flv的音视频裸数据进行了分离,然后用Stream Eye工具分 析了其中的SPS PPS,结果如下: 分析到这里,分析了Video Tag的视频编码格式为H264即AVC的 AVCDecoderConfigurationRecord数据类型,下面再分析一个NALU类型的Video Tag数据部分: 刚才我们分析的Video Tag1,Data部分承载的SPS PPS 部分,现在我们分析的 Video Tag3,中间是音频,先跳过,等下分析。对于Video Tag3也是直接跳过11 字节的Tag Header前面已经分析,不再赘述,直接分析Tag Data部分: 待分析数据第一字节: 十六进制:0x17 我们先分析Video Tag数据部分的第一个字节即视频头 Frame type: 十六进制:0x17 二进制:0001 0111 十进制:1 通过前面1-4bit位发现十进制为1,即认为是key frame; CodeID: 十六进制0x17 二进制:0001 0111 十进制:7 说明这个Video的编码格式AVC也就是常说的H264; 待分析数据第2-5字节: 十六进制:0x00 00 00 00 Avc packet: 十六进制0x00 十进制:0 通过说明后面承载的数据是H264即AVC的NALU单元; CTS: 十六进制0x00 00 00 十进制:0 由于此AVC的编码级别显示没有B帧,则PTS=DTS,所以这里的CTS一直为0; NALU Legth: 十六机制:0x00 00 01 EF 十进制:495 表示这个NALU的长度为495字节,同时我们分析这个Video Tag的头中显示长度 为504,也就很快发现Data部分就是前面分析的这9个字节,剩余的495则为 NALU的真实数据,这就是NALU的裸数据,非常关键。 接下来的0x65-0x29都是NALU的数据,NALU也是有不同的类型,后面文章会详 细介绍。 这里0x65就是NALU的类型,二进制为0110 0101,其中红色显示的5bit就是 NALU类型,这里是IDR帧类型。 至此我们分析完了Flv的Video Tag部分,基本也分析了H264的Nalu打包方法。 Audio Tag音频 Tag: 虽然Flv支持的音频编码格式不仅仅支持AAC,也支持一些MP3 等。但是目前项目实际使用时,我们基本都会把音频编码格式转成 AAC,然后打包进Flv,所以这里也重点分析下AAC裸数据如何打 进Flv,先看下第一个Audio的Tag: Audio Tag Header部分: 这里基本参考Script Tag的头部分析即可,这里简单说明下: 待分析数据: 十六进制:0x08 00 00 04 00 00 00 00 00 00 00 Tagtype: 十六进制:0x08 二进制:0000 1000 通过前1-2bit即知道非加密,后面4-8bit10010即十进制为8 则Tag类型Audio tag; DataSize: 十六进制:0x 00 00 04 十进制:4 说明这个Audio Tag的data字段长度为4字节; Timestamp: 十六进制:0x 00 00 00 第一个Audio Tag该字段一般就是默认为0; TimeStampExtended: 十六进制:0x 00 00 00 时间戳扩展字段也是默认为0; Stream ID: 十六进制:0x 00 00 00 默认为0,该字段暂时未启用; Audio Tag Data部分: 音频头格式:

 

我们先分析数据部分第一字节弄清楚音频的编码格式等基本信息: 待分析数据: 十六进制:0xAF 二进制:1010 1111 SoundFormat: 十六进制:0xAF 二进制:1010 1111 通过前4个bit,则表示的A即12,所以音频编码为AAC; SoundRate: 十六进制:0xAF 二进制:1010 1111 说明AAC采样频率用的44KHz SoundSize: 十六进制:0xAF 二进制:1010 1111 说明AAC采样精度是16bit即2字节; SoundType: 十六进制:0xAF 二进制:1010 1111 说明AAC的声道数是2; 其实对于AAC音频来说,一般Audio Tag的音频头字段都是0xAF,这里变化不大。 由于是AAC,接 下来需要继续分析一个字节。 AAC Packet Type: 待分析数据: 十六机制数据:0x00 AAC Packet Type: 十六进制:0x00 十进制:0 这里为0则说明下面的真实数据是AAC Sequence Header,这个字段有点类似H264 的编码配置SPS或者PPS,一般只在整个Flv文件出现一次。 那么下面分析AAC Sequence Header字段,这个值需要解析AAC的裸数据得到, 同时它起到的作用和AAC的ADTS一样,但是这里并不是ADTS,可以认为是AAC 裸数据的另外一种封装格式。 AAC Sequence Header: 这个字段也被称为是AudioSpecificConfig,AudioSpecificConfig包含着一些更加 详细的音频信息,它的定义在ISO14496-3中1.6.2.1。 格式如下:如果有疑问,你可以加 q q  群  384170753 一起交流

 

 

待分析数据: 十六机制数据:0x12 10 二进制数据:0001 0010 0001 0000 AAC Profile: 十六进制:0x12 二进制:0001 0010 十进制:2 这里为2,则说明编码方式是AAC LC AAC Sample Frequence: 十六进制:0x12 0x10 二进制:0001 0010 0001 0000 十进制:4 这里为4,则说明采样频率是44KHz,对于AAC基本都是这个值; AAC Channel Config: 十六进制:0x12 0x10 二进制:0001 0010 0001 0000 十进制:4 这里为2,则说明AAC的音频通道是2; AAC Reserve: 十六进制:0x12 0x10 二进制:0001 0010 0001 0000 这里三个bit保留位都是0; 综上所述,对于音频编码格式是AAC的,则第一个Audio Tag基本是四字节的固定 值: 0xAF 00 12 10,这可以作为判断音频为AAC的快速方法。当然有时会有点出入。 我们分析了Audio的第一个Tag值为AudioSpecificConfig类型的,再分析一个是裸 数据的Tag Data字段如下图: 说明: 1. 第一部分红框11字节还是Audio Tag的Header字段,上面已经分析不再赘述; 2. 第二部分承载数据的蓝框1字节是音频编码类型等信息,前面分析AAC Sequence Header已经分析了,一般只有一路音频,所以该字段固定不再变化; 3. 绿框决定了该Audi Tag的数据部分是AAC Sequence Header还是 AAC Raw Data,这里值为0x01,则说明该Audio承载的AAC Raw裸数据; 4. 后面的粉框9字节即为AAC Raw Data,关于AAC的编码方式和裸数据含义以后 再讲。 FLV总结: 这篇文章首先讲解了Flv的基本概念、目前现状以及在直播方案中的应用。后面在 我本地通过Flv Parse专门分析了Flv文件的封装格式。其中Audio Tag和Video Tag 已经分析到AAC和H264的数据帧如何封装到Tag的Data字段,基本按照分析的方 法就能很简单的将Flv里面的音频和视频裸数据提取出来,当然也能将H264和 AAC数据打包封装成Flv。 下面说解装的操作步骤: 1. 分析Flv的头字段,一般9字节作为开头,主要是根据头字段判断是不是FLV格 式,其次判断是否有音视频。因为Flv只封装视频,没有音频是可以传输和播放 的,这个我在本地做了实验,VLC是可以播放的,甚至没有Script Tag也是可以 的; 2. 接着分析第一个Tag,一般是Script Tag。这个Tag前面是11字节的Tag Header 头数据,后面AMF0和AMF1包,严格按照这两个包的定义分析即可,上文已经详 细说明; 3. 分析视频的第一个Video Tag,还是11字节的Tag Header头,紧接着分析Data的 第一字节,分析帧类型和编码方式。帧类型能找出关键帧,这是很多特殊操作的 关键。 4. 如果3分析出来的编码方式不是AVC即H264,那么直接走5.如果是AVC,则继续 分析下一个字节AVC packet类型,一般不是AVC的编码配置就是NALU字段。第 一个是AVC的编码配置,则提取出SPS PPS等信息,如果是NALU则根据NALU的 类型分析出裸码流; 5. 直接按照指定的编码方式分析裸数据即可; 6. 分析第一个音频Video Tag,同样分析Tag Data字段的第一字节分析音频编码方 式和基本信息,如果不是AAC则直接走7;如果是再分析第二字节,判断AAC的 Packet类型是AAC Sequence Header还是AAV Law裸数据。是AAC Sequence Header就进一步分析AAC相关信息,如果裸数据,则解析出AAC音频帧即可; 7. 分析AAC Sequence Header即可,参考上文; 8. 后面交替分析Video Tag和Audio Tag的裸数据即可,直到分析结束; 封装步骤跟解装步骤相反即可. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值