flv视频解析:音视频学习(四、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,所以我们找的位置是正确。

  • flv⽂件中Timestamp和TimestampExtended拼出来的是dts。也就是解码时间。Timestamp和TimestampExtended拼出来dts单位为ms。(如果不存在B帧,当然dts等于pts)
  • 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格式详解+实例剖析

    相关推荐

    相关文章