一. FLV封装简图

FLV格式主要由Header, Body(PreviousTagSize, Tag)组成,简单结构图如下:

FLV格式封装初学

二. FLV文件头Header

主要包括flv的类型,版本信息以及包含是否包含音视频情况,共占9个字节,分别如下:

1. 文件标识(3B):总是为”FLV”,0x46 0x4c 0x56

2. 版本(1B):目前为0x01

3. 流信息(1B):文件的标志位说明。前5位保留,必须为0;第6位为音频Tag:1表示有音频;第七位保留,为0; 第8位为视频Tag:1表示有视频.如果音视频均包含,则为0x05.

4. Header长度(4B):整个header的长度,一般为9(版本为0x01时);大于9表示下面还有扩展信息。即0x00000009

 

三. FLV文件体

文件体主要包括PreviousTagSize, Tag. 具体组成如下:

FLV格式封装初学

1. PreviousTagSize

PreviousTagSize 表示前一个tag的大小,共占4个字节.所以PreviousTagSize 0是0.

2. Tag

Tag是flv结构中数据的主要承载者,并且音视频数据,脚本数据都将封装成一个tag数据,并且每一个Tag中只能存放一种类型数据,故Tag包含Tag header和Tag Data两部分,Tag Header中主要指出数据类型,数据大小,时间戳,扩展时间戳以及StreamID(总为0).

2.1 Tag头部

Tag类型(1):0x08:音频; 0x09:视频; 0x12:脚本; 其他:保留   //用于区分Tag的类型

数据区长度(3):数据区的长度

时间戳(3):整数,单位是毫秒。对于脚本型的tag总是0 (CTS)

时间戳扩展(1):将时间戳扩展为4bytes,代表高8位。很少用到

StreamsID(3):总是0

例:

type=0x12=18。这里应该是一个scripts。
size=0x000125=293。长度为293。
timestreamp=0x000000。这里是scripts,所以为0
TimestampExtended =0x00
stream id =0x000000

2.2 Tag数据

数据区(由数据区长度决定):数据实体.Tag数据共有三种类型,Audio, Video, Script.

(1) Script Tag Data结构(控制帧)

脚本Tag一般只有一个,是flv的第一个Tag,用于存放flv的信息,比如duration、audiodatarate、creator、width等。

在脚本数据中,所有数据都是以数据类型+(数据长度)+数据的格式出现的. 数据类型占1byte,数据长度看数据类型是否存在,后面才是数据.

一般来说,该Tag Data结构包含两个AMF包。AMF(Action Message Format)是Adobe设计的一种通用数据封装格式,在Adobe的很多产品中应用,简单来说,AMF将不同类型的数据用统一的格式来描述。第一个AMF包封装字符串类型数据,用来装入一个“onMetaData”标志,这个标志与Adobe的一些API调用有,在此不细述。第二个AMF包封装一个数组类型,这个数组中包含了音视频信息项的名称和值。具体说明如下,大家可以参照图片上的数据进行理解。

FLV格式封装初学

例:

FLV格式封装初学

上图为第一个AMF包

  • type=0x02对应String
  • size=0A=10
  • value=onMetaData 正好是10个字节。

     

    FLV格式封装初学


    上图为第二个AMF
  • type=0x08 对应ECMA array type。

表示数组,类似Map。后面4个字节为数组的个数。然后是键值对,第一个为键,2个字节为长度。后面跟具体的内容。接着3个字节表示值的类型,然后根据类型判断长度。
上图我们可以判断,总共有13个键值对。
第一个长度为8个字节是duration。值类型是0x004073,第一个字节是00,所以是double,8个字节。
第二个长度5个字节是width。值也是double类型,8个字节。
依次解析下去...

到处,我们已经知道了如何解析FLV中Tag为script的数据。

(2) Video Tag Data结构(视频Tag)

视频Tag用开始的第1个字节包含视频数据的参数信息,从第2个字节为视频流数据:

FLV格式封装初学

第1个字节的前4位的数值表示帧类型,第1个字节的后4位的数值表示视频编码类型。具体格式如下:

FLV格式封装初学

特殊情况:

视频的格式(CodecID)是AVC(H.264)的话,VideoTagHeader会多出4个字节的信息,AVCPacketType 和CompositionTime。

  • AVCPacketType 占1个字节
类型
0 AVCDecoderConfigurationRecord(AVC sequence header)
1 AVC NALU
2 AVC end of sequence (lower level NALU sequence ender is not required or supported)

AVCDecoderConfigurationRecord.包含着是H.264解码相关比较重要的spspps信息,再给AVC解码器送数据流之前一定要把sps和pps信息送出,否则的话解码器不能正常解码。而且在解码器stop之后再次start之前,如seek、快进快退状态切换等,都需要重新送一遍sps和pps的信息.AVCDecoderConfigurationRecord在FLV文件中一般情况也是出现1次,也就是第一个video tag.

  • CompositionTime 占3个字节
条件
AVCPacketType ==1 Composition time offset
AVCPacketType !=1 0

AVCPacketType =0。而后面三个字节也是0。说明这个tag记录的是AVCDecoderConfigurationRecord。包含sps和pps数据。

第二个video tag,  AVCPacketType =1,而后面三个字节为000043。这是一个视频帧数据。

sps pps

前面我们提到第一个video 一般存放的是sps和pps。这里我们具体解析下sps和pps内容。先看下存储的格式(图6):
0x01+sps[1]+sps[2]+sps[3]+0xFF+0xE1+sps size+sps+01+pps size+pps
我们看到图7 。
sps[1]=0x64
sps[2]=00
sps[3]=0D
sps size=0x001B=27
跳过27个字节后,是0x01
pps size=0x0005=118
跳过5个字节,就到了back-pointers。

(3) Audio Tag Data结构(音频Tag)

音频Tag开始的第1个字节包含了音频数据的参数信息,从第2个字节开始为音频流数据。如图为音频Tag结构:

FLV格式封装初学

第1个字节的前4位的数值表示了音频编码类型,第5-6位的数值表示音频采样率,第7位表示音频采样精度,第8位表示音频类型。具体格式如下:

FLV格式封装初学

从上图可以看出,FLV封装格式并不支持48KHz的采样率。

 

参考:

https://www.cnblogs.com/lidabo/p/9018548.html

相关文章: