RTMP视频流的帧格式分析

RTMP(Real-Time Messaging Protocol)是基于 TCP 的协议,其底层传输的数据实际上封装了 FLV(Flash Video)格式的 Tag。在 RTMP 流中,数据被切分成一个个 Chunk(块)进行发送。

为了让你深入理解,我将模拟抓取一个真实场景:一个主播正在推流,内容包含一段 H.264 视频和 AAC 音频。

以下是详细的分析:


1. RTMP Chunk Header(包头)分析

无论音频还是视频,数据包的最外层都是 RTMP Chunk Header。

  • 假设数据 (Hex): 03 00 00 00 00 00 04 05 00 00 00
  • 详细解析 :
    • 03 : Format (2 bit) + Chunk Stream ID (6 bit)
      • Format=0(表示这是一个完整的 Chunk Header,包含时间戳、长度、类型等全部信息)。
      • CSID=3(表示块流 ID 为 3)。
    • 00 00 00 : Timestamp (3 bytes)。时间戳为 0(通常是流的第一个包)。
    • 00 00 04 : Message Length (3 bytes)。消息体长度为 4 字节(这是一个极小的包,通常用于发送握手后的配置信息)。
    • 05 : Message Type ID (1 byte) 。类型为 5,表示 Audio Data(如果是 9 则是 Video Data)。
    • 00 00 00 : Stream ID (4 bytes)。流 ID 为 0。

2. 音频包详细分析

AAC 音频在 RTMP 中有两种主要的包类型:AAC Sequence Header (配置信息)和 AAC Raw Data(声音数据)。

示例场景:发送 AAC 配置信息

这是推流开始后发送的第一个音频包,解码器需要它来知道采样率、声道数等。

  • 假设 Payload 数据 (Hex): AF 00 11 90 56 E5

    • (注意:不包含上面的 Chunk Header,这里是 Tag Body 的内容)
  • 详细格式解析:

    1. AF : Sound Format & Info (1 byte)

      • 高 4 位 1010 (10): Sound Format = AAC。
      • 高 3-2 位 11 (3): Sample Rate = 44 kHz。
      • 高 1 位 1 (1): Sample Size = 16-bit。
      • 高 0 位 1 (1): Sound Type = Stereo (立体声)。
      • 总结: 44100Hz, 16位, 立体声 AAC。
    2. 00 : AAC Packet Type (1 byte)

      • 00 = AAC Sequence Header (AudioSpecificConfig)。
      • 01 = AAC Raw Data (真正的音频帧)。
      • 分析 : 这里 00 说明这是配置包,告诉播放器如何初始化解码器。
    3. 11 90 56 E5 : AudioSpecificConfig Data (4 bytes)

      • 这是 AAC 的 ADTS(Audio Data Transport Stream)头部信息去掉同步字后的紧凑格式。
      • 通常包含 Profile (如 LC)、Sampling Frequency Index、Channel Configuration 等信息。
      • 播放器会将这部分数据提取出来,构建解码器上下文。
示例场景:发送真实的音频帧
  • 假设 Payload 数据 : AF 01 [后面跟随一长串 AAC 压缩数据]
    • AF: 同上,音频格式信息。
    • 01 : AAC Packet Type = 1。表示后面的数据是裸的 AAC ES (Elementary Stream) 数据,不包含 ADTS 头(因为 RTMP/FLV 已经在配置包里定义了格式,这里为了节省带宽不再重复发送头部)。

3. 视频包详细分析

H.264 视频在 RTMP 中也分两种:AVC Sequence Header (SPS/PPS) 和 AVC NALU (I帧/P帧/B帧)。

示例场景:发送 AVC 配置信息 (SPS/PPS)

这是推流的第一个视频包,没有画面,只有元数据。

  • 假设 Payload 数据 (Hex): 17 00 00 00 00 01 67 42 ...

    • (注:为了演示清晰,简化了数据长度)
  • 详细格式解析:

    1. 17 : Frame Type & Codec ID (1 byte)

      • 高 4 位 0001 (1): Frame Type = Keyframe (IDR 帧)。
        • 1: Keyframe (I帧)
        • 2: Inter frame (P帧/B帧)
        • 3: Disposable inter frame
        • ...
      • 低 4 位 0111 (7): Codec ID = AVC。
        • 7 = H.264 (AVC)
        • 12 = H.265 (HEVC)
      • 含义: 这是一个关键帧的配置包。
    2. 00 : AVCPacket Type (1 byte)

      • 00 = AVC Sequence Header
      • 01 = AVC NALU unit。
      • 分析 : 这里 00 表示这是包含 SPS 和 PPS 的配置包。
    3. 00 00 00 : Composition Time (3 bytes)

      • 仅在 Packet Type 为 1 时有意义。这里因为是 Header,通常为 0。
    4. 01 ... : DecoderConfigurationRecord Data

      • 这里存储的是 ISO BMFF 格式的 AVCDecoderConfigurationRecord。
      • 它包含:ConfigurationVersion、AVCProfileIndication、ProfileCompatibility、AVCLevelIndication、LengthSizeMinusOne(通常为 3,表示 NALU 长度用 4 字节表示)。
      • 紧接着是 SPS (Sequence Parameter Set)PPS (Picture Parameter Set) 的数据。
