RTSP 协议基础:从一次真实的推流事故说起

我记得刚入行那会儿,接手过一个远程监控项目。摄像头在千里之外,我这边用 FFmpeg 拉流,画面死活出不来。折腾了两天,最后发现是 RTSP 的 DESCRIBE 请求被防火墙拦了。嗯,从那以后我就养成了一个习惯——搞流媒体,先把协议啃透。

RTSP 是流媒体世界的「遥控器」。它不负责传视频数据,只管「播放、暂停、快进、停止」这些控制指令。说白了,它就是个指挥家,真正演奏的是 RTP 和 RTCP。

RTSP 与 HTTP 的区别

很多新手会把 RTSP 和 HTTP 搞混。毕竟它们都用文本格式,都像在「发请求-收响应」。但本质上,HTTP 是「拿来」,RTSP 是「控制」。

对比维度 RTSP HTTP
核心目的 控制媒体流(播放/暂停/停止) 传输文档/资源
状态性 有状态(维护会话状态机) 无状态(每个请求独立)
默认端口 554 80 / 443
数据传输 不直接传数据,由 RTP 承载 直接在响应体传数据
方向性 双向控制(客户端↔服务器) 请求-响应模式
典型方法 SETUP, PLAY, PAUSE, TEARDOWN GET, POST, PUT, DELETE

关键点:RTSP 的 URL 以 rtsp:// 开头,而 HTTP 是 http://。但 RTSP 也可以承载在 HTTP 之上(RTSP over HTTP),用于穿透防火墙。我在项目中就遇到过这种场景——摄像头在内网,只能走 HTTP 80 端口出去,这时候就得用 RTSP 隧道。

RTSP 消息格式

RTSP 消息分两种:请求和响应。格式和 HTTP 非常像,都是文本行 + 头部 + 空行 + 消息体。

一个典型的 RTSP 请求长这样:

DESCRIBE rtsp://192.168.1.100:554/live/stream RTSP/1.0
CSeq: 1
Accept: application/sdp
User-Agent: FFmpeg/4.4

响应呢?

RTSP/1.0 200 OK
CSeq: 1
Content-Type: application/sdp
Content-Length: 456

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,结果服务器一直返回旧响应。
  • Content-Type:通常是 application/sdp,描述媒体参数。
  • 空行:不能少,少了服务器解析会出错。

RTSP 核心方法

RTSP 定义了多个方法,但实际推流拉流中,这六个方法是必用的。我按它们在一次完整会话中的调用顺序列出来:

方法 作用 典型场景
OPTIONS 查询服务器支持哪些方法 客户端刚连接时,先问一下「你支持啥?」
DESCRIBE 获取媒体描述(SDP) 拿到视频编码、分辨率、码率等信息
SETUP 建立传输通道(UDP/TCP) 指定 RTP 端口、传输模式
PLAY 开始播放 告诉服务器「可以发数据了」
PAUSE 暂停播放 临时停止,但不关闭会话
TEARDOWN 终止会话 关闭连接,释放资源

个人经验:OPTIONS 不是必须的。很多客户端(包括 FFmpeg)会直接发 DESCRIBE,如果服务器不支持,再回退。但我建议你在调试阶段先发 OPTIONS,能快速确认服务器是否活着。

RTSP 状态机

RTSP 是有状态的。服务器会维护每个会话的状态,客户端必须按顺序调用方法。状态机其实不复杂,就四个状态:

  • INIT:初始状态,刚建立 TCP 连接。
  • READY:SETUP 完成后,准备好接收媒体流。
  • PLAYING:正在播放中。
  • RECORDING:正在录制(推流场景)。

状态转换规则:

  1. INIT → 发 DESCRIBE → 仍在 INIT
  2. INIT → 发 SETUP → 进入 READY
  3. READY → 发 PLAY → 进入 PLAYING
  4. PLAYING → 发 PAUSE → 回到 READY
  5. 任何状态 → 发 TEARDOWN → 回到 INIT(或断开)

避坑指南:我曾经在代码里犯过一个低级错误——在 PLAYING 状态下又发了一次 SETUP。结果服务器直接返回 455 Method Not Valid In This State。记住:SETUP 只能在 READY 或 INIT 状态下调用。

下面这张图把整个流程串起来了,你一看就明白:

RTSP 状态机与核心方法流程 RTSP 状态机与核心方法流程 INIT(初始) READY(就绪) PLAYING(播放) RECORDING(录制) SETUP PLAY RECORD PAUSE PAUSE TEARDOWN TEARDOWN 说明: 1. 箭头上的文字表示调用的 RTSP 方法。 2. 红色虚线箭头表示 TEARDOWN 可以从任何状态回到 INIT。

你看,整个流程其实很清晰。客户端先连上来,发 DESCRIBE 问清楚媒体信息,然后 SETUP 建立通道,最后 PLAY 开始拉流。推流的话,把 PLAY 换成 RECORD 就行。

核心要点:RTSP 本身不传视频数据。它只负责「控制」。真正的音视频数据走的是 RTP(实时传输协议),而 RTP 的传输参数(端口、编码格式)就是在 SETUP 和 DESCRIBE 阶段协商好的。这个设计理念很重要——控制面和数据面分离。