11、RTP/RTCP协议栈:RTP包头解析、RTCP控制报文类型、SRTP安全传输

各位同学,今天我们来聊聊WebRTC中最核心的传输协议——RTP/RTCP。说实话,很多做WebRTC开发的朋友,一开始都被这堆协议搞晕过。我当年第一次看RFC 3550的时候,也是硬着头皮啃下来的。但等你真正理解了,就会发现这些设计其实非常巧妙。

RTP包头:12字节的玄机

RTP(Real-time Transport Protocol)是WebRTC传输音视频数据的"卡车"。它的包头只有12字节,但每个字段都有讲究。来,我们直接看结构:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

我来拆解一下这几个关键字段:

  • V(Version):版本号,固定为2。目前主流就是RTPv2。
  • P(Padding):填充位。有时候为了对齐,会在包尾加填充字节。我在做音频编解码对接时遇到过,某些硬件编码器会强制填充,这时候你得知道怎么处理。
  • X(Extension):扩展位。WebRTC里经常用到,比如OneByte扩展头,用来传一些自定义信息。
  • CC(CSRC Count):贡献源数量。混音场景下会用,比如多人会议。
  • M(Marker):标记位。视频里通常表示一帧的结束,音频里表示会话的开始。
  • PT(Payload Type):负载类型。告诉接收方这个包是H264、VP8还是Opus。嗯,这里要注意,WebRTC里PT值可以动态协商,不是固定的。
  • Sequence Number:序列号。用来检测丢包和排序。我见过有人把这个和RTP时间戳搞混,其实序列号是递增的,时间戳是采样时钟。
  • Timestamp:时间戳。音频用48kHz时钟,视频用90kHz时钟。为什么视频用90kHz?因为这是MPEG标准里定的,方便计算帧率。
  • SSRC:同步源标识。每个RTP流有一个唯一的SSRC,用来区分不同的媒体流。

核心要点:RTP包头虽然只有12字节,但每个字段都承载着关键信息。序列号和时间戳是RTP的"双引擎",一个负责顺序,一个负责时序。

RTCP控制报文:不只是报告

RTCP(RTP Control Protocol)是RTP的"管家"。它不传媒体数据,只传控制信息。RTCP有五种基本报文类型,我按使用频率排个序:

类型 名称 作用
200 SR(Sender Report) 发送方报告,包含发送统计和NTP时间戳
201 RR(Receiver Report) 接收方报告,包含丢包率、抖动等
202 SDES(Source Description) 源描述,包含CNAME等信息
203 BYE 退出通知
204 APP 应用自定义

我个人觉得,SR和RR是最重要的。为什么?因为WebRTC的拥塞控制全靠它们。你看这个SR报文结构:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|    RC   |   PT=200     |             length            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         SSRC of sender                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              NTP timestamp, most significant word             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             NTP timestamp, least significant word             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         RTP timestamp                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     sender's packet count                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      sender's octet count                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           report block(s)                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

这里有个细节:NTP时间戳和RTP时间戳同时存在。NTP是绝对时间,RTP是媒体时钟。通过这两个时间戳的映射,接收方可以计算出网络延迟。我曾经在调试音画同步时,就是靠这个映射关系定位到问题的。

避坑指南:RTCP的发送间隔有严格限制。RFC 3550规定,RTCP带宽不能超过会话总带宽的5%。如果你在项目中遇到RTCP报文过多导致网络拥塞,记得检查一下带宽分配。

SRTP:给RTP加把锁

RTP本身是明文传输的。你想想看,如果视频会议里被人抓包,那画面太美不敢看。所以WebRTC强制使用SRTP(Secure RTP)进行加密。

SRTP不是重新发明轮子,它是在RTP基础上加了加密和认证。核心机制就两个:

  • 加密:使用AES算法加密RTP负载。默认是AES-128,密钥通过DTLS-SRTP协商。
  • 认证:使用HMAC-SHA1对RTP包进行完整性校验。防止中间人篡改。

SRTP的包格式和RTP几乎一样,只是在尾部多了两个字段:

| RTP Header | RTP Payload (encrypted) | MKI (optional) | Authentication Tag |

MKI是Master Key Identifier,用来标识使用哪组密钥。Authentication Tag是认证标签,接收方用这个来验证包是否被篡改。

我记得有一次,客户反馈视频通话偶尔出现花屏。排查了半天,发现是SRTP认证失败导致丢包。原因是密钥协商时,DTLS握手超时了。后来我们调整了超时时间,问题就解决了。

注意事项:SRTP的认证标签长度可以配置。WebRTC默认是80位(10字节),但有些场景为了节省带宽,可以缩短到32位。不过我不建议这么做,安全性会打折扣。

协议栈全景图

说了这么多,我们来画一张图,把RTP/RTCP/SRTP的关系理清楚:

RTP/RTCP/SRTP 协议栈架构 应用层(WebRTC PeerConnection) SRTP 安全层(加密 + 认证) RTP/RTCP 传输层 UDP 传输层 RTP:媒体数据包,12字节包头 RTCP:控制报文,SR/RR/SDES/BYE/APP SRTP:AES加密 + HMAC认证 密钥协商:DTLS-SRTP

从这张图可以看得很清楚:应用层生成媒体数据,交给SRTP加密,然后封装成RTP包,最后通过UDP发送。RTCP是并行通道,负责反馈网络质量。

实际开发中,你不需要手动处理这些协议细节。WebRTC的Native API已经封装好了。但理解底层原理,能帮你更好地排查问题。比如:

  • 如果视频卡顿,先看RTCP RR报文里的丢包率
  • 如果音画不同步,检查RTP时间戳和NTP时间戳的映射
  • 如果连接失败,确认DTLS-SRTP密钥协商是否完成

好了,这一章的内容就到这里。RTP/RTCP是WebRTC的"血管",搞懂了它们,你就掌握了WebRTC传输的核心。

一句话总结:RTP传数据,RTCP传控制,SRTP保安全。三者配合,构成了WebRTC的传输基石。


公众号:蓝海资料掘金营,微信deep3321