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 流的内部结构!

相关推荐
_Evan_Yao1 小时前
从 IP 路由到 Agent 路由:最长前缀匹配如何帮你分发任务?
java·网络·后端·网络协议·tcp/ip
maosheng11461 小时前
RHCE的第一次笔记
服务器·网络·笔记
魔极客2 小时前
第十二节:龙晰 AnolisOS-23.4-x86_64.qcow2 虚拟机的网络配置方式及 ssh 连接
网络·ssh·php
时空系2 小时前
第8篇:结构模板——自定义数据类型 Rust中文编程
开发语言·网络·rust
北方的流星11 小时前
华三路由器NAT配置
运维·网络·华三
数据法师12 小时前
开源情报收集工具GhostTrack深度测评:IP、手机号、用户名的合规信息查询方案
网络·网络协议·tcp/ip
丑八怪大丑13 小时前
Java网络编程
linux·服务器·网络
想成为优秀工程师的爸爸14 小时前
第三十篇技术笔记:郭大侠学UDS - 人有生老三千疾,望闻问切良方医
网络·笔记·网络协议·tcp/ip·信息与通信
数智工坊15 小时前
【SAM-DETR论文阅读】:基于语义对齐匹配的DETR极速收敛检测框架
网络·论文阅读·人工智能·深度学习·transformer