音视频学习(四、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对组成。(大端字节序)
在这里插入图片描述

4.1.2 header解析

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

详细信息见下图:
在这里插入图片描述

这个是昨天拉流,保存出来的flv视频,通过这个查看这个视屏的二进制格式,我们就能到,上面的描述的对的。
在这里插入图片描述

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
详细见下图:
在这里插入图片描述

实例分析一下:
在这里插入图片描述
我们来看一下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的,直接看这个工具的显示就可以了。
在这里插入图片描述
是不是很清楚,就是不知道为什么有一个0x03的type,难道是昨天的拉流可能还有问题,先不管。

4.1.5 audio data

audio数据又是一个新的tag了,所以简单看一下head:
在这里插入图片描述
对号入座吧,我就不用了,直接来结果公布:
在这里插入图片描述

audio data:

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

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

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

接着2位为采样率

类型
05.5-kHz
111-kHz
222-kHz
344-kHz

AAC 总是3

接着1位为采样的长度

类型
0snd8Bit
1snd16Bit

压缩过的音频都是16bit

接着1位为音频类型

类型
0sndMono
1sndStereo

AAC 总是1

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

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

在这里插入图片描述

4.1.6 video data

还是先取得video head数据,现在就不用细说了,都比较熟悉了。
在这里插入图片描述
解析结果:
在这里插入图片描述

video data数据,跟音频一样

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

后4位为编码ID (CodecID)

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

AVCPacketType 占1个字节

类型
0AVCDecoderConfigurationRecord(AVC sequence header)
1AVC NALU
2AVC 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 ==1Composition time offset
AVCPacketType !=10

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

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

2020-06-26补加
之前没有考虑到需要用到sps/pps的数据,所以就不写,等到后面用到了,现在在来补充一下知识:

sps pps
前面我们提到第一个video 一般存放的是sps和pps。这里我们具体解析下sps和pps内容。先看下存储的格式
0x01+sps[1]+sps[2]+sps[3]+0xFF+0xE1+sps size+sps+01+pps size+pps

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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值