将H264和AAC封装成FLV
FLV官方标准文档
http://download.macromedia.com/f4v/video_file_format_spec_v10_1.pdf
FLV是一个二进制文件,FLV Header和FLV Body构成。
FLV Header一般有9个字节,前3个字节是”FLV”,即0x46 0x4c 0x56。
第4个字节是版本号,目前一般是0x01。
第5个字节的前五位保留为0当有音频时第六位置1第七位保留为0当有视频时第八位置1。
第6到9字节为FLV Header的长度,一般为9。
FLVBody由一连串的PreviousTagSize+Tag构成。PreviousTagSize表示前一个Tag的长度,一共占4字节。Tag有三种类型,分别是VideoTag、AudioTag、ScriptsTag。ScriptsTag总是第一个tag,并且只有一个。每个Tag都有TagHeader和TagData。
1、TagHeader占11个字节。
image.png2、ScriptsTagData中包含2个AMF Packet。第一个AMF Packet包含13个字节是固定的。
image.png第二个AMF Packet包含了很多音视频的信息,比如,视频长度、比特率、甚至关键帧索引等信息。它开头是1个字节的AMF包类型,一般是0x08,表示数组。第2-5个字节表示数组的个数。再后面就是metadata数组了。最后会有3个字节的结束符(0x0 0x0 0x9)。
3、VideoTagData包含VideoHeader和VideoData。
VideoHeader第一个字节是video info。前4bit表示视频数据帧的类型,后4bit表示编码器的类型。
如果是H264的视频,则VideoHeader还要多4个字节。包含1个字节的avc_packet_type和3个字节的composition_time。
avc_packet_type:0x0表示avc sequence header,0x01表示NALU。
VideoData需要完整的一帧的数据,而在RTP传输中,由于一帧数据太大,不利于传输,在传输时会对一帧进行分片。所以在这里需要将接收到的FU_A的NALU转换成原始的NALU,然后将多个NALU组成完成的一帧视频数据,存入VideoData中。至此VideoTagData就封装完成了。
4、AudioTagData也包含AudioHeader和AudioData。
AudioHeader第一个字节是audio info。前4bit是音频格式,第5-6bit是采样率,第7bit是采样精度,第8bit是声道数。如果音频格式是AAC的则还要多一个字节的aac_packt_type。
aac_packt_type:0x0表示AAC Sequence Header,0x01表示AAC Raw。
AAC一帧数据通常较小,在RTP传输中,每次都是一个包一帧数据,不像H264视频需要分开。所以取出RTP中的音频数据,加上ADTS头就可以直接放入AudioData。至此AudioTagData就封装完成了。
备注:
FLV存储的都是大端数据,所以需要把小端数转成大端数再写入文件中。