第 1 章 FLV 文件格式
FLV 文件中的每种标签类型均构成单一数据流。一个 FLV 文件中最多包含一个音频流和一个视频流,二者同步。FLV 文件无法定义多个同类型独立流。
与 SWF 文件不同,FLV 文件以大端字节序 存储多字节整数。例如,数字 300(0x12C)在 SWF 格式中为 UI16 类型,字节序列是 0x2C 0x01;在 FLV 格式中为 UI16 类型,字节序列是 0x01 0x2C。此外,FLV 使用 SWF 未采用的 3 字节整数类型:UI24(无符号 24 位整数)。
FLV 文件头
所有 FLV 文件均以以下文件头开头:
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| 签名 | UI8 | 固定为 'F'(0x46) |
| 签名 | UI8 | 固定为 'L'(0x4C) |
| 签名 | UI8 | 固定为 'V'(0x56) |
| 版本 | UI8 | 文件版本(如 FLV 1 版为 0x01) |
| 保留标志 | UB[5] | 必须为 0 |
| 音频标志 | UB[1] | 存在音频标签 |
| 保留标志 | UB[1] | 必须为 0 |
| 视频标志 | UB[1] | 存在视频标签 |
| 数据偏移 | UI32 | 从文件起始到主体起始的字节偏移(即文件头大小) |
FLV 1 版的数据偏移通常为 9。该字段用于兼容未来版本的更大文件头。
FLV 文件主体
FLV 文件头之后,剩余部分由回指指针 与标签交替组成,结构如下:
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| 前一标签大小 0 | UI32 | 固定为 0 |
| 标签 1 | FLVTAG | 第一个标签 |
| 前一标签大小 1 | UI32 | 前一标签总大小(含头部);FLV 1 版为 11 + 前一标签数据大小 |
| 标签 2 | FLVTAG | 第二个标签 |
| ... | ... | ... |
| 倒数第二个标签大小 | UI32 | 倒数第二个标签大小 |
| 最后一个标签 | FLVTAG | 最后一个标签 |
| 最后一个标签大小 | UI32 | 最后一个标签大小 |
FLV 标签
FLV 标签格式如下:
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| 标签类型 | UI8 | 8 = 音频;9 = 视频;18 = 脚本数据;其余保留 |
| 数据大小 | UI24 | 数据字段长度 |
| 时间戳 | UI24 | 标签数据生效时间(毫秒),相对第一个标签(固定为 0) |
| 时间戳扩展 | UI8 | 时间戳高 8 位,与低 24 位组成 32 位有符号整数 |
| 流 ID | UI24 | 固定为 0 |
| 数据 | --- | 标签类型 = 8→音频数据;=9→视频数据;=18→脚本数据对象 |
播放时,FLV 标签的时序仅由时间戳决定,忽略负载数据内置的计时机制。
音频标签
音频标签与 SWF 的 DefineSound 标签类似,负载数据基本一致,仅新增 SWF 不允许的 Nellymoser 8kHz 格式。
音频数据
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| 音频格式 | UB[4] | 0 = 平台字节序 PCM;3 = 小端 PCM;4=16kHz 单声道 Nellymoser;5=8kHz 单声道 Nellymoser;6=Nellymoser;10=AAC;11=Speex;15 = 设备专属音频 |
| 采样率 | UB[2] | 0=5.5kHz;1=11kHz;2=22kHz;3=44kHz;AAC 固定为 3 |
| 采样位深 | UB[1] | 0=8 位;1=16 位(仅未压缩格式有效,压缩格式内部解码为 16 位) |
| 声道 | UB[1] | 0 = 单声道;1 = 立体声(Nellymoser 固定 0;AAC 固定 1) |
| 音频数据 | UI8 [长度] | 格式 = 10→AAC 音频数据;否则为对应格式音频数据 |
格式 3(PCM)存储原始 PCM 采样:8 位为无符号字节,16 位为小端有符号数;立体声为左 - 右交替存储。格式 0 与格式 3 一致,但 16 位采样按创建平台字节序存储,不建议使用。Nellymoser 8kHz/16kHz 为特殊情况,采样率无法用采样率字段表示,指定该格式时忽略采样率与声道字段。AAC 格式的采样率、声道字段会被播放器忽略,实际参数从 AAC 码流提取。
AAC 音频数据
Flash Player 9.0.115.0 及以上支持 AAC 格式。
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| AAC 包类型 | UI8 | 0=AAC 序列头;1 = 原始 AAC 帧 |
AudioSpecificConfig 定义见 ISO 14496-3,与 MP4/F4V 的 esds 盒子内容不同,结构更深。
视频标签
视频标签与 SWF 的 VideoFrame 标签类似,负载数据一致。
视频数据
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| 帧类型 | UB[4] | 1 = 关键帧(AVC 可搜索帧);2 = 间帧(AVC 不可搜索);3 = 可丢弃间帧(仅 H.263) |
| 编解码器 ID | UB[4] | 1=JPEG(未使用);2=Sorenson H.263;3 = 屏幕视频;4=On2 VP6;5 = 带透明通道 VP6;6 = 屏幕视频 v2;7=AVC(H.264) |
| 视频数据 | --- | 按编解码器 ID 对应数据包 |
帧类型 = 5 时,负载为 1 字节:0 = 客户端搜索序列开始;1 = 客户端搜索序列结束。
AVC 视频包
承载 AVC 视频数据负载。
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| AVC 包类型 | UI8 | 0=AVC 序列头;1=AVC NALU;2=AVC 序列结束 |
合成时间偏移见 ISO 14496-12 8.15.3,FLV 中偏移单位为毫秒。AVCDecoderConfigurationRecord 见 ISO 14496-15 5.2.4.1,与 MP4/F4V 的 avcC 盒子信息一致。
数据标签
封装单次方法调用,通常在 Flash Player 的 NetStream 对象上执行,由方法名与参数集组成。
脚本数据
表格
| 字段 | 类型 | 说明 |
|---|---|---|
| 对象 | SCRIPTDATAOBJECT[] | 任意数量脚本数据对象 |
| 结束标记 | UI24 | 固定为 9 |
脚本数据对象 / 结束标记
- 脚本数据对象:定义 ActionScript 对象数据,包含对象名与对象数据。
- 结束标记:固定为 9,标识对象列表结束。
脚本数据字符串 / 长字符串
- 字符串:长度(UI16)+ 字符串数据。
- 长字符串:长度(UI32)+ 字符串数据,用于超过 65535 字符的字符串。
脚本数据值
表示 ActionScript 值 / 对象,支持数字、布尔、字符串、对象、数组、日期等类型,不同类型对应不同存储格式。
onMetaData 元数据
FLV 可包含 onMetaData 标记元数据,通过 NetStream.onMetaData 暴露给 ActionScript,常见字段:
- 时长、宽、高、视频码率、帧率、视频编解码器 ID
- 音频采样率、采样位深、立体声、音频编解码器 ID
- 文件大小