4、实战:Wireshark抓包分析:抓取RTP/RTCP数据包、过滤与定位音视频流、解析RTP头部字段、提取RTCP SR包中的同步信息

说实话,很多搞音视频的同学,理论背得滚瓜烂熟,一遇到线上音画不同步就抓瞎。为什么?因为你没亲眼看过RTP包长什么样。

Wireshark就是我们的“音视频显微镜”。今天我就带你亲手抓一次包,把RTP和RTCP的底裤扒干净。嗯,咱们不搞虚的,直接上实战。

本章目标:学会用Wireshark抓取RTP/RTCP数据包,精准定位音视频流,解析RTP头部字段,并从RTCP SR包中提取NTP和RTP时间戳,计算音视频同步所需的绝对时间。

4.1 抓包前的准备工作

我个人习惯,抓包前先做三件事:

  1. 关闭无关应用——浏览器、下载工具全关,减少噪声包。
  2. 确定抓包接口——如果你在PC上测试,选连接摄像头或麦克风的网卡;如果在服务器上,选监听端口对应的接口。
  3. 设置抓包过滤器——别上来就抓全量,包太多你根本看不过来。

我建议直接用这个过滤器:

udp.port == 5004 || udp.port == 5005

5004是RTP默认端口,5005是RTCP默认端口。当然,你的应用可能用别的端口,改一下就行。

小技巧:如果你不确定端口,可以先抓几秒全量包,然后用 rtp 或 rtcp 作为显示过滤器,Wireshark会自动识别RTP流。

4.2 开始抓包与过滤音视频流

好,现在开始抓包。假设你正在开一个视频会议,或者播放一个RTSP流。点击Wireshark的“开始捕获”按钮,等个10-15秒,然后停止。

包已经抓下来了,但里面混杂着各种UDP包。怎么快速找到音视频流?

用这个显示过滤器:

rtp

Wireshark会自动把所有RTP包高亮出来。你会发现,RTP包通常成对出现——一路音频,一路视频。怎么区分?看SSRC(同步源标识符)。

我个人习惯,先统计一下SSRC:

Statistics -> RTP -> Show All Streams

这里会列出所有RTP流,包括SSRC、源地址、目的地址、包数、丢包率。音频流的包通常更小(比如160字节),视频流的包更大(可能1400字节以上)。

注意:如果抓包环境中有NAT或端口转发,源地址可能不是真实发送端。这时候别慌,看SSRC就够了——SSRC在会话期间是唯一的。

4.3 解析RTP头部字段

选中一个RTP包,展开Wireshark底部的RTP协议树。你会看到这样的结构:

Real-Time Transport Protocol
    [Stream setup by SDP (frame 1)]
    10.. .... = Version: RFC 1889 Version (2)
    ..0. .... = Padding: False
    ...0 .... = Extension: False
    .... 0000 = Contributing source identifiers count: 0
    0... .... = Marker: False
    Payload type: DynamicRTP-Type-96 (96)
    Sequence number: 12345
    Timestamp: 3600
    Synchronization Source identifier: 0x3a1b2c3d (975318589)

我来拆解一下每个字段的实际意义:

字段 长度 作用 实战注意点
Version 2 bits RTP版本号,目前都是2 如果看到版本号不是2,说明包可能被篡改或解析错误
Padding 1 bit 是否有填充字节 某些加密场景会用,普通流很少见
Extension 1 bit 是否有头部扩展 WebRTC常用扩展,比如abs-send-time
CSRC count 4 bits 贡献源数量 混音场景才有,普通点对点通信为0
Marker 1 bit 标记位,通常用于帧边界 视频关键帧的第一个包Marker=1
Payload Type 7 bits 编码类型标识 96-127是动态类型,需要对照SDP
Sequence Number 16 bits 包序号,检测丢包和乱序 每个RTP流独立计数,从随机值开始
Timestamp 32 bits 媒体采样时间戳 音频和视频的时钟频率不同,不能直接比较
SSRC 32 bits 同步源标识符 同一路流的所有包SSRC相同

这里有个坑,我踩过好几次——Timestamp字段不是绝对时间。音频的时钟频率通常是8000Hz或48000Hz,视频是90000Hz。所以音频的Timestamp增长慢,视频增长快。你直接拿音频的Timestamp和视频的Timestamp比大小?没意义。

那怎么比?得靠RTCP SR包。

4.4 提取RTCP SR包中的同步信息

