FLV 文件 的总体结构 由 File Header 文件头、File Body 文件体 组成 ;

  • File Header 文件头 固定为 9 字节 ,
  • File Body 文件体 由 若干 " Previous Tag Size 前一个标签大小 + Tag 数据块 " 组成 ;
    • Tag 数据块 由 Tag Header 数据块头、Tag Body 数据块体 组成 ;
    • Tag Header 数据块头 由 固定 11 字节组成 ;
    • Tag Body 需要根据 三种不同的 Tag 类型 各自有不同的结构 , 如 :
      • 音频数据 Audio Data、
      • 视频数据 Video Data、
      • 元数据 Script Data ;

上一篇博客 【FFmpeg】FLV 格式分析 ① ( File Header 文件头 | File Body 文件体 | Tag Header 数据块头结构 | Script Data 元数据结构 ) 中 , 讲解了 Script Data 元数据Tag Body 结构 , 本篇博客介绍 音频数据 Audio Data、视频数据 Video Data 的 Tag Body 结构 ;





一、Tag Body 数据块体结构 - Audio Data 音频数据




1、Audio Data 音频数据简介


在 FLV 文件中 , Audio Data 音频数据 类型的 Tag 数据块 用于存储音频相关信息 ;

音频 Tag 数据块 的 Tag Body 结构 中主要包括

  • 音频格式、
  • 采样率、
  • 采样精度、
  • 声道类型

等参数信息 , 和 实际的音频数据 ;


Audio Data 音频数据 的 Tag 数据块 分为两部分 :

  • 第 1 字节 包含 音频 的参数信息 , 包括音频格式、采样率、采样精度、声道类型 ;
  • 第 2 字节 开始 就是 实际的 音频数据 ;

2、Audio Data 音频数据结构分析


下面是 FLV 文件中 Audio Data 音频数据 类型的 Tag Body 数据块体 的每个字节含义 :

字节偏移 位偏移 字段名称 位宽 描述
0 0-3 Sound Format 4 音频编码格式 :
0 = Linear PCM, 平台字节序
1 = ADPCM
2 = MP3
3 = Linear PCM, 小端字节序(LE)
4 = Nellymoser 16 kHz 单声道
5 = Nellymoser 8 kHz 单声道
6 = Nellymoser
7 = G.711 A-law PCM
8 = G.711 μ-law PCM
9 = 保留
10 = AAC
11 = Speex
14 = MP3 8 kHz
15 = 设备专用
0 4-5 Sound Rate 2 采样率 :
0 = 5.5 kHz,
1 = 11 kHz,
2 = 22 kHz,
3 = 44 kHz。
0 6 Sound Size 1 采样精度 :
0 = 8 位,
1 = 16 位。
0 7 Sound Type 1 声道类型 :
0 = 单声道(Mono)
11 = 立体声(Stereo)
1 0-7 AAC Packet Type 8 ( 仅当 Sound Format 为 10 时 , 才有该字段 )
AAC 特有类型 :
0 = AAC 序列头(AudioSpecificConfig,用于初始化解码器)
1 = AAC 原始数据块(Raw AAC frame data)
2+ Audio Data 可变 实际音频数据 , 根据 Sound Format 的不同 , 这部分数据格式也会不同 ;
对于 AAC,音频数据部分是 Raw AAC 数据帧。
对于 MP3,这部分是 MP3 帧数据

注意 : 上面的 AAC Packet Type 字段 , 仅在 Sound Format 为 10 时 才有 , 该字段也可以算作 AAC 格式的数据部分 ;


4、Audio Data 音频数据 中 AAC Packet Type 字段说明


AAC 序列头 , 设置的 AAC Packet Type 字段值 为 0 ;

  • 通常在 音频流的开头格式切换 时出现 ;
  • 解码器必须 先读取并处理该 序列头 , 提取必要的初始化信息 , 然后才能接收 ACC 原始数据块 , 如 : 采样率、声道配置 参数 ;

AAC 原始数据块 , 设置的 AAC Packet Type 字段值 为 1 ;

  • 在 AAC 序列头 之后 , 所有后续的音频 Tag Body 均为原始数据块 ;
  • AAC 原始数据块 是 编码后的音频内容 , 可以直接传递给 AAC 解码器处理 ;

特别注意 : 一个音频 Tag 的 Tag Body 中 只能包含

  • AAC 序列头 AudioSpecificConfig
  • AAC 原始数据块 Raw AAC Data

两者中的一种数据 , 两种数据不可能出现在同一个 音频 Tag 的 Tag Body 中 ;


AAC Packet Type 是一个 1 字节的字段 , 用于区分 AAC 序列头 和 AAC 原始数据块 这两种数据的类型 ;

