一.RTSP的简述

RTSP(实时流传输协议)是TCP/IP协议体系中的应用层协议,专门用于控制实时流媒体传输。该协议最初由哥伦比亚大学、网景和RealNetworks公司联合开发,并被IETF收录为RFC2326标准。RTSP主要功能是建立、管理和终止媒体会话,支持播放控制(如开始、暂停、快进、停止等),实现一对多的多媒体数据IP网络传输。需要特别说明的是,RTSP本身不直接传输媒体数据,实际数据传输由RTP/RTCP等配套协议完成。
二.RTSP的交互过程
RTSP协议支持两种工作模式:Play模式和Record模式。在Play模式下,客户端主动请求并接收流媒体音视频数据,适用于视频点播和直播观看场景;而在Record模式下,客户端向服务端推送音视频数据,主要用于直播推流和监控录像存储。
2.1.RTSP的Play的交互流程
cpp
RTSP Client RTSP Server
| |
| OPTIONS rtsp://... RTSP/1.0 |
|------------------------------------------->|
| (二进制: 文本协议,非二进制,故略) |
| |
| RTSP/1.0 200 OK |
|<-------------------------------------------|
| |
| DESCRIBE rtsp://... RTSP/1.0 |
|------------------------------------------->|
| (返回 SDP,文本) |
|<-------------------------------------------|
| |
| SETUP rtsp://.../trackID=0 RTSP/1.0 |
|------------------------------------------->|
| Transport: RTP/AVP;unicast;client_port=5000-5001 |
| |
| RTSP/1.0 200 OK |
| Session: 123456; Transport: server_port=5002-5003 |
|<-------------------------------------------|
| |
| PLAY rtsp://... RTSP/1.0 |
| Session: 123456 |
|------------------------------------------->|
| RTSP/1.0 200 OK |
|<-------------------------------------------|
| |
| ============= RTP 数据流 (二进制) ============== |
| (RTP 包结构见下图) |
|<===========================================|
| ============= RTCP 数据流 (二进制) ============= |
|<-------------------------------------------|
| |
| TEARDOWN rtsp://... RTSP/1.0 |
| Session: 123456 |
|------------------------------------------->|
| RTSP/1.0 200 OK |
|<-------------------------------------------|
上图展示了RTSP协议中Play指令的交互流程。RTSP客户端与服务端需要完成以下步骤:首先通过OPTIONS字段获取服务器支持的接口,接着使用DESCRIBE字段获取直播流媒体信息,然后通过SETUP字段建立媒体传输通道,发送PLAY指令开始播放。在播放过程中,服务端通过RTP包传输音视频数据,同时通过RTCP包传输控制信息。最后通过TearDown指令结束会话。以下是具体的交互流程表格:
|------------------------------|-------------------|-------------------------------------|---|
| Direction访问方向 | Message消息 | Description描述 | |
| Rtsp Client---->Rtsp Server | OPTION request | Rtsp Client访问Rtsp Server有哪些方法 | |
| Rtsp Server---->Rtsp Client | OPTION response | Rtsp Server回应有多少方法可用 | |
| Rtsp Client---->Rtsp Server | DESCRIBE request | Client 请求得到 Server 提供的流媒体初始化描述信息 | |
| Rtsp Server---->Rtsp Client | DESCRIBE response | Server 回应媒体初始化信息,主要是 SDP | |
| Rtsp Client---->Rtsp Server | SETUP request | 设置会话属性以及传输模式,请求建立会话 | |
| Rtsp Server---->Rtsp Client | SETUP response | Server 建立会话, 返回会话标识符以及会话相关信息 | |
| Rtsp Client---->Rtsp Server | PLAY request | Rtsp Client 请求播放 | |
| Rtsp Server---->Rtsp Client | PLAY response | Rtsp Server 回应播放请求信息 | |
| Rtsp Server---->Rtsp Client | RTP DATA | Rtsp Server发送RTP的音视频包到Rtsp Client | |
| Rtsp Server---->Rtsp Client | RTCP DATA | Rtsp Server发送RTCP的控制信息包到Rtsp Client | |
| Rtsp Client---->Rtsp Server | TEARDOWN request | Rtsp Client 请求关闭会话 | |
| Rtsp Server---->Rtsp Client | TEARDOWN response | Rtsp Server回应关闭会话请求 | |
2.2.RTSP的Record的交互流程
cpp
Rtsp Client Rtsp Server
| |
|------------------ OPTIONS ------------------->|
| |
|----------------- ANNOUNCE ------------------->|
| |
|------------------ SET UP -------------------->|
| |
|------------------ RECORD -------------------->|
| |
|<---------------- RTP DATA ------------------->|
| |
|<---------------- RTCP DATA ------------------>|
| |
|----------------- Tear Down ------------------->|
| |
上图展示了RTSP录制模式的交互流程。RTSP客户端与服务端需要完成以下步骤:首先通过OPTIONS字段获取服务器支持的接口,然后使用ANNOUNCE字段获取直播流媒体信息,接着通过SETUP字段建立媒体传输通道,再发送RECORD命令开始录制。在数据传输阶段,客户端通过RTP传输音视频数据,同时通过RTCP发送控制包。最后通过TearDown结束会话。以下是具体的交互流程表格:
|------------------------------|-------------------|---------------------------------------------------------------------------|---|
| Direction访问方向 | Message消息 | Description描述 | |
| Rtsp Client---->Rtsp Server | OPTION request | Rtsp Client访问Rtsp Server有哪些方法 | |
| Rtsp Server---->Rtsp Client | OPTION response | Rtsp Server回应有多少方法可用 | |
| Rtsp Client---->Rtsp Server | ANNOUNCE request | Rtsp Client 请求得到 Server 提供的流媒体初始化描述信息(比如视频编码(H.264/H.265)、分辨率、帧率、SDP 描述等) | |
| Rtsp Server---->Rtsp Client | ANNOUNCE response | Rtsp Server 回应媒体初始化信息,主要是 SDP | |
| Rtsp Client---->Rtsp Server | SETUP request | 设置会话属性以及传输模式,请求建立会话 | |
| Rtsp Server---->Rtsp Client | SETUP response | Server 建立会话, 返回会话标识符以及会话相关信息 | |
| Rtsp Client---->Rtsp Server | RECORD request | Rtsp Client 发送RECORD命令请求录制、直播 | |
| Rtsp Server---->Rtsp Client | RECORD response | Rtsp Server 回应录制请求信息 | |
| Rtsp Client---->Rtsp Server | RTP DATA | Rtsp Client发送RTP的音视频包到Rtsp Server | |
| Rtsp Client---->Rtsp Server | RTCP DATA | Rtsp Client发送RTCP的控制信息包到Rtsp Server | |
| Rtsp Client---->Rtsp Server | TEARDOWN request | Rtsp Client 请求关闭会话 | |
| Rtsp Server---->Rtsp Client | TEARDOWN response | Rtsp Server回应关闭会话请求 | |
三.RTSP和RTP/RTCP关系
cpp
+-------------------------------------------------+
| 应用层 |
| ┌─────────────────┐ |
| │ RTSP │ |
| └─────────────────┘ |
| ┌──────────────────┐ ┌─────────────────┐ |
| │ RTP/RTCP (UDP) │ │ TCP │ |
| └──────────────────┘ └─────────────────┘ |
+-------------------------------------------------+
| 网络层 (IP, RSVP) |
+-------------------------------------------------+
| 数据链路层 |
+-------------------------------------------------+
| 物理层 |
+-------------------------------------------------+
这三个协议分工明确,是 RTSP 推流中 "控制 + 数据 + 质量监控" 的铁三角
1. 核心分工:一个指挥,一个干活
| 协议 | 角色 | 核心职责 | 传输方式 |
|---|---|---|---|
| RTSP | 指挥官 | 只负责「控制会话」,比如建立连接、协商参数、开始 / 暂停 / 停止推流 | 基于 TCP(可靠传输) |
| RTP | 搬运工 | 只负责「传输媒体数据」,比如视频帧、音频帧的打包和发送 | 通常基于 UDP(低延迟) |
| RTCP | 质检员 | 伴随 RTP 工作,负责监控传输质量(丢包率、延迟、抖动)并反馈 | 通常基于 UDP(和 RTP 同端口号 + 1) |
2. 完整推流流程里的协作关系
cpp
1. RTSP 先建立控制连接(TCP)
↓
2. RTSP 协商传输参数(比如用哪个端口传 RTP)
↓
3. 建立 RTP/RTCP 传输通道(UDP)
↓
4. RTSP 发送 RECORD/PLAY 指令 → 通知开始推流/拉流
↓
5. RTP 负责源源不断地发视频/音频数据
↓
6. RTCP 定期发送质量反馈,让客户端/服务器调整传输策略
↓
7. RTSP 发送 TEARDOWN 指令 → 断开会话,释放 RTP/RTCP 端口
3. 关键区别与联系
- 控制与数据分离:RTSP 控制流和 RTP 媒体流是两条独立的通道,互不干扰。比如:网络卡顿的时候,RTSP 的控制指令可以先暂停推流,RTP 通道也会同步停止发送数据。
- 协议依赖关系 :
- RTSP 本身不传输媒体数据,必须依赖 RTP/RTCP 才能完成推流 / 拉流;
- RTP/RTCP 是纯数据 / 控制协议,没有会话管理能力,必须由 RTSP 来协商端口、建立会话。
- 传输方式差异 :
- RTSP 用 TCP:因为控制指令必须可靠送达(比如 "停止推流" 指令丢了会导致异常);
- RTP/RTCP 用 UDP:因为媒体数据对延迟敏感,少量丢包可以通过纠错 / 重传机制处理,不用像 TCP 那样等待重传确认。
四.RTP是如何进行发包和拆包的?
一、先搞懂核心:RTP 到底在干什么?
RTP(Real-time Transport Protocol)是专门给音视频用的传输协议,核心目的是:
- 把大块的视频帧 / 音频数据,切成一个个小的 RTP 包,通过 UDP 发送出去;
- 接收端再把这些小包按顺序拼起来,还原成原始帧。
你可以把它想象成:
- 你要寄一本很厚的书(视频帧),快递一次装不下,只能拆成几页纸(RTP 包)分别寄;
- 每个信封上都写了页码(序号)、寄件时间(时间戳),对方收到后按页码拼起来,就能还原整本书。
二、RTP 发包(发送端)过程详解
1. 前提:为什么要拆包?
- UDP 单包最大长度受限于 MTU(以太网通常是 1500 字节);
- 减去 IP 头(20 字节)+ UDP 头(8 字节),剩下给 RTP 数据的空间大约是
1500 - 28 = 1472字节; - 如果你的视频帧(比如一帧 H.264 I 帧)超过 1472 字节,就必须拆成多个 RTP 包发送,否则会被 IP 层分片,导致延迟和丢包率上升。
2. 发包步骤(以 H.264 为例)
- 拿到原始帧数据:比如一帧 H.264 NALU,大小 2000 字节。
- 确定 RTP 负载类型和最大包长 :
- 负载类型:H.264 通常用
96作为动态负载类型; - 最大 RTP 包数据长度:设为 1400 字节(留安全余量)。
- 负载类型:H.264 通常用
- 循环切分数据 :
- 第 1 个包:取 0~1399 字节,加上 RTP 头;
- 第 2 个包:取 1400~1999 字节,加上 RTP 头;
4.给每个包打 RTP 头:每个 RTP 包都有固定的头结构,关键字段如下:
cpp
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 重点字段作用:
sequence number(序列号):每个包递增 1,用于接收端排序和检测丢包;timestamp(时间戳):同一帧的所有 RTP 包时间戳相同,用于接收端区分不同帧;M(marker 位):同一帧的最后一个包设为 1,告诉接收端「这是这一帧的最后一个包」;PT(payload type):标识负载类型(H.264、AAC 等)。
5.发送 RTP 包:通过 UDP 套接字,按顺序发送所有切好的包。
三、RTP 拆包(接收端)过程详解
接收端的核心任务:按时间戳和序列号,把 RTP 包还原成原始帧。
1. 接收端步骤
- 收到 RTP 包 :解析 RTP 头,提取
sequence number、timestamp、M 位、SSRC等信息。 - 缓存与排序 :
- 按
timestamp分组,同一时间戳的包属于同一帧; - 同一帧内的包按
sequence number排序; - 处理乱序包(比如后收到的包序列号比前面的大),先缓存起来。
- 按
- 判断帧是否完整 :
- 收到标记
M=1的包,说明这是该时间戳帧的最后一个包; - 检查同一时间戳下,序列号是否连续,有没有丢包;
- 收到标记
- 拼接数据:把同一帧的所有 RTP 包的负载数据按顺序拼接起来,还原成原始 NALU / 帧数据;
- 递交给解码器:把拼接好的完整帧数据传给 H.264 解码器。
cpp
【发送端】
原始视频帧(2000字节)
↓
切分:
+----------------+
| 包1(0~1399字节) | seq=100, ts=1234, M=0
+----------------+
| 包2(1400~1999字节) | seq=101, ts=1234, M=1
+----------------+
↓
通过 UDP 发送出去(顺序可能乱)
【接收端】
收到包2 → 缓存(ts=1234, seq=101, M=1)
收到包1 → 缓存(ts=1234, seq=100, M=0)
↓
按 ts=1234 分组,按 seq 排序:包1 → 包2
↓
拼接负载:1400字节 + 600字节 = 2000字节
↓
还原成原始视频帧,传给解码器
四.总结
- 发包:按 MTU 限制把大帧切成多个 RTP 包,每个包带有序列号、时间戳、标记位,通过 UDP 发送;
- 拆包:按时间戳分组、序列号排序,收到标记位为 1 的包后拼接数据,还原成原始帧;
- 核心:时间戳区分帧,序列号保证顺序,标记位标识帧结束,三者配合完成数据的拆分与重组。