音视频学习(四、FLV格式解析)

由于上一节使用到了rtmp推流,然后一直推一直出错,用rtmp推流的数据格式是FLV,所以这一节分析一下FLV的格式,补充补充知识。

4.1 FLV格式解析

4.1.1 FLV总体认识

FLV 是FLASH VIDEO的简称,FLV流媒体格式是随着Flash MX的推出发展而来的视频格式。由于它形成的文件极小、加载速度极快,使得网络观看视频文件成为可能,它的出现有效地解决了视频文件导入Flash后,使导出的SWF文件体积庞大,不能在网络上很好的使用等问题。

FLV包括文件头(File Header)和文件体(File Body)两部分,其中文件体由一系列的Tag及Tag Size对组成。(大端字节序)
音视频学习(四、FLV格式解析)_第1张图片

4.1.2 header解析

heard部分由一下几个部分组成:
Signature(3 Byte)+Version(1 Byte)+Flags(1 Bypte)+DataOffset(4 Byte)

详细信息见下图:
音视频学习(四、FLV格式解析)_第2张图片

这个是昨天拉流,保存出来的flv视频,通过这个查看这个视屏的二进制格式,我们就能到,上面的描述的对的。
音视频学习(四、FLV格式解析)_第3张图片

4.1.3 body解析

FLV body由⼀对对的(Previous Tag Size字段 + tag)组成。

  • Previous Tag Size字段 排列在Tag之前,占⽤4个字节。
    Previous Tag Size记录了前⾯⼀个Tag的⼤⼩,⽤于逆向读取处理。
    FLV header后的第⼀个Pervious Tag Size的值为0。

  • Tag⼀般可以分为3种类型:脚本(帧)数据类型、⾳频数据类型、视频数据。

tag组成:tag type+tag data size+Timestamp+TimestampExtended+stream id+ tag data
详细见下图:
音视频学习(四、FLV格式解析)_第4张图片

实例分析一下:
音视频学习(四、FLV格式解析)_第5张图片
我们来看一下tag1,首先我框起来的是Pervious Tag Size0,因为是第一个,所以填为0;
接下来就到TAG:
type:0x12 是script 数据
data size: 0x00 01 a0 = 0x1a0长度的数据
Timestamp:0x000000
TimestampExtended:0x00
stream id:0x00 00 00

0x00000018地址开始就是tag1 data数据的开始,然后data size=0x01a0,所以计算出下一个tag1结束的地址:0x000001B8,这个地址就很好找,刚好是最后框的地方,这里4个字节正好是Pervious Tag Size1=0x01ab,我们之前得到的data size=0x01a0,tag head刚好=0x0b,所以tag1加起来的大小刚好=0x01ab,所以我们找的位置是正确。

  1. flv⽂件中Timestamp和TimestampExtended拼出来的是dts。也就是解码时间。Timestamp和TimestampExtended拼出来dts单位为ms。(如果不存在B帧,当然dts等于pts)
  2. CompositionTime 表示PTS相对于DTS的偏移值, 在每个视频tag的第14~16字节。显示时间(pts) = 解码时间(tag的第5~8字节) + CompositionTime。CompositionTime的单位也是ms。

4.1.4 script data

script data脚本数据就是描述视频或者音频的信息数据,如宽度、高度、时间等等,一个文件中通常只有一个script数据。该类型的tag又被称为MeteData Tag。

第⼀个AMF包: 第1个字节表示AMF包类型,⼀般总是0x02,表示字符串。第2-3个字节为UI16类型值,标识字符串的⻓度,⼀般总是0x000A(“onMetaData”⻓度)。后⾯字节为具体的字符串,⼀般总为“onMetaData”(6F,6E,4D,65,74,61,44,61,74,61)。

第⼆个AMF包: 第1个字节表示AMF包类型,⼀般总是0x08,表示数组。第2-5个字节为UI32类型值,表示数组元素的个数。后⾯即为各数组元素的封装,数组元素为元素名称和值组成的对。

具体对二进制我这里就不解析了,看着上面的文字都能解析,我使用了一个工具,可以解析flv的,直接看这个工具的显示就可以了。
音视频学习(四、FLV格式解析)_第6张图片
是不是很清楚,就是不知道为什么有一个0x03的type,难道是昨天的拉流可能还有问题,先不管。

4.1.5 audio data

audio数据又是一个新的tag了,所以简单看一下head:
音视频学习(四、FLV格式解析)_第7张图片
对号入座吧,我就不用了,直接来结果公布:
音视频学习(四、FLV格式解析)_第8张图片

audio data:

  • 第⼀个字节包含了⾳频数据的参数信息

下面是第一个字节具体分析:
前4位为音频格式

类型
0 Linear PCM, platform endian
1 ADPCM
2 MP3
3 Linear PCM, little endian
4 Nellymoser 16-kHz mono
5 Nellymoser 8-kHz mono
6 Nellymoser
7 G.711 A-law logarithmic PCM
8 G.711 mu-law logarithmic PCM
9 reserved
10 AAC
11 Speex
14 MP3 8-Khz
15 Device-specific sound

接着2位为采样率

类型
0 5.5-kHz
1 11-kHz
2 22-kHz
3 44-kHz

AAC 总是3

接着1位为采样的长度

类型
0 snd8Bit
1 snd16Bit

压缩过的音频都是16bit

接着1位为音频类型

类型
0 sndMono
1 sndStereo

AAC 总是1

  • 第⼆个字节开始为⾳频流数据

    需要判断该数据是真正的⾳频数据,还是⾳频config信息
    如果音频格式=10(AAC类型)第二个数据就是音频config数据。

音视频学习(四、FLV格式解析)_第9张图片

4.1.6 video data

还是先取得video head数据,现在就不用细说了,都比较熟悉了。
音视频学习(四、FLV格式解析)_第10张图片
解析结果:
音视频学习(四、FLV格式解析)_第11张图片

video data数据,跟音频一样

  • 第⼀个字节包含视频数据的参数信息
    前4位为帧类型Frame Type
类型
1 keyframe (for AVC, a seekable frame) 关键帧
2 inter frame (for AVC, a non-seekable frame)
3 disposable inter frame (H.263 only)
4 generated keyframe (reserved for server use only)
5 video info/command frame

后4位为编码ID (CodecID)

类型
1 JPEG (currently unused)
2 Sorenson H.263
3 Screen video
4 On2 VP6
5 On2 VP6 with alpha channel
6 Screen video version 2
7 AVC
  • 第⼆个字节开始为视频流数据
    但是如果上面的编码ID为AVC的话(h264),VideoTagHeader会多出4个字节的信息,AVCPacketType 和CompositionTime

AVCPacketType 占1个字节

类型
0 AVCDecoderConfigurationRecord(AVC sequence header)
1 AVC NALU
2 AVC end of sequence (lower level NALU sequence ender is not required or supported)

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

CompositionTime 占3个字节

条件
AVCPacketType ==1 Composition time offset
AVCPacketType !=1 0

注意:CompositionTime 单位毫秒。CompositionTime 单位为ms : 显示时间 = 解码时间(tag的第58字节,位置索引[4][7]) +
CompositionTime。

这次就不用对二进制数据了吧,感兴趣自己去分析一下二进制数据。

主要参考博客:flv格式详解+实例剖析

你可能感兴趣的:(音视频学习)