📹 第一章 流媒体与RTSP/RTP/RTCP简介
📄 一句话概括

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 秒实验

  1. 对设备发 OPTIONS,把 Public 头的完整内容抄下来。
  2. 数一下你实际用到的有几个方法,剩下的为什么用不到。
  3. 对 PLAY 加一个 Range,看能不能从中间开始播。

常见误区

  1. 以为 11 个方法都要实现。 客户端只要实现前五个就能播,PAUSE 和 GET_PARAMETER 加上更完整。
  2. 以为推流和拉流用不同的方法集。 SETUP 两边都用,只是 client_port 和 server_port 的含义互换。
  3. 以为 Range 只能写秒数。 还有 clock= 形式用绝对时间, 回放录像时按「某年某月某日某时」定位就得用它。
自测三问(点开对答案) 1. 五个必用的方法按顺序是哪些? —— OPTIONS、DESCRIBE、SETUP、PLAY、TEARDOWN。OPTIONS 可以省,SETUP 可能要走两次。 2. 哪个方法能一次问出设备支持哪些能力? —— OPTIONS,看响应里的 Public 头。它列出的方法比说明书可靠,因为说明书说的是理论支持。 3. 推流时 SETUP 的端口含义和拉流时有什么不同? —— 互换了。 拉流时 client_port 是「我收数据的端口」,推流时是「你发数据的端口」——同一字段,角色反了。

下一节换协议:RTSP 讲完了,进 RTP,先看那 12 个字节怎么排。

相关笔记