FLV封装格式解析
FLV (Flash Video) 是由 Adobe 公司推出的一种封装格式,主要用于流媒体系统。FLV 封装的媒体文件具有体积轻巧、封装播放简单等特点,很适合网络应用。目前各浏览器普遍使用 Flash Player 作为网页播放器,使得安装有浏览器的计算机终端不需要另外安装播放器,这也是 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
上一篇: AVI媒体封装格式
下一篇: java按照指定格式数据封装
推荐阅读
-
适合flv格式用什么播放器可以播放(能播放rmvb格式的播放器app)
-
手机flv播放器(手机能播放m3u8格式的播放器使用方法)
-
python解析xml模块封装代码
-
手机flv播放器(手机能播放m3u8格式的播放器使用方法)
-
解析json字符串的方式(json格式和字典区别)
-
jsonobject解析json字符串特别慢(json格式转换文本的方法)
-
简介Objective-C解析XML与JSON数据格式的方法
-
实例解析iOS app开发中音频文件播放工具类的封装
-
Android编程使用pull方式解析xml格式文件的方法详解
-
适合flv格式用什么播放器可以播放(能播放rmvb格式的播放器app)