3. RTSP协议详解:RTSP请求方法、SDP描述、与RTP/RTCP的关系

好,咱们进入第三个章节。RTSP这个协议,说白了就是视频流的「遥控器」。你想想看,我们要看一个实时视频,总不能直接把数据流硬塞过来吧?总得有个「播放」、「暂停」、「快进」的操作。RTSP干的就是这个活。

我记得刚入行那会儿,有个项目需要对接海康的NVR。我拿着文档看了半天,发现RTSP的交互流程其实比想象中简单。但坑也不少。今天我就把这块掰开了讲清楚。

3.1 RTSP请求方法

RTSP的请求方法,我习惯把它类比成VCR的按键。常用的就那么几个:

  • OPTIONS:客户端问服务器「你支持哪些操作?」。服务器会回复一个列表。
  • DESCRIBE:客户端问「这个流长什么样?」。服务器返回SDP描述。
  • SETUP:客户端说「我要开始接收数据了,咱们把传输通道建好」。这一步会协商端口和传输协议。
  • PLAY:客户端说「开始播放」。服务器开始推送RTP流。
  • PAUSE:暂停播放。注意,有些设备不支持暂停。
  • TEARDOWN:断开连接,释放资源。

核心要点:RTSP本身不传输视频数据。它只负责控制。真正的视频数据走的是RTP。

我在项目中遇到过一个问题:有些低端摄像头对OPTIONS请求的回复不完整。你发OPTIONS过去,它可能只回一个空列表。这时候我建议你直接发DESCRIBE试试。嗯,这算是个小技巧。

3.2 SDP描述

SDP,全称是Session Description Protocol。它不负责传输,只负责描述。说白了就是一份「视频流说明书」。

一个典型的SDP长这样:

v=0
o=- 123456 789012 IN IP4 192.168.1.100
s=Live Stream
c=IN IP4 0.0.0.0
t=0 0
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; profile-level-id=42E01E; sprop-parameter-sets=Z0IACpZUBQFs, aMljiA==

我来拆解一下关键字段:

字段 含义 我的经验
v=0 版本号,固定为0 别改它,改了设备不认
o= 会话发起者和会话ID 有些设备会校验这个ID,乱填可能被拒
m=video 媒体类型和端口 端口填0表示由服务器分配
a=rtpmap 编码格式和时钟频率 H264的时钟频率固定是90000
a=fmtp 编码参数 这里藏着SPS/PPS,解码的关键

避坑指南:我曾经在解析SPS/PPS时踩过坑。有些设备会把sprop-parameter-sets字段的base64编码搞错。如果你发现画面花屏,先检查这个字段。

你想想看,如果没有SDP,客户端根本不知道视频是H264还是H265,分辨率是多少,帧率是多少。所以DESCRIBE这一步是必须的。

3.3 与RTP/RTCP的关系

这三者的关系,我打个比方:

  • RTSP:是导演,负责喊「开始」、「停」。
  • RTP:是快递员,负责把视频数据一包一包送过去。
  • RTCP:是监工,负责反馈「这包丢了」、「那包延迟了」。

在实际项目中,RTP和RTCP通常是成对出现的。RTP走偶数端口,RTCP走下一个奇数端口。比如RTP用5000,RTCP就用5001。

我记得有一次调试一个NVR项目,画面总是卡顿。我抓包一看,发现RTCP的反馈包被防火墙拦截了。服务器收不到丢包信息,就一直重传,导致网络拥堵。嗯,这个问题排查了整整一个下午。

重要提醒:RTCP的反馈机制在某些场景下可以关闭。但我不建议这么做。没有RTCP,你就等于闭着眼睛开车。丢包了也不知道,画面花了也不知道。

RTP的头部结构也很关键。我简单说一下:

 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            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

这里面的sequence number和timestamp,是保证视频流畅播放的关键。sequence number用来排序,timestamp用来控制播放节奏。

为什么会丢包?说白了就是网络不稳定。但有了RTP的序列号,接收端可以判断哪些包丢了,然后通过RTCP告诉发送端。发送端可以选择重传,也可以选择忽略。

我个人习惯在项目中把RTCP的间隔设短一点。默认是5秒一次报告,我一般改成1秒。这样能更快发现网络问题。但代价是多了些带宽开销。你根据实际情况权衡。

最后总结一下:RTSP负责控制,SDP负责描述,RTP负责传输,RTCP负责反馈。四者配合,才能实现一个稳定的实时视频流系统。

下一章我会讲RTSP的交互流程和状态机。到时候咱们用Wireshark抓包看看,这些协议到底是怎么跑的。