RTCP SR(Sender Report)包,是RTP流的“时间锚点”。它里面包含了两个关键时间戳:

  • NTP Timestamp:绝对时间,从1900年1月1日开始的秒数,64位。
  • RTP Timestamp:对应同一时刻的RTP时间戳,32位。

有了这两个值,你就能把RTP时间戳映射到真实世界的时间。说白了,就是给RTP流“对表”。

在Wireshark里,找到RTCP SR包的方法:

rtcp && rtcp.packet_type == 200

展开后,你会看到:

RTCP Sender Report
    Packet type: Sender Report (200)
    Length: 12 (52 bytes)
    SSRC: 0x3a1b2c3d
    NTP timestamp: Feb 15, 2025 14:23:45.123456 UTC
    RTP timestamp: 1080000
    Sender's packet count: 1500
    Sender's octet count: 2400000

注意看,NTP Timestamp显示的是人类可读的时间,而RTP Timestamp是1080000。这意味着:当绝对时间是2025年2月15日14:23:45.123456时,视频RTP时间戳是1080000。

音频流也有自己的RTCP SR包。找到音频的SSRC,再找对应的SR包:

rtcp && rtcp.packet_type == 200 && rtcp.ssrc == 0x音频SSRC

假设音频SR包显示:

  • NTP: Feb 15, 2025 14:23:45.123456 UTC
  • RTP Timestamp: 96000

好了,现在你有了两个流的“时间锚点”。怎么判断音画是否同步?

很简单:

  1. 从视频流中选一个RTP包,记下它的RTP Timestamp(比如1089000)。
  2. 计算这个包相对于SR包的RTP时间差:1089000 - 1080000 = 9000。
  3. 视频时钟频率是90000Hz,所以时间差 = 9000 / 90000 = 0.1秒。
  4. 从音频流中选一个RTP包,记下它的RTP Timestamp(比如96800)。
  5. 计算音频时间差:96800 - 96000 = 800。音频时钟频率是8000Hz,时间差 = 800 / 8000 = 0.1秒。

两个流的时间差都是0.1秒,说明它们相对于SR包是同步的。如果视频是0.1秒,音频是0.15秒,那就差了50毫秒——这就是音画不同步的根源。

核心公式:

绝对时间 = SR包的NTP时间 + (当前RTP时间戳 - SR包的RTP时间戳) / 时钟频率

音频时钟频率:8000Hz(PCMU/PCMA)、48000Hz(Opus/AAC)

视频时钟频率:90000Hz(H.264/H.265/VP8/VP9)

4.5 用SVG图梳理核心逻辑

上面讲的内容有点多,我画张图帮你理清思路:

RTP/RTCP抓包分析流程与同步信息提取 RTP/RTCP抓包分析流程与同步信息提取 1. 抓取UDP包 2. 过滤RTP流 3. 定位音视频流 4. 解析RTP头 音频流 (SSRC-A) 视频流 (SSRC-V) 音频RTCP SR包 NTP: T0, RTP: RTP_A0 视频RTCP SR包 NTP: T0, RTP: RTP_V0 音频RTP包 (RTP_A1) 视频RTP包 (RTP_V1) 计算绝对时间 T = T0 + (RTP_X - RTP_X0) / 时钟频率 音画同步判断 音频时钟:8000/48000Hz 视频时钟:90000Hz

4.6 避坑指南

实战中,有几个坑我反复踩过,今天一并告诉你:

坑1:NTP时间戳的精度问题

RTCP SR包中的NTP时间戳是64位,但Wireshark显示时只精确到微秒。如果你需要纳秒级精度,得自己解析原始字节。不过对于音画同步来说,微秒级已经够了。

坑2:SR包发送频率

RTCP SR包不是每个RTP包都发,通常几秒才发一个。如果你抓包时间短,可能抓不到SR包。我建议至少抓30秒,确保每个流都有至少一个SR包。

坑3:多路流共用一个SSRC?

我曾经遇到一个奇葩设备,音频和视频用了同一个SSRC。这种情况Wireshark会混淆。解决办法:看Payload Type,音频通常是0、8、96等,视频是96-127。如果还分不清,看包大小——音频包小,视频包大。

4.7 小结

今天这一章,我们亲手抓了RTP包,过滤出了音视频流,解析了RTP头部字段,还从RTCP SR包里提取了同步信息。说白了,音画同步的核心就一句话:把RTP时间戳映射到NTP绝对时间,然后比较两个流的时间差。