欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FLV封装格式解析

程序员文章站 2022-07-13 11:54:57
...

FLV (Flash Video) 是由 Adobe 公司推出的一种封装格式,主要用于流媒体系统。FLV 封装的媒体文件具有体积轻巧、封装播放简单等特点,很适合网络应用。目前各浏览器普遍使用 Flash Player 作为网页播放器,使得安装有浏览器的计算机终端不需要另外安装播放器,这也是 FLV 格式广为流行的原因之一。

FLV封装格式解析
FLV格式的扩展名为.flv。FLV文件主要由一个头header加上由多个Tag组成的Body构成。如下所述;

 1、FLV Header

所有 FLV 格式文件都以 FLV Header 开头。FLV Header 类型是 FLVHEADER,FLVHEADER 定义如下:

 FLVHEADER 定义如下:

字段 类型 说明
Signature UI8(无符号8位) 'F' (0x46)
Signature UI8 'L' (0x4C)
Signature UI8 'V' (0x56)
Version UI8 FLV 版本。例如,0x01 表示 FLV 版本 1
TypeFlags UI8 b[0] 是否存在视频流
b[2] 是否存在音频流
其他字段保留,值为0
DataOffset UI32 FLV Header 长度(字节)

FLV文件头部总共有9个字节,前3个字节为FLV的署名。
第4个字节是flv版本,一般是0x01。
第5个字节的最低位表示是否存在视频流,存在为1,不存在为0。该字节的其他高位为0。
第6、7、8、9字节表示FLV Header 长度(字节)。

typedef struct {
    UI8 Signature;
    UI8 Signature;
    UI8 Signature;
    UI8 Version;
    UI8 TypeFlags;
    UI32 DataOffset;
}   FLVHEADER;

2、FLV body
FLV文件除去FLV Header 9个字节剩下的就是FLV Body部分,这个部分只包含一系列的Tag和后指针back-pointer组成,后指针表示前一Tag的大小。。FLV Body 类型是 FLVBODY,FLVBODY 定义如下:

字段 类型 说明
PreviousTagSize0 UI32 值总为 0
Tag1 FLVTAG 第一个 Tag
PreviousTagSize1 UI32 前一 Tag 大小,单位字节。FLV 版本 1 中, 此值等于前一 Tag 的 DataSize + 11(该Tag的总长度)
Tag2 FLVTAG 第二个 Tag
... ... ...
PreviousTagSizeN-1 UI32 倒数第二个 Tag 大小,单位字节
TagN FLVTAG 最后一个 Tag
PreviousTagSizeN UI32 最后一个 Tag 的大小,单位字节
typedef struct {
    UI32 PreviousTagSize0;
    FLVTAG Tag1;
    UI32 PreviousTagSize1;
    FLVTAG Tag2;
    ...
    UI32 PreviousTagSizeN-1;
    FLVTAG TagN;
    UI32 PreviousTagSizeN;
}   FLVBODY;

3. FLV Tag

FLV Tag 包含音频、视频或脚本元数据、可选的加密元数据和 payload。FLV Tag 类型是 FLVTAG,FLVTAG 定义如下: 

字段 类型 说明
Reserved UB [2] 用于 FMS 的保留字段, 值为 0
Filter UB [1] 指示 packet 是否需要预处理。
0 = 不需要预处理。
1 = packet 在渲染前需要预处理(例如解密)。
未加密文件中此值为0,加密文件中此值为1。
TagType UB [5] 8 = 音频
9 = 视频
18 = 脚本数据
DataSize UI24 Tag 中除通用头外的长度,即 Header + Data 字段的长度 (等于 Tag 总长度 – 11)
Timestamp UI24 当前 Tag 的解码时间戳 (DTS),单位是毫秒。FLV 文件中第一个 Tag 的 DTS 总为 0
TimestampExtended UI8 和 Timestamp 字段一起构成一个 32 位值, 此字段为高 8 位。单位毫秒
StreamID UI24 总为 0
Header IF TagType == 8
 AudioTagHeader
IF TagType == 9
 VideoTagHeader
音频或视频 TagHeader,注意脚本没有 TagHeader
Data IF TagType == 8
 AUDIODATA
IF TagType == 9
 VIDEODATA
IF TagType == 18
 SCRIPTDATA
音频、视频或脚本 TagBody
typedef struct {
    UB[2] Reserved;
    UB[1] Filter;
    UB[5] TagType;
    UI24 DataSize;
    UI24 Timestamp;
    UI8 TimestampExtended;
    UI24 StreamID;
  IF TagType == 8
    AudioTagHeader Header;
  IF TagType == 9
    VideoTagHeader Header;
  IF TagType == 8
    AUDIODATA Data;
  IF TagType == 9
    VIDEODATA Data;
  IF TagType == 18
    SCRIPTDATA Data;
}   FLVTAG;

 一个 FLVTAG 中,前 11 个字节是通用 TagHeader,后面紧跟跟着音频 Tag、视频 Tag 或脚本 Tag,其中音频 Tag 和视频 Tag 都包含 TagHeader 和 TagBody 两部分,脚本 Tag 只有 TagBody 部分。
上面 Timestamp 和 TimestampExtended 两个字段拼成一个 32 位的时间戳,是当前 Tag 的解码时间戳 (DTS)。对于音频帧来说,PTS 和 DTS 相同。对于视频帧来说,若含 B 帧,则 PTS 和 DTS 不同,H264 视频帧 PTS = DTS + CTS,CTS 就是 CompositionTime 字段,参考 3.2.1 节 CompositionTime 字段的定义。

3.1 Audio Tag