FFMPEG FLV
一、FLV的结构
flv不是适合做视频流,是一个视频文件的封装格式。由文件头和文件体组成。flv文件提是一对对的(Previous Tag Size字段 + tag)组成。Previous Tag Size占4字节,记录上一个Tag的大小。设计Previous Tag Size是用来回溯的
每个Tag里面还有一个Tag Header
二、Tag Data的三种类型
2.1 Script Tag Data结构
字节偏移范围 | 字段名称 | 数据类型 | 长度(字节) | 作用说明 | 示例值 / 固定值 |
---|---|---|---|---|---|
0 | 第一个 AMF 包类型 | UI8 | 1 | 标识第一个 AMF 包的类型,固定为 0x02(表示字符串类型)。 | 0x02 |
1-2 | 字符串长度 | UI16(大端序) | 2 | 表示后续字符串的字节长度,"onMetaData" 长度为 10,故值为 0x000A。 | 0x000A |
3-12 | 字符串内容 | UI8[10] | 10 | 具体字符串值,固定为 "onMetaData"(ASCII 码:6F 6E 4D 65 74 61 44 61 74 61)。 | "onMetaData" |
13 | 第二个 AMF 包类型 | UI8 | 1 | 标识第二个 AMF 包的类型,固定为 0x08(表示数组类型)。 | 0x08 |
14-17 | 数组元素个数 | UI32(大端序) | 4 | 表示后续元信息键值对的数量(如 16 个键值对则为 0x00000010)。 | 0x00000010(16 个元素) |
18-n | 元信息键值对(循环结构) | - | 可变 | 每个键值对由 “字符串键”+“值” 组成,重复次数 = 数组元素个数。 | - |
18-19 | 键的字符串长度 | UI16(大端序) | 2 | 首个键(如 "duration")的长度("duration" 为 8 字节,值为 0x0008)。 | 0x0008("duration" 长度) |
20-27 | 键的字符串内容 | UI8[8] | 8 | 首个键的具体值,如 "duration"(时长)。 | "duration" |
28 | 值的类型 | UI8 | 1 | 首个值的类型,0x00 表示 DOUBLE 类型(元信息值多为浮点数)。 | 0x00(DOUBLE 类型) |
29-36 | 值的具体数据 | DOUBLE | 8 | 首个键对应的值,如时长 210.732 秒(二进制表示的浮点数)。 | 210.732 |
37-38 | 下一个键的字符串长度 | UI16(大端序) | 2 | 第二个键(如 "width")的长度("width" 为 5 字节,值为 0x0005)。 | 0x0005("width" 长度) |
39-43 | 下一个键的字符串内容 | UI8[5] | 5 | 第二个键的具体值,如 "width"(视频宽度)。 | "width" |
44 | 下一个值的类型 | UI8 | 1 | 第二个值的类型,同样为 0x00(DOUBLE 类型)。 | 0x00(DOUBLE 类型) |
45-52 | 下一个值的具体数据 | DOUBLE | 8 | 第二个键对应的值,如视频宽度 768.0 像素。 | 768.0 |
... | ...(其余键值对) | ... | ... | 按上述 “长度 - 键 - 类型 - 值” 结构循环,直至数组元素全部解析完毕。 | ...(如 height=320.0、videocodecid=7.0 等) |
每个AMF包表示后面的一段数据中存的是什么
- 第一个 AMF 包:第 1 个字节是
0x02
,表示这是字符串类型的包;第 2 - 3 字节为0x000A
,代表后续字符串长度是 10 字节;后面 10 个字节是具体字符串 “onMetaData” ,用来标识这个 Script Tag Data 是存放元数据的。 - 第二个 AMF 包:第 1 个字节为
0x08
,表明是数组类型的包;第 2 - 5 字节0x00000010
表示数组里有 16 个元素;后续按顺序存放视频宽、高、时长、帧率等元信息的键值对。像视频宽度 “width”,先是 2 字节表示键的长度0x0005
,接着 5 字节是键名 “width” ,然后 1 字节表示值的类型0x00
(DOUBLE 类型 ),最后 8 字节是具体值768.0
。视频时长 “duration” 等其他元信息也是类似的结构进行存储。
2.2 Audio Tag Data结构
1. 第1字节
bit位 | Field | Comment |
---|---|---|
[0,3] | 音频格式 | 0 = 线性 PCM,平台字节序 10 = 高级音频编码(AAC) |
[4,5] | 采样率 | 0 = 5.5kHz 1 = 11kHz 2 = 22.05kHz 3 = 44.1kHz 对于AAC总是3。但实际上AAC是可以⽀持到48khz以上的频率 (这个参数对于AAC意义不⼤)。 |
6 | 采样精度 | 0 = snd8Bit 1 = snd16Bit 此参数仅适⽤于未压缩的格式,压缩后的格式都是将其设为1 |
7 | 音频声道 | 0 = sndMono 单声道 1 = sndStereo ⽴体声,双声道 对于AAC总是1 |
2. 第2字节
非 AAC 格式音频:从第二个字节开始为音频流数据。这些音频流数据会根据不同的音频压缩格式,有着不同的编码方式和数据结构。
AAC音频第二个字节定义为AACPacketType,
其取值仅为0
或1
,直接决定后续字节的数据类型,以此实现 AAC 音频数据的区分:
AACPacketType 值 | 后续字节数据类型 | 区分说明 |
---|---|---|
0 | AudioSpecificConfig | 后续字节为 AAC 的配置信息,包含编码类型、采样率、声道等核心参数,仅在第一个 AAC 音频 Tag 中出现。 |
1 | AAC Raw Frame Data | 后续字节为实际的 AAC 音频帧数据,是用于解码播放的原始音频流,后续所有 AAC 音频 Tag 均为此类型。 |
3. 后续字节
(1) 当AACPacketType=0
:后续字节为配置信息(AudioSpecificConfig)
若第二个字节为0
,则从第二个字节开始(即Tag Data[1]
及之后)的字节均为AudioSpecificConfig
结构数据,该结构遵循ISO-14496-3 Audio
标准,包含以下关键位字段(按位解析):
- audioObjectType(5 位):标识 AAC 编码类型(如 1 代表 AAC LC);
- samplingFrequencyIndex(4 位):采样率索引(如 3 对应 48kHz、4 对应 44.1kHz);
- channelConfiguration(4 位):声道配置(如 1 代表单声道、2 代表立体声);
- 若
samplingFrequencyIndex=0xF
,需额外读取后续 24 位字节获取实际采样率。
该配置信息仅出现一次,用于告知播放器解码所需的核心参数。
(2) 当AACPacketType=1
:后续字节为音频帧数据
若第二个字节为1
,则从第三个字节(Tag Data[2]
)开始的后续字节为真正的AAC Raw Frame Data
(AAC 原始帧数据)。第二个字节仅作为类型标识,不包含音频流内容,播放器可直接解析第三个字节及之后的字节以获取用于播放的音频数据。
2.3 Video Tag Data结构
在 FLV 格式中,当视频编码 ID(CodecID)为7
时,表示视频采用AVC(Advanced Video Coding,即 H.264) 格式,此时视频数据部分(从第二个字节开始)遵循AVC VIDEO PACKET
结构。这一结构专门用于封装 H.264 视频帧数据,包含帧类型标识、解码所需的关键参数及实际视频帧内容,具体含义如下:
第1个字节
AVC 格式视频从第二个字节开始的结构可简化为:
字节位置(从视频数据区起始算) | 字段名称 | 长度(字节) | 核心作用 |
---|---|---|---|
1(第二个字节) | AVC Packet Type | 1 | 区分配置信息 / 帧数据 / 结束标识 |
2-4(第三至第五个字节) | Composition Time | 3 | 音视频同步的时间偏移量 |
≥5(第六个字节及之后) | AVC Frame Data | 可变 | 实际 H.264 参数集或帧数据 |