最近做RTMP Client,费力很大功夫终于把H264码流推送到Red5服务器上,封装包的时候用到FLV文件格式,下面是结合FLV Format Specification进行的分析。
1. FLV文件对齐方式
FLV文件以大端对齐方式存放多字节整型。
如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。
如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。
2. FLV文件格式
FLV文件格式比较简单,分为Header和Body两部分。
即:|FLV_Header(9)|FLV_Body(n)|,括号里是长度,以byte为单位。
以下分别介绍Header和Body的具体内容格式。
3. FLV Header格式
FLV Body的内容长度是固定的,格式如下:
| F(8) | L(8) | V(8) | Version(8) | TypeFlagsReserved(5) | TypeFlagsAudio(1)| TypeFlagsReserved(1) | TypeFlagsVideo(1) | DataOffset(32) |.
可知FLV Header头部的长度为9 bytes。
前三个字节为FLV,十六进制表示为 0x46 0x4C 0x56。
Version为FLV的版本号,一般为0x01。
TypeFlagsReserved为保留位,均为0
TypeFlagsAudio为FLV文件中是否包括音频数据,1是有,0是没有。
TypeFlagsVideo为FLV文件中是否包括视频数据,1是有,0是没有。
DataOffset为FLV Header的长度,为固定值0x00000009。
4. FLV Body格式
FLV Body的内容为多个Tag和Tag的长度组成。
即:
| PreviousTagSize0(32) | Tag1(PreviousTagSize1) |PreviousTagSize1(32) | Tag2 | ……| PreviousTagSizeN-1(32) | TagN(previousTagSizeN)| previousTagSizeN(32) |
PreviousTagSize0为0x00000000。
Tag为每一个内容,目前包括音频、视频、脚本。
previousTagSize为前一个Tag的长度。
5. FLV Tag格式
FLV Tag是FLV Body的内容,具体Tag同样是由Tag Header和Tag Data组成。
即FLV Tag Format :
| TagType(8) | DataSize(24) | Timestamp(24) |TimestampExtended(8) | StreamID(24) | Data(DataSize) |
TagType为Tag的类型:
目前支持的类型:
音频为0x08;
视频为0x09;
脚本数据为0x12。
DataSize为Data的长度。
Timestamp为相对第一个Tag的时间戳,因此第一个Tag的时间戳为0。也可以将所有Tag的时间戳全配置为0,解码器会自动处理。
StreamID为默认的全为0。
Data为具体的数据内容,
如果TagType=0x08,为AudioData;
如果TagType=0x09,为VideoData;
如果TagType=0x12,为ScriptDataObject,但该项因为内容不固定,所以在FLV文件中可以没有该Tag内容。
6. VideoData格式
VideoData的内容,同样包括VideoData Header和VideoData Body。
即VideoData Format:
Video Header = | FrameType(4) | CodecID(4) |
VideoData = | FrameType(4) | CodecID(4) | VideoData(n) |
FrameType为数据类型,1为关键帧,2为非关键帧,3为h263的非关键帧,4为服务器生成关键帧,5为视频信息或命令帧。
CodecID为包装类型,1为JPEG,2为H263,3为Screen video,4为On2 VP6,5为On2 VP6,6为Screen videoversion 2,7为AVC。
VideoData为数据具体内容:
如果CodecID=2,为H263VideoPacket;
如果CodecID=3,为ScreenVideopacket;
如果CodecID=4,为VP6FLVVideoPacket;
如果CodecID=5,为VP6FLVAlphaVideoPacket;
如果CodecID=6,为ScreenV2VideoPacket;
如果CodecID=7,为AVCVideoPacket;
7. AVCVideoPacket格式
AVCVideoPacket同样包括Packet Header和Packet Body两部分:
即AVCVideoPacket Format:
| AVCPacketType(8)| CompostionTime(24) | Data |
AVCPacketType为包的类型:
如果AVCPacketType=0x00,为AVCSequence Header;
如果AVCPacketType=0x01,为AVC NALU;
如果AVCPacketType=0x02,为AVC end ofsequence
CompositionTime为相对时间戳:
如果AVCPacketType=0x01, 为相对时间戳;
其它,均为0;
Data为负载数据:
如果AVCPacketType=0x00,为AVCDecorderConfigurationRecord;
如果AVCPacketType=0x01,为NALUs;
如果AVCPacketType=0x02,为空。
8. AVCDecorderConfigurationRecord格式
AVCDecorderConfigurationRecord包括文件的信息。
具体格式如下:
| cfgVersion(8) | avcProfile(8) | profileCompatibility(8) |avcLevel(8) | reserved(6) | lengthSizeMinusOne(2) | reserved(3) | numOfSPS(5) |spsLength(16) | sps(n) | numOfPPS(8) | ppsLength(16) | pps(n) |
未完,待续...