前言
最近因为要使用rtmp推H.264,了解到rtmp只能推flv格式,不能直接推H.264,所以专门学习了flv格式,自己将H.264格式封装成Flv,盯着一堆二进制看了两天,哈哈哈,有点头大。
这篇文章将介绍Flv格式,至于如何将H.264封装成Flv,以及如何使用rtmp推H.264将在后面的文章介绍。
Flv由 “Flv header” 和 “Flv Body”组成。
Flv Body由一系列的Tag组成,每个Tag又有一个preTagSize字段,标记着前面一个Tag的大小。
下图是Flv Header的内容,(UI8表示无符号8位,也就是一个字节;UB[5]表示一个字节中的5位)
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 Body”的格式就不一样了。
下面这张图归纳一下上面讲的内容,看完后对flv应该有个总体的了解了。
一般一个flv文件由一个头部信息,一个script Tag,以及若干个video Tag和audio Tag组成。
下面来详细讲解每种类型的Tag Data
Flv有三种tag:“Audio Tag Data”、“Video Tag Data”、“Script Tag Data”
1、Audio Tag Data
如果SoundFormat=10,那么音频数据就是AACAUDIODATA。
AACAUDIODATA格式如下:
2、Video Tag Data
对于H.264数据来说,CodecID = 7。
当CodecID = 7时,视频数据就是AVCVIDEOPACKET格式。
下面讲解一下AVCVIDEOPACKET。
以下是AVCDecoderConfigurationRecord的结构
说这么多可能有点乱了,下面来解析一个实例
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)
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出现,而且只有一个。
结构如下图所示
AMF包:第一个字节表示AMF包的类型
第一个AMF包:
第一个字节一般为0x02,表示字符串,第2-3个字节表示字符串的长度,一般为0x000A,后面跟的就是字符串,一般为"onMetaData"。
第二AMF包:
第一个字节为0x08,表示数组,第2-5个字节表示数组元素个数,后面跟着就是数组的元素,格式为:元素名长度(UI16) + 元素名(UI8[n]) + 元素的值(double),最后以“009”结尾。
常见的数组元素