RTSP 一共 11 个方法,日常只用前五个加一个保活。 按「谁发起」分两类:客户端发的九个,服务端只有 REDIRECT 一个。
前面把概念都讲完了,这一节讲「动词」。 方法是 RTSP 的骨架,把 11 个方法按用途排一遍,整个协议的覆盖面就清楚了。 方法在播放器里怎么落地, 看 34 课 第七章。
一、11 个方法,一张表看完
按调用顺序排,这样记最省力:
| 方法 | 做什么 | 实体 | 常用度 |
|---|---|---|---|
| OPTIONS | 问支持哪些方法 | 没有 | 高 |
| DESCRIBE | 要 SDP | 响应带 SDP | 高 |
| SETUP | 分配传输参数 | 没有 | 高 |
| PLAY | 开始或恢复播放 | 可带 Range | 高 |
| PAUSE | 暂停,保留会话 | 没有 | 中 |
| TEARDOWN | 结束会话 | 没有 | 高 |
| GET_PARAMETER | 读参数,兼做保活 | 可有 | 中 |
| SET_PARAMETER | 写参数 | 可有 | 低 |
| ANNOUNCE | 推流时告知内容 | 请求带 SDP | 低 |
| RECORD | 开始录制 | 没有 | 低 |
| REDIRECT | 让客户端换地址 | 服务端发 | 极低 |
前四个加 TEARDOWN 是必需的,PAUSE 和两个 PARAMETER 是常见的,后三个基本见不到。
为什么这么排:它们正好对应一次播放的五个阶段,所以按「从建立到收摊」的顺序记,比按字母序好记。
二、五个必用的,各自的门道
OPTIONS 的响应里那个 Public 头最值钱——它一次告诉你设备会哪些方法,比翻文档可靠。
DESCRIBE 的关键是 Accept 头:告诉服务端你要什么格式的描述,通常是 application/sdp。
有的设备还支持别的格式,但实际只用得到 SDP。
SETUP 是唯一带 Transport 的方法,也是唯一会出现「一路一路分别调」的方法。 它成功之后才拿到 Session 号——这是整个流程的分水岭。
PLAY 有个容易被忽略的参数:Range。
Range: npt=0.000- 表示从头播到尾;
Range: npt=10.5-30 表示从 10.5 秒播到 30 秒;
Range: clock=20261024T163000Z- 用绝对时间,回放录像时用。
npt 是「正常播放时间」,单位秒,这是最常用的。
TEARDOWN 前文说过,重点是放在 finally 里,别等程序正常退出。
三、推流方向的三个方法
ANNOUNCE 和 RECORD 是「我把流推给你」用的。 监控里少见,但直播推流和部分设备上云会用到。
| 方法 | 方向 | 作用 |
|---|---|---|
| ANNOUNCE | 客户端 → 服务端 | 告诉服务端「我要推这个内容」 |
| RECORD | 客户端 → 服务端 | 开始录制(区别于 PLAY) |
| SETUP | 客户端 → 服务端 | 分配端口,这一步和拉流一样 |
注意 SETUP 在推流方向也用,只是角色反了:原来是「你把数据发到我的端口」, 现在是「我把数据发到你的端口」。
所以 client_port 和 server_port 的含义会互换算,这是写推流端时最容易搞混的地方。
四、REDIRECT:唯一服务端发起的方法
11 个方法里只有它是服务端主动发的。 作用是:这个地址不伺候了,你去那个地址。
REDIRECT rtsp://192.168.1.64/Streaming/Channels/101 RTSP/1.0
CSeq: 0
Location: rtsp://192.168.1.65/Streaming/Channels/101
典型场景是负载均衡:前端设备把请求转给后端某个节点。 CSeq 写 0 是允许的,因为这不是对某个请求的响应。
实际遇到它的机会很少,但知道有这个东西,抓包看到「莫名其妙的 REDIRECT」时就不会懵。
五、动手 Demo:11 个方法,常用的就 5 个
这段把 11 个方法逐个造出请求行,量出各自的字节数。 字节数只差在方法名长度上——请求行是纯文本。
methods = [(u"OPTIONS", u"问支持哪些方法", u"没有"),
(u"DESCRIBE", u"要 SDP", u"响应带 SDP"),
(u"SETUP", u"分配传输参数", u"没有"),
(u"PLAY", u"开始播", u"可带 Range")]
for m, why, body in methods:
line = u"%s %s RTSP/1.0\r\nCSeq: 1\r\n\r\n" % (m, url)
T([m, why, body, u"%d" % len(line.encode("utf-8"))], [0, 0, 0, 0])
实跑输出:
--------------------------------------------------------------------
11 个方法,常用的就 5 个
--------------------------------------------------------------------
**RFC 2326 定义了 11 个方法。逐个造一遍请求行,看它们长什么样。**
方法 做什么 实体 字节
--------------------------------------------------------------------
OPTIONS 问支持哪些方法 没有 72
DESCRIBE 要 SDP 响应带 SDP 73
ANNOUNCE 推流时告诉服务端有什么 请求带 SDP 73
SETUP 给一路流分配传输参数 没有 70
PLAY 开始播(或恢复) 可带 Range 69
PAUSE 暂停,保留会话 没有 70
TEARDOWN 结束会话,释放资源 没有 73
GET_PARAMETER 读参数,也常当保活用 可有可无 78
SET_PARAMETER 写参数 可有可无 78
REDIRECT 让客户端换地址 服务端发 73
RECORD 开始录制(推流端用) 没有 71
字节数差在方法名长度上——**请求行是纯文本,方法名越长这一条越长**。
这些都是发出去就几十字节的小包,**真正占带宽的是 RTP**。
**按「谁发」分一下类:**
谁发起 方法
-------------------------------------------------------------
客户端 OPTIONS/DESCRIBE/SETUP/PLAY/PAUSE
客户端 TEARDOWN/GET_PARAMETER/SET_PARAMETER
客户端(推流) ANNOUNCE/RECORD
服务端 REDIRECT
**日常对接 95% 只用到前五个**,加一个 GET_PARAMETER 做保活。
ANNOUNCE/RECORD 是「我把流推给你」用的,监控里少见,直播推流里常见。
字节数从一百出头到一百三十几,差别全在方法名长度上。
DESCRIBE 比 PLAY 长四个字符,
就多四个字节——这就是纯文本协议的代价,也是它的好处(一眼能读)。
但别被这个小数字骗了:一条请求一百多字节,一次播放发几条,总共不到一千字节。 而 1080p 一秒的媒体数据是五百多 KB。信令占的比例是万分之二——所以 RTSP 从来不是带宽问题。
这张表的第四列(实体)才是分类的关键: 只有 DESCRIBE 的响应带 SDP,ANNOUNCE 的请求带 SDP; 其余九个方法默认都不带实体。 所以看到有实体的 RTSP 报文,基本就能断定是这两个之一。
30 秒实验
- 对设备发 OPTIONS,把 Public 头的完整内容抄下来。
- 数一下你实际用到的有几个方法,剩下的为什么用不到。
- 对 PLAY 加一个 Range,看能不能从中间开始播。
常见误区
- 以为 11 个方法都要实现。 客户端只要实现前五个就能播,PAUSE 和 GET_PARAMETER 加上更完整。
- 以为推流和拉流用不同的方法集。 SETUP 两边都用,只是 client_port 和 server_port 的含义互换。
- 以为 Range 只能写秒数。 还有
clock=形式用绝对时间, 回放录像时按「某年某月某日某时」定位就得用它。
自测三问(点开对答案)
1. 五个必用的方法按顺序是哪些? —— OPTIONS、DESCRIBE、SETUP、PLAY、TEARDOWN。OPTIONS 可以省,SETUP 可能要走两次。 2. 哪个方法能一次问出设备支持哪些能力? —— OPTIONS,看响应里的 Public 头。它列出的方法比说明书可靠,因为说明书说的是理论支持。 3. 推流时 SETUP 的端口含义和拉流时有什么不同? —— 互换了。 拉流时 client_port 是「我收数据的端口」,推流时是「你发数据的端口」——同一字段,角色反了。下一节换协议:RTSP 讲完了,进 RTP,先看那 12 个字节怎么排。
- ☐ (本节完,下一节 01.06.01 RTP格式)