3、RTSP协议详解:RTSP协议栈、信令流程与RTP/RTCP的关系
RTSP这个协议,说白了就是流媒体的遥控器。你想想看,我们平时看视频,点播放、暂停、拖动进度条,这些操作在流媒体世界里就是通过RTSP来完成的。我最早接触RTSP是在做安防摄像头项目的时候,那时候被各种信令搞得头大,后来摸清了套路,发现它其实挺规整的。
3.1 RTSP协议栈定位
RTSP全称是Real Time Streaming Protocol,它工作在应用层。但它跟HTTP不太一样——HTTP是无状态的,RTSP是有状态的。什么意思呢?就是RTSP服务器得记住每个客户端当前在干什么,是刚连接上,还是已经在播放了。
来看一下RTSP在协议栈里的位置:
嗯,这里要注意:RTSP信令走TCP,而真正的音视频数据走RTP/UDP。这个分工很明确,信令要可靠,媒体要实时。
3.2 RTSP信令流程详解
RTSP的交互过程,我习惯把它叫做"四步握手"。分别是OPTIONS、DESCRIBE、SETUP、PLAY。每一步都有它的意义,少一步都不行。
3.2.1 OPTIONS —— 探探路
客户端先发个OPTIONS请求,问问服务器支持哪些方法。这就像你进一家餐厅,先看看菜单上有什么菜。
客户端 -> 服务器:
OPTIONS rtsp://192.168.1.100:554/live/stream RTSP/1.0
CSeq: 1
User-Agent: MyRTSPClient/1.0
服务器 -> 客户端:
RTSP/1.0 200 OK
CSeq: 1
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE
Date: Mon, 15 Jan 2024 10:30:00 GMT
3.2.2 DESCRIBE —— 看看流长什么样
DESCRIBE请求用来获取媒体描述信息,服务器会返回SDP(Session Description Protocol)。SDP里描述了视频编码格式、分辨率、帧率、音频采样率等等。
客户端 -> 服务器:
DESCRIBE rtsp://192.168.1.100:554/live/stream RTSP/1.0
CSeq: 2
Accept: application/sdp
服务器 -> 客户端:
RTSP/1.0 200 OK
CSeq: 2
Content-Type: application/sdp
Content-Length: 145
v=0
o=- 1234567890 1234567890 IN IP4 192.168.1.100
s=Live Stream
c=IN IP4 0.0.0.0
t=0 0
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=42e01f;sprop-parameter-sets=Z0IACpZUBQHsgA==,aM4G4g==
m=audio 0 RTP/AVP 97
a=rtpmap:97 MPEG4-GENERIC/16000/1
你看这个SDP,它告诉客户端:视频是H264编码,时钟频率90000,音频是MPEG4,采样率16000。这些信息后面SETUP的时候要用到。
3.2.3 SETUP —— 建立传输通道
SETUP这一步最关键。客户端要告诉服务器:我用什么端口收数据,用什么传输模式。这里有个坑——RTP和RTCP端口是配对的,RTP用偶数端口,RTCP用下一个奇数端口。
客户端 -> 服务器:
SETUP rtsp://192.168.1.100:554/live/stream/video RTSP/1.0
CSeq: 3
Transport: RTP/AVP/UDP;unicast;client_port=5000-5001
服务器 -> 客户端:
RTSP/1.0 200 OK
CSeq: 3
Transport: RTP/AVP/UDP;unicast;client_port=5000-5001;server_port=6000-6001
Session: 12345678
3.2.4 PLAY —— 开始播放
最后一步,告诉服务器开始发送数据。可以指定播放的范围,比如从第几秒开始。
客户端 -> 服务器:
PLAY rtsp://192.168.1.100:554/live/stream RTSP/1.0
CSeq: 4
Session: 12345678
Range: npt=0.000-
服务器 -> 客户端:
RTSP/1.0 200 OK
CSeq: 4
Session: 12345678
RTP-Info: url=rtsp://192.168.1.100:554/live/stream/video;seq=0;rtptime=0
收到这个响应后,RTP数据就开始从服务器往客户端飞了。
3.3 RTSP与RTP/RTCP的关系
很多人搞不清RTSP和RTP/RTCP到底什么关系。我打个比方:RTSP是导演,RTP是演员,RTCP是场记。
- RTSP(导演):负责喊开始、暂停、结束,不参与具体表演
- RTP(演员):负责把音视频数据演出来,实时传输
- RTCP(场记):记录演出质量,比如丢包率、延迟、抖动
它们之间的协作关系可以用这张图来表示:
3.4 RTP协议核心要点
RTP头部虽然只有12字节,但信息量很大。我挑几个关键字段说说:
| 字段 | 长度 | 作用 |
|---|---|---|
| Sequence Number | 16位 | 检测丢包和乱序,每发一个包加1 |
| Timestamp | 32位 | 时间戳,用于播放同步和抖动计算 |
| SSRC | 32位 | 同步源标识,区分不同的流 |
| Payload Type | 7位 | 标识负载类型,如H264=96 |
关键理解:RTP不保证可靠传输,也不保证按序到达。它只负责把数据包打上时间戳和序号扔出去。丢包了怎么办?那是上层应用的事,RTP不管。
3.5 RTCP的作用
RTCP是RTP的"小跟班",它周期性地发送控制包。主要做三件事:
- 质量反馈:发送端报告(SR)和接收端报告(RR),包含丢包率、累计丢包数、延迟抖动
- 源描述:CNAME,标识参与者的规范名称
- 会话控制:BYE包,通知对方自己要离开了
RTCP的带宽占用一般控制在会话总带宽的5%以内。这个比例是协议规定的,别乱改。
3.6 实际项目中的注意事项
做了这么多年流媒体,总结几个RTSP推流的要点:
- 信令超时:RTSP请求超时时间建议设5-10秒,太短容易误判,太长影响用户体验
- 会话保活:有些服务器会主动断开空闲会话,可以用GET_PARAMETER定期发心跳
- 端口选择:RTP端口范围建议用大端口(10000以上),避免被系统服务占用
- NAT穿透:如果客户端在NAT后面,SETUP时要用服务器返回的server_port来收数据
我的习惯:做RTSP客户端的时候,我会在SETUP之后先发一个PLAY请求,然后立刻开始接收RTP数据。不要等PLAY响应回来再开接收线程,因为有些服务器响应慢,但数据已经发出来了。提前开好接收缓冲区,能避免丢包。
RTSP这套信令流程,说白了就是"先问能不能、再看是什么、再定怎么传、最后开始播"。理解了这个逻辑,后面做WebRTC和RTSP的融合就顺了。