解码器需要根据 AAC Packet Type 的值来 判断当前 Tag Body 的数据内容是 序列头 还是 音频帧 ;


5、AAC 序列头 AudioSpecificConfig 结构分析


AAC 序列头 AudioSpecificConfig 是 用于初始化 AAC 解码器的必需数据 , AAC Packet Type 值 固定 设置为 0 , 表示这是 AAC 序列头 ;

字段名称 大小 描述
AAC Packet Type 1 字节 固定值为 0,表示这是 AAC 序列头。
AudioSpecificConfig 可变(通常 2 字节) 提供采样率、声道等 AAC 解码器初始化参数,具体结构见下文。

AudioSpecificConfig 的结构 如下 :

字段名称 位宽 描述
AudioObjectType 5 位 AAC 编码的类型(2 表示 AAC-LC)。
SamplingFrequencyIndex 4 位 采样率索引,对应具体采样率值(如 3 表示 48 kHz,4 表示 44.1 kHz)。
ChannelConfiguration 4 位 声道配置(如 2 表示立体声)。
其他数据(可选) 可变 如果需要更多初始化参数,会在这里存储(通常在扩展配置中)。

AAC 序列头的数据案例 :

00 12 10
  • 00 : 设置 AAC Packet Type = 0 , 表示这是 AAC 序列头 ;
  • 12 10 : 设置 2 字节的 AudioSpecificConfig 值 , 转为二进制 0001 0010 0001 0000
    • 0 ~ 4 位 , 是 AudioObjectType = 00010 , 该值表示 AAC 编码类型 , 2 = AAC-LC ;
    • 5 ~ 8 位 , 是 SamplingFrequencyIndex = 0100 , 该值表示采样率 , 4 = 44.1 kHz ;
    • 9 ~ 12 位 , 是 ChannelConfiguration = 0010 , 该值表示声道配置 , 2 = 立体声 ;

6、AAC 原始数据块 Raw AAC Data 结构分析


AAC 原始数据块 Raw AAC Data , 需要设置 AAC Packet Type = 1 字段值 ;

字段名称 大小 描述
AAC Packet Type 1 字节 固定值为 1,表示这是 AAC 原始数据块。
Raw AAC Data 可变(通常多个字节) 编码后的 AAC 音频帧内容,直接传递给解码器处理。

AAC 原始数据块 示例 : 数据为

01 FF EE 76
  • 01 : AAC Packet Type = 1 , 表示这是原始数据块 ;
  • FF EE 76 : Raw AAC Data , 实际的 AAC 音频帧数据 ;

7、AAC 序列头 AudioSpecificConfig 与 AAC 原始数据块 Raw AAC Data 对比分析


特性 AAC 序列头 AAC 原始数据块
AAC Packet Type 0 1
内容 AudioSpecificConfig 初始化参数 编码后的 AAC 音频帧数据
大小 通常固定 2 字节或更多 大小可变,取决于音频帧的编码情况
功能 提供解码器初始化信息 实际的音频数据,用于播放
是否包含 ADTS 不包含 不包含

8、AAC Packet Type 字段与 ADIF 格式 和 ADTS 格式 的关系


在之前的博客 【FFmpeg】AAC 音频格式分析 ( ADIF 格式 | ADTS 格式 | AAC ADTS 音频格式分析 | ADTS 帧头格式解析 | 代码实战 - 生成 ADTS 帧头数据 ) 中 , 介绍了 AAC 的两种格式 , ADIF 格式 和 ADTS 格式 ;

  • ADIF 格式 ( Audio Data Interchange Format ⾳频数据交换格式 ) 是一种用于 存储 AAC 数据的文件格式 , 适合静态音频文件 ;
    在这里插入图片描述

  • ADTS 格式 ( Audio Data Transport Stream 音频数据传输流格式 ) 适用于 数据传输 , ADTS 格式 将音频数据划分为多个小帧 , 每个帧包含一段音频数据和帧头 , 每个帧头包含解码该帧的必要信息 , 如 : 帧长度、声道数和采样率等 ;
    在这里插入图片描述


FLV 中的 AAC 音频数据 , 即不是 ADIF , 也不是 ADTS 格式 , 而是基于 AAC 原始数据(Raw AAC Data)的存储方式 ;

AAC 序列头 AudioSpecificConfig 不是 ADTS 帧头 , FLV 中的 AAC 音频数据 不是完整的 ADTS 格式 , AAC 数据的帧头信息并不是以完整 ADTS 帧头的形式存储 , 而是采用 AudioSpecificConfig 数据提供必要的解码参数 ;


9、Audio Data 音频数据 解析流程


在这里插入图片描述

解析 FLV 文件中的 Audio Data 音频数据 需要 逐步处理 FLV 文件的结构 , 从 File Header 头部到音频 Tag 的具体数据 , 解析流程 :

