1.FLV封装格式简介
FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式,由于其封装后的⾳视频⽂件体积小、封装简单等特点,⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤ FLV格式封装的⽂件后缀为.flv。
2.FLV封装格式分析
FLV封装格式是由**⼀个⽂件头(file header)**和 **⽂件体(file Body)**组成:
FLV body由⼀对对的(Previous Tag Size字段 + tag)组成,Previous Tag Size字段排列在Tag之前,占⽤ 4个字节。**Previous Tag Size记录了前⾯⼀个Tag的大小,⽤于逆向读取处理。**FLV header 后的第⼀个Pervious Tag Size的值为0。
Tag⼀般可以分为3种类型:
- 脚本(帧)数据类型
- ⾳频数据类型
- 视频数据
FLV数据以⼤端序进⾏存储,在解析时需要注意。
⼀个标准FLV⽂件结构如下图:
FLV⽂件的详细内容结构如下图:
3.FLV封装格式详细解析
3.1.FLV解析流程
3.2.FLV header
FLV头的结构如下:
Field | Type | Comment |
---|---|---|
签名 | UI8 | F’(0x46) |
签名 | UI8 | ‘L’(0x4C) |
签名 | UI8 | ‘V’(0x56) |
版本 | UI8 | FLV的版本。0x01表示FLV版本为1 |
保留字段 | UB5 | 前五位都为0 |
⾳频流标识 | UB1 | 是否存在⾳频流 |
保留字段 | UB1 | 为0 |
视频流标识 | UB1 | 是否存在视频流 |
⽂件头⼤⼩ | UI32 | FLV版本1时填写9,表明的是FLV头的⼤小 |
数据type中,UI表示⽆符号整形,后⾯跟的数字表示其⻓度是多少位,比如:UI8,表示⽆符号整形,⻓度⼀个字节UI24是三个字节,UI[8*n]表示多个字节。UB表示位域,UB5表示⼀个字节的5位。可以参考c中的位域结构体。
FLV头占9个字节,⽤来标识⽂件为FLV类型,以及后续存储的⾳视频流,⼀个FLV⽂件,每种类型的tag都属于⼀个流,也就是⼀个flv⽂件最多只有⼀个⾳频流,⼀个视频流,不存在多个 独立的音视频流在⼀个文件的情况。
3.3.FLV Body
FLV Header之后,就是FLV File Body。FLV File Body是由⼀连串的back-pointers + tags构成。 Back-pointer表示Previous Tag Size(前⼀个tag的字节数据⻓度),占4个字节。
3.4.FLV Tag tag header
每⼀个Tag也是由两部分组成:tag header和tag data。Tag Header⾥存放的是当前tag的类型、数据区(tag data)的⻓度等信息。
tag header⼀般占11个字节的内存空间。FLV tag header结构如下:
Field | Type | Comment |
---|---|---|
Tag类型 Type | UI8 | 8:audio 9:video 18:Script data(脚本数据) all Others:reserved 其他所有值未使⽤ |
数据区⼤小 | UI24 | 当前tag的数据域的⼤⼩,不包含tag header。 Length of the data in the Data field |
时间戳Timestamp | UI24 | 当前帧时戳,单位是毫秒。相对值,第⼀个tag的时戳总是为0 |
时戳扩展字段 TimestampExtended | UI8 | 如果时戳⼤于0xFFFFFF,将会使⽤这个字节。这个字节是 时戳的⾼8位,上⾯的三个字节是低24位。 |
StreamID | UI24 | 总是为0 |
数据域 | UI[8*n] | 数据域数据 |
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 。
3.Script data脚本数据就是描述视频或⾳频的信息的数据,如宽度、⾼度、时间等等,⼀个⽂ 件中通常只有⼀个元数据,⾳频tag和视频tag就是⾳视频信息了,采样、声道、频率,编码等 信息。
3.5.FLV Tag data
FLV Tag data,在FLV Tag Header之后,分为MetaData Tag、Audio Tag、Video Tag。
3.5.1.MetaData Tag
MetaData Tag存放⼀些关于FLV视频和⾳频的元信息,⽐如:duration、width、 height等,通常该类型Tag会作为FLV⽂件的第⼀个tag,并且只有⼀个,跟在File Header后。
从上图可以得到:
- 第一个PreviousTagSize值是0
- MetaData Tag 的类型是12
- 记录的信息有duration(5.12秒)、width(768)、height(320)、videodatarate(码率207.260)、framerate(帧率25)
3.5.2.Audio Tag
⾳频Tag Data区域开始的:
- 第⼀个字节包含了⾳频数据的参数信息
- 第⼆个字节开始为⾳频流数据
注意:这两个字节属于tag的data部分,不是header部分。
第⼀个字节为⾳频的信息格式如下:
Field | Type | Comment |
---|---|---|
⾳频格式 SoundFormat | UB4 | 0 = Linear PCM, platform endian 2 = MP3 10 = AAC |
采样率 SoundRate | UB2 | 对于AAC总是3(这个参数对于AAC意义不⼤) |
采样精度 SoundSize | UB1 | 0 = snd8Bit 1 = snd16Bit 此参数仅适⽤于未压缩的格式,压缩后的格式都是将其设为1 |
⾳频声道 SoundType | UB1 | 0 = sndMono 单声道 1 = sndStereo ⽴体声,双声道 (对于AAC总是1) |
第⼆个字节开始为⾳频数据(需要判断该数据是真正的⾳频数据,还是⾳频config信息)
3.5.3.Video Tag
视频Tag Data开始的:
-
第⼀个字节包含视频数据的参数信息
-
第⼆个字节开始为视频流数据
第⼀个字节包含视频信息,格式如下:
第⼆个字节开始为视频数据 :