示例场景:发送关键帧数据 (I-Frame)
  • 假设 Payload 数据 : 17 01 00 00 1D 00 00 00 01 67 42 ...

    • (注:实际长度字段取决于配置)
  • 详细格式解析:

    1. 17 : Frame Type = Keyframe (1), Codec ID = AVC (7)。
    2. 01 : AVCPacket Type = AVC NALU (1)。表示这是真正的视频画面数据。
    3. 00 00 1D : Composition Time (3 bytes)
      • 表示解码时间戳与显示时间戳之间的偏移量 (PTS - DTS)。假设值为 29ms(0x001D),意味着这个帧应该比解码时间晚 29ms 显示(B帧常用,但在纯 I/P 帧流中通常为 0)。
    4. 00 00 00 01 : NALU Start Code (4 bytes) (虽然 FLV 通常使用 Length 字段,但在分析底层 H.264 码流时常见 Start Code,但在 RTMP Tag Body 内部,通常是 长度数据 的结构)。
      • 修正 :在 FLV 结构中,这里应该是 NALU Length。如果 LengthSizeMinusOne=3,这里就是 4 字节长度。
      • 假设 Length = 00 00 00 1C (28 字节)。
    5. 67 ... : NALU Data
      • 67 (十进制 103) 代表 NALU 类型为 SPS (非关键 IDR)。但这里如果是 I 帧,通常会包含 SPS/PPS(如果 IDR 周期性插入配置),或者类型 65 (IDR slice)。
      • 实际数据结构示例循环:
        • [4 Bytes: Length] [1 Byte: NALU Header] [N Bytes: Payload]
        • [4 Bytes: Length] [1 Byte: NALU Header] [N Bytes: Payload]

4. 总结对比表

字段位置 音频包 (AAC) 视频包
第一个字节 AF (Sound Format=AAC, 44k, Stereo, 16bit) 17 (Frame Type=Keyframe, Codec=AVC)
第二个字节 00 (Seq Header) 或 01 (Raw Data) 00 (Seq Header) 或 01 (NALU)
后续字节 AAC AudioSpecificConfig 或 Raw ES Data 3字节 CompTime + DecoderRecord 或 NALU Units

核心点记忆:

  1. 配置包 是必须先发送的,包含了解码必需的表头信息。
  2. 音频 AAC00 类型是头,01 类型是去掉 ADTS头的裸流。
  3. 视频 AVC00 类型是 SPS/PPS 头,01 类型是 NALU 单元。
  4. Composition Time :只在视频 01 类型中有意义,用于音画同步中的补正。

希望这个详细的数据包分析能帮你理解 RTMP 流的内部结构!

相关推荐
Piko6147 小时前
H3C IRF2 堆叠实战:打造高可靠核心交换网络
运维·网络·笔记
茯苓gao9 小时前
嵌入式开发笔记:CANopen相关移位运算与通信协议术语详解
网络·嵌入式硬件·学习·信息与通信
万联WANFLOW10 小时前
SD-WAN 控制平面高可用怎么做?SDWAN 控制器挂了,全网会发生什么
运维·网络·分布式·架构
酱学编程10 小时前
【从零到一实现一个 AI Agent 框架 · 第四篇】04. 任务规划:拆解复杂目标 -
服务器·网络·数据库·人工智能
风行南方12 小时前
密码学之分组密码
网络·密码学
艾莉丝努力练剑12 小时前
OpenCode AI 编程:Ubuntu 24.04 环境安装与使用指南
linux·服务器·网络·人工智能·tcp/ip·ubuntu
谷雪_65813 小时前
Linux 网络命名空间:从内核原理到企业级容器网络架构全景实战
linux·网络·架构
liulilittle13 小时前
KCC 拥塞控制算法缺陷修复记录(26/07/05)
网络·tcp/ip·计算机网络·c·信息与通信·tcp·通信
Tian_Hang14 小时前
Eclipse Ditto 的权限策略
java·服务器·前端·网络·ide·ubuntu·eclipse
ai生成式引擎优化技术14 小时前
从知识连接到智能组织:WSaiOS认知网络的理论框架与系统设计摘要
网络·python·plotly·django·pygame