基于RTMP协议的音视频传输----FLV格式

基于RTMP协议传输Video 或者Audio,需要将音视频数据转成FLV格式,看一下FLV格式。

FLV格式

总体上,FLV格式由Flv header和Flv Body组成。
基于RTMP协议的音视频传输----FLV格式_第1张图片

FLV Header

Flv Header包含了FLV最基本的信息。

FLV Header
Signature UI8 ‘F’ (0x46)
Signature UI8 ‘L’ (0x4C)
Signature UI8 ‘V’ (0x56)
Version UI8 FLV 版本。例如,0x01 表示 FLV 版本 1
TypeFlags UI8 b[0] 是否存在视频流 ;b[2] 是否存在音频流;其他字段保留,值为0
DataOffset UI32 FLV Header 长度(字节),FLV版本1中,固定为9.

实际看一下FLV文件的16进制数据格式:
基于RTMP协议的音视频传输----FLV格式_第2张图片
上面 46 4c 56 01 05 20 20 20 09 就是FLV Header。 46 4c 56 就是 “FLV”,01表示FLV版本,05转成二进制形式 0000 0101,1表示存在,0表示不存在,就表示存在音频流和视频流。后面的四个字节00 00 00 09表示DataOffset。

FLV Body

Flv Body部分由一系列 previousTagSize字段 和 tag 交织构成。

  • previousTagSize表示前一 tag 大小,第一个Tag的previousTagSize总为0;
  • tag分三种类型,video、audio、scripts。
    再看一下FLV Tag的格式。

FLV Tag

  • Tag有三种类型,Audio Tag(音频Tag),Video Tag(视频Tag),Script Tag(又称Metadata Tag)
  • 每个Tag由Tag Header和Tag Data组成,对于不同类型的Tag,Tag Header的格式都是相同的,Tag Body的格式不一样。
    基于RTMP协议的音视频传输----FLV格式_第3张图片
    先来看一段真实的Flv文件的数据。
    基于RTMP协议的音视频传输----FLV格式_第4张图片
  • 蓝色框内,就是FLV文件的Header,上面已经分析过;
  • 红色框内(12 00 00 f4 00 00 00 00 00 00 00 ),共11字节,表示Script Tag,并且后面Tag Data Size为 00 00 f4,10进制为244长度;
  • 紫色阴影选中的,上面Script Tag后面的就是Script Tag Data,共244字节;
  • 黄色框内,表示previousTagSize。第一个previousTagSize为00 00 00 00,第二个为 00 00 00 ff,表示前面的Script Tag的整体长度为255字节(从Tag Header开始12 00 00 f4…)。
  • 绿色框内的标识下一个Tag。且,下一个Tag的TagType为09,表示视频数据。

Tag Data

接下来就需要看一下Flv Tag Data的格式。
Flv有三种tag:Audio Tag Data、Video Tag Data、Script Tag Data。

Audio Tag Data

Audio Tag Data包括 AudioTagHeader 和 AudioTagBody 两部分。

AudioTagHeader AudioTagBody
AudioTagHeader

包含着音频类型、采样率等的基本信息。如下表:
基于RTMP协议的音视频传输----FLV格式_第5张图片
ACCPacketType表示AAC帧类型。仅当声音格式SoundFormat为 10 时,存在此字段。否则不存在此字段。
当声音格式SoundFormat为 10 时,音频数据就是AACAUDIODATA:
基于RTMP协议的音视频传输----FLV格式_第6张图片
看几个FLV文件中的Audio Data的实际数据:
基于RTMP协议的音视频传输----FLV格式_第7张图片
基于RTMP协议的音视频传输----FLV格式_第8张图片

Video Tag Data

基于RTMP协议的音视频传输----FLV格式_第9张图片
直接看一下上面的Video Tag Data格式。
对于H.264数据来说,CodecID = 7。当CodecID = 7时,视频数据就是AVCVIDEOPACKET格式。
下面看一下AVCVIDEOPACKET:
基于RTMP协议的音视频传输----FLV格式_第10张图片

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

可以看一下AVCDecoderConfigurationRecord的数据格式:
基于RTMP协议的音视频传输----FLV格式_第11张图片
看一下实际的Video AVCDecoderConfigurationRecord数据:
基于RTMP协议的音视频传输----FLV格式_第12张图片

  • 第一个红框内表示Video Tag Header,共11字节;
  • 第一个绿框内表示Video Tag Data前面的参数,从17 可以得出:FrameType = keyframe(1),CodeId = AVC(7)。从AVCVIDEOPACKET得出,此Tag的数据部分,实际为AVCDecoderConfigurationRecord。
  • 第一个蓝色框内表示AVCDecoderConfigurationRecord前面的信息部分,可以得到只有一个sps,且长度为0x17 == 23;
  • 黄框表示sps的数据;
  • 后面的蓝框内表示pps的内容,只有一个pps,且长度为4;
  • 最后一个红框内,表示下一个Video Tag的开始。

crazy!!!!!!!

AVCPacketType = 1 ,one or more nalus

这种情况下,就是真正的 Video数据,看一下格式:
基于RTMP协议的音视频传输----FLV格式_第13张图片
即当AVCPacketType = 1时,就是真正的Video数据。格式为一个4字节的Nalu长度,接着就是Nalu Data。
看一下真正的数据:
基于RTMP协议的音视频传输----FLV格式_第14张图片
如上图中的真实Video数据:

  • 红框中是一个Video Tag 的Header,共11字节;
  • 蓝框中,17表示是FrameType = keyframe(1),CodeId = AVC(7);01表示AVCPacketType为Nalu。
  • 绿框中是一个Nalu的开始,00 00 30 38位Nalu Length,65是真正Nalu数据的开始。

其实,每一个真正的FLV格式的数据,都可以按照上面的Flv Tag格式分析出来。

Script Tag Data

该类型Tag又通常被称为onMetadataTag,会放一些关于FLV视频和音频的元数据信息如:duration、width、height等。通常该类型Tag会跟在FileHeader后面作为第一个Tag出现,而且只有一个。格式为:
在这里插入图片描述
然后每一个AMF包的格式为:
在这里插入图片描述
AMF Type如下:
基于RTMP协议的音视频传输----FLV格式_第15张图片

  • 第一个AMF包的第一个字节,也就是类型,一般为0x02,表示字符串,第2-3个字节表示字符串的长度,一般为0x000A,后面跟的就是字符串,一般为"onMetaData";
  • 第二AMF包第一个字节为0x08,表示数组,第2-5个字节表示数组元素个数,后面跟着就是数组的元素,格式为:元素名长度(UI16) + 元素名(UI8[n]) + 元素的值(double),最后以“009”结尾。
    看一个真正的Script Tag Data:
    基于RTMP协议的音视频传输----FLV格式_第16张图片
  • 红框内表示FLV Header,共9字节;
  • 蓝框内表示Script Tag Data的开始,也就是Script Tag Header;
  • 绿框内表示第一个AMF包,上面有解释;
  • 黄框内表示第二个AMF包,08表示数组,00 00 00 0b表示共有11个元素。
  • 下一个黄框内,表示Script Tag Data结束符 00 00 09;
  • 最后一个红框内,表示下一个Flv Tag的开始。

Oh My God!!!!!!!!!!!!!
FLV格式实在太复杂。再加上RTMP协议,真是够了。

你可能感兴趣的:(流媒体,H264)