1. RTSP协议基础:从一次推流事故说起
我记得刚入行那会儿,接手过一个监控项目。摄像头推流到服务器,白天好好的,一到晚上就断流。查了三天,最后发现是RTSP的TEARDOWN消息没处理好。嗯,从那以后我就养成了一个习惯——先把协议吃透,再动手写代码。
RTSP(Real Time Streaming Protocol),说白了就是流媒体的“遥控器”。它不负责传视频数据,只管“播放”、“暂停”、“停止”这些控制命令。你想想看,看电视的时候,遥控器本身不传输画面,对吧?RTSP就是那个遥控器。
1.1 RTSP协议概述
RTSP由IETF在RFC 2326中定义,后来更新到RFC 7826。它是一个应用层协议,默认端口是554。它的设计目标很简单:对流媒体会话进行控制。
RTSP支持以下操作:
- DESCRIBE:获取媒体描述信息(比如SDP)
- SETUP:建立传输通道(指定RTP端口)
- PLAY:开始播放
- PAUSE:暂停播放
- TEARDOWN:终止会话
- OPTIONS:查询服务器支持的方法
我在项目中遇到过一个问题:客户端发了PLAY,但服务器没响应。后来发现是客户端没先发SETUP。RTSP的交互顺序是固定的,跳步就会出问题。
核心要点:RTSP是控制协议,不是传输协议。它管理会话的生命周期,但视频数据走的是RTP。
1.2 RTSP与RTP/RTCP的关系
很多新手搞混这三者的关系。我画个图你就明白了。
这张图展示了三者的分工:
- RTSP:负责“握手”和“控制”。比如客户端说“我要看这个流”,服务器说“好的,用UDP传给你”。
- RTP:负责“干活”。视频帧、音频帧都封装在RTP包里,一个包一个包地发出去。
- RTCP:负责“汇报”。它周期性地发送统计信息,比如丢了多少包、延迟多大。
我曾经遇到一个场景:推流到公网服务器,画面卡顿严重。查了RTP的序列号,发现丢包率高达15%。但RTCP报告显示只有3%。后来发现是RTCP的统计周期太长,没反映真实情况。所以我现在做项目,都会把RTCP的发送间隔调短一些。
个人经验:调试推流问题时,先看RTCP报告,再看RTP序列号。RTCP告诉你“有没有问题”,RTP告诉你“问题在哪”。
1.3 RTSP消息格式与交互流程
RTSP的消息格式和HTTP很像。它也是文本协议,用\r\n换行。但有一个关键区别:RTSP是有状态的。HTTP每次请求都是独立的,但RTSP必须按顺序来。
消息格式
一个典型的RTSP请求长这样:
DESCRIBE rtsp://192.168.1.100:554/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=- 123456 789012 IN IP4 192.168.1.100
s=Live Stream
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
注意看CSeq字段。这个序列号必须一一对应。请求的CSeq是1,回复的CSeq也必须是1。我见过有人写代码时忘了递增CSeq,结果服务器一直报错454 Session Not Found。
交互流程
完整的RTSP推流交互流程如下:
| 步骤 | 方向 | 消息 | 说明 |
|---|---|---|---|
| 1 | C → S | OPTIONS | 查询服务器支持哪些方法 |
| 2 | S → C | 200 OK | 返回支持的方法列表 |
| 3 | C → S | DESCRIBE | 请求媒体描述(SDP) |
| 4 | S → C | 200 OK | 返回SDP内容 |
| 5 | C → S | SETUP | 指定传输方式(UDP/TCP)和端口 |
| 6 | S → C | 200 OK | 确认会话ID和传输参数 |
| 7 | C → S | PLAY | 开始推流 |
| 8 | S → C | 200 OK | 开始传输RTP数据 |
| ... | ... | RTP数据 | 持续推流 |
| N | C → S | TEARDOWN | 结束会话 |
这个流程里有一个坑:SETUP必须在PLAY之前。我见过有人把顺序搞反了,结果服务器返回455 Method Not Valid In This State。RTSP的状态机很严格,你跳步它就不认。
避坑指南:我曾经在项目中遇到一个诡异的问题——推流到一半,服务器突然断开。查了日志发现,客户端发了两次SETUP,第二次把第一次的会话覆盖了。记住:一个会话只能有一个SETUP,除非你要切换传输方式。
状态码速查
RTSP的状态码和HTTP类似,但有一些特有的:
| 状态码 | 含义 | 常见场景 |
|---|---|---|
| 200 | OK | 一切正常 |
| 301 | Moved Permanently | 流地址变了,需要重定向 |
| 454 | Session Not Found | 会话ID无效或已过期 |
| 455 | Method Not Valid In This State | 操作顺序不对(比如没SETUP就PLAY) |
| 461 | Unsupported Transport | 服务器不支持客户端指定的传输方式 |
| 500 | Internal Server Error | 服务器内部错误 |
我个人习惯在代码里把455和461单独处理。这两个错误最常见,而且通常都是客户端的问题。比如461,多半是你指定了RTP/AVP/TCP但服务器只支持RTP/AVP。
1.4 小结
RTSP协议其实不复杂。记住三句话:
- RTSP是遥控器,RTP是画面,RTCP是反馈。
- 消息格式和HTTP一样,但有状态,顺序不能乱。
- 交互流程是固定的:OPTIONS → DESCRIBE → SETUP → PLAY → TEARDOWN。