FLV封装格式

简介

FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式,由于其封装后的⾳视频⽂件体积⼩、封装简单等特点,⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤FLV格式封装的⽂件后缀为.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⽂件的详细内容结构如下图:

 

 FLV header

  FLV头占9个字节,⽤来标识⽂件为FLV类型,以及后续存储的⾳视频流。⼀个FLV⽂件,每种类型的tag都属于⼀个流,也就是⼀个flv⽂件最多只有⼀个⾳频流,⼀个视频流,不存在多个独⽴的⾳视频流在⼀个⽂件的情况。

下面以实际的一个文件头为例,来看看FLV Header:

 

结构如下:

Field size pos value comment
签名 u8 0 0x46 'F'
签名 u8 1 0x4c 'L'
签名 u8 2 0x56 'V'
版本 u8 3 0x01 FLV版本:0x01表示版本1
保留字段 5 (bit) 4 00000(0x05: 0000 0101) 默认0 
音频流标识 1 (bit) 4 1(0x05: 0000 0101) 是否存在音频流:1有音频流
保留字段 1 (bit) 4 0(0x05: 0000 0101) 默认0 
视频流标识 1 (bit) 4 1(0x05: 0000 0101) 是否存在视频流:1有视频流
文件头大小 u32 5 0x09

FLV版本1时填写9,表明的是FLV头的⼤⼩,为后期的
FLV版本扩展使⽤。包括这四个字节。数据的起始位置
就是从⽂件开头偏移这么多的⼤⼩。

 FLV Body

就是FLV File Body。FLV File Body是由⼀连串的back-pointers + tags构成。Back-pointer表示Previous Tag Size(前⼀个tag的字节数据⻓度),占4个字节。可以看到上图中第一个Previous Tag Size:00 00 00 00 表示0。

 

 

 FLV Tag

每⼀个Tag也是由两部分组成:tag header和tag data。Tag Header⾥存放的是当前tag的类型、数据区(tag data)的⻓度等信息。

Tag header

tag header⼀般占11个字节的内存空间。我们以第一个和第二个Tag分析一下,FLV tag结构如下:

 

       

Field Type pos Comment
Tag 类型 Type u8 0x0d

0x08:audio 0x09:video 0x12:Script data(脚本数据)

:表明第一个Tag是脚本数据

数据区大小 u24 0x0e

当前tag的数据区域的大小,不包含tag header。

:第二个Previous Tag Size: 0x174 + 0x17+1=0x18c

可以看到 0x017f = 0x174 (Tag)+ 11(Header)

时间戳 u24 0x11 当前帧时戳,单位是毫秒。相对值,第⼀个tag的时戳总是为0
时间戳扩展字段 u8 0x14

如果时戳⼤于0xFFFFFF,将会使⽤这个字节。这个字节是时戳的⾼8位,

上⾯的三个字节是低24位。

StreamID u24 0x15 总是0
数据区域 u[8*n] 0x16 数据域数据

注意:
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)

Script Tag Data

该类型Tag⼜被称为MetaData Tag,存放⼀些关于FLV视频和⾳频的元信息,⽐如:duration、width、height等。通常该类型Tag会作为FLV⽂件的第⼀个tag,并且只有⼀个,跟在File Header后。该类型Tag DaTa的结构如下所示(source.200kbps.768x320.flv⽂件为例):

 

 

 

 

 

Audio Tag Data

⾳频Tag Data区域开始的:

  • 第⼀个字节包含了⾳频数据的参数信息,
  • 第⼆个字节开始为⾳频流数据。

注意:(这两个字节属于tag的data部分,不是header部分

 

 

Field Type Value comment
音频格式 uB4 10 (0xaf)

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

 采样率  uB2  3 (0xaf)  

0 = 5.5kHz 1 = 11kHz
2 = 22.05kHz 3 = 44.1kHz
对于AAC总是3。但实际上AAC是可以⽀持到48khz以上的频率
(这个参数对于AAC意义不⼤)。

 采样精度  uB1  1 (0xaf)  

0 = snd8Bit
1 = snd16Bit
此参数仅适⽤于未压缩的格式,压缩后的格式都是将其设为1

 音频声道  uB1   1 (0xaf)  

0 = sndMono 单声道
1 = sndStereo ⽴体声,双声道
对于AAC总是1

第⼆个字节开始为⾳频数据(需要判断该数据是真正的⾳频数据,还是⾳频config信息)。

 

Filed Type Comment
音频数据 u[8*n]

if SoundFormat == 10 (AAC类型)
AACAUDIODATA
else
Sound data—varies by format

 

 

 

 

 

 

 

Video Tag Data

视频Tag Data开始的:

  • 第⼀个字节包含视频数据的参数信息,
  • 第⼆个字节开始为视频流数据。

 第⼀个字节包含视频信息,格式如下:

Field Type Value Comment
帧类型 uB4 1 (0x17)

1: keyframe (for AVC, a seekable frame)——h264的IDR,关
键帧
2: inter frame (for AVC, a non- seekable frame)——h264的
普通帧
3: disposable inter frame (H.263 only)
4: generated keyframe (reserved for server use only)
5: video info/command frame

编码ID uB4 7 (0x17)

使⽤哪种编码类型:
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

第⼆个字节开始为视频数据

Field Type Comment
视频数据 u[8*n]

If CodecID == 2
H263VIDEOPACKET
If CodecID == 3
SCREENVIDEOPACKET
If CodecID == 4
VP6FLVVIDEOPACKET
If CodecID == 5
VP6FLVALPHAVIDEOPACKET
If CodecID == 6
SCREENV2VIDEOPACKET
if CodecID == 7 (AVC格式)
AVCVIDEOPACKET

 

 

 

 

posted @ 2020-08-27 22:55  Vzf  阅读(514)  评论(0编辑  收藏  举报