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 / RTP / RTCP 关系图 RTSP 控制命令 DESCRIBE/SETUP/PLAY RTP 媒体数据传输 H.264 / AAC / 音视频 RTCP 质量反馈 丢包率 / 抖动 / 延迟 说明 RTSP 建立会话 → RTP 传输数据 → RTCP 反馈质量 三者协同工作,缺一不可 典型推流流程: 客户端 → DESCRIBE → SETUP → PLAY → RTP推流 → TEARDOWN

这张图展示了三者的分工:

  • 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。