[解析 FLV Header][检查音频标志][逐个解析 Tag][判断 Tag 类型][解析 Audio Tag Header][根据 SoundFormat 解析音频数据][输出结果]

以下是详细的解析流程 :

  • 解析 FLV 文件的头部 File Header : 检查 Signature 字段 是否为 FLV 确认文件类型 , 然后 检查 Type Flags , 确定是否包含音频数据 ;
偏移量 字段名称 大小 描述
0x00 Signature 3 字节 文件标识,固定为 “FLV”
0x03 Version 1 字节 版本号,常见为 0x01
0x04 Type Flags 1 字节 指示是否包含音频(第 3 位)和视频(第 1 位)
0x05 Data Offset 4 字节 Header 的总长度,通常为 9 字节
  • 解析 FLV Body 文件体 : File Body 文件体 由 若干 " Previous Tag Size 前一个标签大小 + Tag 数据块 " 组成 , 每个 Tag 包括 如下内容 :
偏移量 字段名称 大小 描述
0x00 Previous Tag Size 4 字节 前一个 Tag 的大小(包括其 Header 和 Body)。
0x04 Tag Header 11 字节 描述 Tag 的类型、数据大小、时间戳等信息。
0x0F Tag Body 可变 实际的音频、视频或脚本数据。
  • 解析 Tag Header 数据块头 : 获取 Tag 类型 , 如果 Tag 类型为 8 ( Audio Tag ) , 确认是 Audio Tag 音频数据块 ;
字节偏移 字段名称 长度(字节) 描述
0 Tag Type 1 0x08 音频数据 Audio Tag
0x09 视频数据 Video Tag
0x12 元 数 据 Script Tag
1 Data Size 3 数据块体 Tag Body 的大小 , 单位 字节 Byte
4 Timestamp 3 时间戳 的 低 24 位 , 单位 毫秒 ms , 表示该数据块的 解码时间 dts ;
7 Timestamp Extended 1 时间戳的扩展位 , 时间戳 的 高 8 位 , 单位 ms , 该时间是 dts 解码时间 ;
8 Stream ID 3 保留字段 , 固定为 0 ;
  • 解析 Tag Body 数据块体 :第 1 字节(Sound Format、Sound Rate、Sound Size 和 Sound Type);
偏移量 字段名称 位宽 描述
0 SoundFormat 4 音频编码格式(如 10 表示 AAC)。
4 SoundRate 2 采样率(如 3 表示 44 kHz)。
6 SoundSize 1 采样精度(如 1 表示 16 位)。
7 SoundType 1 声道类型(如 1 表示立体声)。
  • 如果 Sound Format 是 AAC , 则进一步解析 AAC Packet Type ;

10、Audio Data 音频数据 类型的 Tag 数据块 的 Tag Body 数据块体部分示例展示


Audio Data 音频数据 类型的 Tag 数据块 的 Tag Body 数据块体部分示例 : 该示例没有 FLV 文件头 , 没有 Tag Header 数据块头 , 只有 Tag Body 数据块体数据 ;

AF 00 12 10

上述十六进制数据解析如下 :

  • AF : 设置的 Tag Header 数据 , 转为二进制为 1010 1111 ;

    • 1010 : 0 ~ 3 位 , Sound Format = 10 , 表示该 Audio Data 音频数据 类型的 Tag 数据块 的 Tag Body 数据块体 的格式是 AAC 格式 ;
    • 11 : 4 ~ 5 位 , Sound Rate = 3 , 表示采样率 是 44100 Hz , 该值是默认值 , 没有实际意义 ;
    • 1 : 第 6 位 , Sound Size = 1 , 采样位数是 16 位 , 默认值 , 没有实际意义 ;
    • 1 : 第 7 位 , Sound Type = 1 , 表示 立体声 , 也是默认值 , 没有实际意义 ;
    • AAC 音频 的 解码参数 不在 Tag Header 数据中 , 而是在 Tag Body 中的 AAC 序列头 的 AudioSpecificConfig 参数中 ;
  • - - - 下面是设置的 Tag Body 数据 - - - ;

  • 00 : 设置 AAC Packet Type = 0 , 表示这是 AAC 序列头 ;

  • 12 10 : 设置 2 字节的 AudioSpecificConfig 值 , 转为二进制 0001 0010 0001 0000

    • 0 ~ 4 位 , 是 AudioObjectType = 00010 , 该值表示 AAC 编码类型 , 2 = AAC-LC ;
    • 5 ~ 8 位 , 是 SamplingFrequencyIndex = 0100 , 该值表示采样率 , 4 = 44.1 kHz ;
    • 9 ~ 12 位 , 是 ChannelConfiguration = 0010 , 该值表示声道配置 , 2 = 立体声 ;
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