代码生成x264编码flv记录
最近研究h264+aac 的flv直播 ,把flv格式完全的啃了下。下面简单说下。
flv 文件开始是9个字节的flv头。 46 4c 56 就是 F L V 的十六进制。第4个字节 01 表示FLV版本号
第5个字节表示文件音视频信息。1是只有视频, 5 音频和视频混合 4 只有音频。
再后面4个字节 0x00 0x00 0x00 0x09,转十进制为9,表示FLV header的长度.
然后后面4个字节是0 0 0 0 ,prev tag size 该值永远为0,因为文件才开始,一个tag都还没有呢。
然后后面就是tag了,通常都是第一个tag是脚本, 一个字节0x12 ,脚本里记录了flv一些必要的参数。比如视频音频编码,视频宽高
声音采样率,声道,文件大小,播放长度。tag结束后,会记录4个字节的prev tag size,标明上一个tag 的总长度
-------------------------------------------------------------------------------------------------------------------------------
声音tag 格式
tag head 11字节
11字节 = TYPE 1字节 + Size 3字节 + timestamp 4字节 +streamID 3字节
TYPE 0x8表示音频tag
Size 为后面具体数据长度
streamID 永久为0
timestamp 时间戳
head后面接tag body
1个字节 定义了声音 编码 声道 采样率 。
如果这个声音是0x10 AAC编码,则后面有个1个AACPacketType 字节的数据。
然后后面就是声音实际数据了。
结束了就写入4字节的prev tag size, 一个tag就写入完毕。(注:aac 的编码还有个aac tag头 标明一些额外的aac信息,aac具体百度)
-----------------------------------------------------------------------------------------------------------------------------------
视频tag
tag head 11字节
11字节 = TYPE 1字节 + Size 3字节 + timestamp 4字节 +streamID 3字节
TYPE 0x9表示视频tag
Size 为后面具体数据长度
streamID 永久为0
timestamp 时间戳
head后面接tag body
-------------------------------------------------------------
由于x264编码,我们flv文件必须在实际视频tag之前把pps sps相关参数标明,不然后续解码器无法工作。
即flv头+prevsize+ 0x12的脚本tag + 0x9视频tag头(11字节)+ 0x17 0x00 0x00 0x00 0x00 0x01 sps[1] sps[2] sps[3] 0xff 0xe1 ....0x9视频tag整体包长4字节+ xTag+xBody+PrevTagSize+.....
最先开始的0x9视频tag 即装的是sps pps数据。然后后续的视频tag才装实际的nalu数据。
数据包格式
0x9视频tag头(11字节)+ frametype&codecID 1字节+ 0x01(avcPacketType)+ 0x00 0x00 0x00 (composition3字节,具体值要看avcPacketType)+ 4字节记录后面NALU数据的长度 + 具体NALU数据+ prev tag size.