1. RTSP 协议基础:从一次握手说起
RTSP 这个协议,说白了就是流媒体世界的「遥控器」。你想想看,我们平时看视频,要点播放、暂停、快进、后退——RTSP 做的就是这件事,只不过它控制的是网络上的实时流媒体。
我记得刚入行那会儿,有个同事把 RTSP 和 HTTP 搞混了,结果调试了整整两天才发现问题。嗯,这里要注意:RTSP 虽然长得像 HTTP,但它俩本质完全不同。
1.1 RTSP 协议概述
RTSP(Real Time Streaming Protocol)由 IETF 在 RFC 2326 中定义。它是一个应用层协议,负责建立和控制媒体会话。说白了,它不负责传输媒体数据本身,只负责「指挥」——告诉服务器什么时候发、怎么发、发什么。
核心要点:RTSP 是一个有状态协议。什么意思?服务器会记住你当前处于哪个阶段——是刚建立连接,还是正在播放,还是已经暂停。这一点和 HTTP 的无状态特性完全不同。
RTSP 支持三种传输模式:
- 单播(Unicast):一对一传输,最常见
- 组播(Multicast):一对多传输,节省带宽
- 广播(Broadcast):基本不用,效率太低
我在项目中遇到过最坑的事:客户要求用组播做大规模直播,结果网络设备不支持 IGMP Snooping,整个网络直接瘫痪。所以啊,选传输模式前一定要先确认网络环境。
1.2 RTSP 与 RTP/RTCP 的关系
很多人刚接触流媒体时,会把 RTSP、RTP、RTCP 这三个协议搞混。我画了一张图,帮你理清它们的关系:
这张图你看懂了吗?RTSP 在最上层,负责发号施令;RTP 在中间层,负责搬运数据;RTCP 在旁边,负责打小报告——告诉你网络状况好不好。
个人经验:我建议你在做推流时,把 RTSP 和 RTP 的端口分开配置。RTSP 默认用 554 端口,RTP 用偶数端口,RTCP 用下一个奇数端口。比如 RTP 用 5000,RTCP 就用 5001。这样排查问题时会清晰很多。
1.3 RTSP 消息格式
RTSP 的消息格式和 HTTP 很像,但有几个关键区别。来看一个典型的请求和响应:
// 客户端请求
DESCRIBE rtsp://example.com/live/stream RTSP/1.0
CSeq: 1
Accept: application/sdp
User-Agent: MyStreamClient/1.0
// 服务器响应
RTSP/1.0 200 OK
CSeq: 1
Content-Type: application/sdp
Content-Length: 123
v=0
o=- 1234567890 1234567890 IN IP4 192.168.1.100
s=Live Stream
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
RTSP 消息由三部分组成:
- 起始行:请求方法 + URI + 协议版本,或者协议版本 + 状态码 + 原因短语
- 消息头:键值对,CSeq 是必填项,用于匹配请求和响应
- 消息体:可选,通常是 SDP 描述
| 方法 | 作用 | 我在项目中踩过的坑 |
|---|---|---|
| DESCRIBE | 获取媒体描述(SDP) | 有些服务器不返回 SDP,需要硬编码参数 |
| SETUP | 建立传输通道 | 端口绑定失败最常见,记得检查防火墙 |
| PLAY | 开始播放 | Range 头不传的话,默认从开头播 |
| PAUSE | 暂停播放 | 某些摄像头不支持暂停,会直接断开 |
| TEARDOWN | 终止会话 | 不调这个就断开,服务器可能一直占着资源 |
1.4 RTSP 交互流程
一个完整的 RTSP 交互流程,就像一次精心编排的舞蹈。每一步都有固定的顺序,跳错一步就会摔跟头。
这个流程看起来简单,但实际项目中坑不少。我曾经遇到过一个摄像头,它要求必须先发 OPTIONS 才能 DESCRIBE,否则直接返回 400。另一个设备更奇葩——SETUP 之后必须 500 毫秒内发 PLAY,超时就自动断开。
避坑指南:我曾经因为没处理 CSeq 序号,导致服务器一直返回 400。RTSP 的 CSeq 必须从 1 开始递增,不能跳号,不能重复。如果你并发发送请求,一定要等上一个响应回来再发下一个,否则序号会乱。
1.5 SDP 协议简介
RTSP 的 DESCRIBE 响应里通常会携带 SDP(Session Description Protocol)信息。SDP 描述了媒体流的格式、编码、传输地址等参数。看一个典型的 SDP:
v=0
o=- 1234567890 1234567890 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=framerate:30
a=fmtp:96 packetization-mode=1;profile-level-id=42E01E;sprop-parameter-sets=Z0IACpY1QKABw...
m=audio 0 RTP/AVP 97
a=rtpmap:97 MPEG4-GENERIC/16000/1
a=fmtp:97 streamtype=5;profile-level-id=1;mode=AAC-hbr;config=1408;sizeLength=13;indexLength=3;indexDeltaLength=3
SDP 的关键字段:
- v=:协议版本,目前只有 0
- o=:会话发起者信息
- s=:会话名称
- c=:连接信息,IP 地址
- m=:媒体描述,包括媒体类型、端口、传输协议、格式
- a=:属性行,描述编码参数
个人习惯:我每次调试 RTSP 推流时,第一件事就是抓包看 SDP。如果 SDP 里的编码参数不对,后面所有工作都是白费。特别是 H.264 的 sprop-parameter-sets,很多设备生成的 SPS/PPS 有坑,需要手动修正。