flv文件格式解析

date: 2014.12.10; modification:2014.12.10

目录:

1 概述

flv文件总体分为两部分: header和body.

其中body部分又是由一个个数据段组成, 这数据段称为Tag. 其中tag又分为Tag header和Tag data. 详见后文.

它们的关系如下图

flv文件结构概览图

flv文件结构概览图

2 File header文件头

File header部分记录了flv的类型, 版本等信息, 是flv的开头, 一般都差不多, 占9bytes. 具体格式如下:

字段 长度 说明
文件类型 3 bytes 字符: "FLV"
版本 1 byte 一般为0x01
流信息 1 byte 倒数第一位是1表示有视频, 倒数第三位是1表示有音频, 倒数第二, 四位必须为0
header长度 4 bytes 整个header的长度, 一般为9; 大于9表示下面还有扩展信息

3 Body

body部分由一个个Tag组成, 每个Tag的下面有一块4bytes的空间, 用来记录这个tag的长度, 这个后置用于逆向读取处理.

4 Tag

每个Tag由也是由两部分组成的: Tag Header和Tag Data. Tag Header里存放的是当前Tag的类型, 数据区(Tag Data)长度等信息, 具体如下:

4.1 Tag Header

名称 长度 介绍
Tag类型 1 bytes 见下文
数据区长度 3 bytes 在数据区的长度
时间戳 3 bytes 整数, 单位是毫秒. 对于脚本型的tag总是0
时间戳扩展 1 bytes 将时间戳扩展为4bytes, 代表高8位. 很少用到
StreamsID 3 bytes 总是0

Tag类型取值:

4.2 Tag Data

Tag header之后紧接着就是数据区(Tag data), 其长度由Tag header中的"数据区长度"字段表明. 数据区根据Tag类型的不同可分为三种, 音频数据, 视频数据和脚本数据.

4.3 脚本Tag Data

脚本Tag一般至少有一个, 用于存放flv的MetaData信息, 比如duration, audiodatarate, creator, width等. 一般这是FLV文件的第一个Tag, 因为知道了这些基本信息之后, 才好继续进行后面的解码的工作.

首先介绍下脚本的数据类型. 所有数据都是以 数据类型+(数据长度)+数据 的格式出现的, 也就是amf封装, 数据类型占1byte, 数据长度看数据类型是否存在, 后面才是数据.

其中数据类型的种类有:

如果类型为String, 后面的2bytes为字符串的长度(Long String是4bytes), 再后面才是字符串数据; 如果是Number类型, 后面的8bytes为Double类型的数据; Boolean类型, 后面1byte为Bool类型.

知道了这些后再来看看flv中的脚本, 一般开头是0x02, 表示String类型, 后面的2bytes为字符串长度, 一般是0x000a("onMetaData"的长度), 再后面就是字符串"onMetaData". 好像flv格式的文件都有onMetaData标记, 在运行ActionScript的时候会用到它. 后面跟的是0x08, 表示ECMA Array类型, 这个和Map比较相似, 一个键跟着一个值. 键都是String类型的, 所以开头的0x02被省略了, 直接跟着的是字符串的长度, 然后是字符串, 再是值的类型, 也就是上面介绍的那些了.

4.4 音频Tag data

第一个byte是音频的信息, 格式如下.

4.5 视频Tag data

和音频数据一样, 第一个byte是视频信息, 格式如下:

接下来就是具体Video的流数据的封装了.

4.5.1 AVC视频封装

对于AVC格式的video, 除了第一个字节的'帧类型'和'编码ID'之外, 从第二个字节开始分别为:

AVCDecoderConfigurationRecord详细说明:

一般第一个视频Tag会封装视频编码的总体描述信息(AVC sequence header), 就是AVCDecoderConfigurationRecord结构(ISO/IEC 14496-15 AVC file format中规定). 其结构如下:

aligned(8) class AVCDecoderConfigurationRecord {
    unsigned int(8) configurationVersion = 1;
    unsigned int(8) AVCProfileIndication;
    unsigned int(8) profile_compatibility;
    unsigned int(8) AVCLevelIndication;

    bit(6) reserved = ‘111111’b;
    unsigned int(2) lengthSizeMinusOne;

    bit(3) reserved = ‘111’b;
    unsigned int(5) numOfSequenceParameterSets;

    for (i=0; i< numOfSequenceParameterSets; i++) {
        unsigned int(16) sequenceParameterSetLength ;
        bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;
    }

    unsigned int(8) numOfPictureParameterSets;

    for (i=0; i< numOfPictureParameterSets; i++) {
        unsigned int(16) pictureParameterSetLength;
        bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;
    }
} 

例如:

下面高亮的部分就是 FLV 文件中的 AVCDecoderConfigurationRecord 部分.

00000130h: 00 00 00 17 00 00 00 00 01 4D 40 15 FF E1 00 0A ; .........M@.?.

00000140h: 67 4D 40 15 96 53 01 00 4A 20 01 00 05 68 E9 23 ; gM@.朣..J ...h?

00000150h: 88 00 00 00 00 2A 08 00 00 52 00 00 00 00 00 00 ; ?...*...R......

根据 AVCDecoderConfigurationRecord 结构的定义:

5 参考文献

http://wuyuans.com/2012/08/flv-format/

http://blog.csdn.net/k1988/article/details/5654631