RTSP
- RTSP介绍
- 1. 与HTTP协议的异同
- 2. RTSP的特性
- RTSP原理
- 1. RTSP会话交互过程
- 2. RTSP客户端状态机
- 3. RTSP server保活机制
- RTSP请求与回应
- 1.RTSP方法一览:
- 2.RTSP请求和回应信息格式
- 3. 必要方法
- 4. 其它方法:
- RTP包传输方式
- 扩展
RTSP介绍
RTSP(Real Timing Streaming Procotol)全称“实时流协议”,是TCP/IP协议体系下的一个应用层协议,定义了一对多应用程序如何有效地通过IP网络传送多媒体数据, 用于多媒体数据的网络控制。
1. 与HTTP协议的异同
同:
- 都是使用纯文本来发送信息,而且协议头语法类似(之所以类似,是为了兼容使用以前的HTTP协议分析代码)
- 用TCP协议传输信息
异:
- HTTP用TCP传输数据,RTSP常用UDP协议传输数据。
- HTTP协议是没有状态的,命令之间没有依赖性。
而RTSP协议是有状态的,RTSP的命令必须按照顺序来发送。 - RTSP协议的客户端和服务器端都可以发送Request请求。
HTTP协议只有客户端能发送Request请求。 - HTTP协议是短连接,在发送一个命令后,连接会断开。
而RTSP协议是长连接,无论处于什么状态都不会去断开连接。 - HTTP协议默认端口是80。
而RTSP协议默认端口是554。
2. RTSP的特性
- 流控分离:数据流和控制流分开,多媒体数据和控制信息通过不同的端口来接收。
- 可拓展性:基于文本的协议,具有较强的可拓展性。
- 安全:RTSP使用网页安全机制。
RTSP原理
RTSP组合使用了可靠传输协议TCP(控制信息)和高效传输协议UDP(媒体数据)来串流内容给用户。支持点播和直播。
RTSP协议本身只负责传输媒体控制信息,并不负责数据传输,使用RTP(Real-time Transport Protocol)和RTCP(Real-time Control Protocol)完成数据传输和数据检测。
会话参与者(发送端和接收端)周期性的向所有参与者发送RTCP包。主要功能是为应用程序提供会话质量或广播性能质量的信息,这些信息包括发送的信息包数目、丢失的信息包数目和信息包抖动等情况。
简而言之:
- RTSP(over TCP) --> 媒体控制
- RTCP(over UDP) --> 监控媒体数据传输质量
- RTP(over UDP) --> 媒体数据传输
协议在网络中的结构图:
1. RTSP会话交互过程
会话交互过程如下图:
- 首先发OPTION cmd请求服务器可使用的方法。
- 然后发DESCRIBE cmd请求服务器返回媒体的matedata,对于audio和video分开传输的情况,返回信息里面还有各自的url。
- 然后发送SETUP cmd请求服务器创建会话,请求体中需带数据传输协议以及客户端RTCP和RTP的接收端口号。
服务器返回会话ID和对应的服务器端口,客户端拿到服务器IP和端口,通过RTCP和RTP协议与服务器连接。 - 最后发送PLAY cmd请求服务器传输数据,此时客户端开始接收数据并播放。
- 播放结束后,发送TERADOWN cmd请求服务销毁会话。
2. RTSP客户端状态机
状态机如下图:
- 初始态(Init): SETUP请求已经发出,等待回复,尚未创建会话
- 就绪态(Ready): 收到SETUP回复,或在播放态收到pause回复,会话已创建好,可以进行数据传输。
- 播放态(Playing):收到PlAY回复,媒体数据开始传输,客户端播放媒体。
- 记录态(Recording): 收到RECORD回复,客户端开始录制数据。
3. RTSP server保活机制
客户端如果一段时间内(默认是60s)没有任何响应,那么rtsp服务器就会关闭该会话,所以客户端需要发送心跳包给服务器。
- rtsp层面上,定期向server发无效的控制信息(要带有session id的cmd,比如,空消息体的get_parameter命令,)
- rtp层面上,定期向server发送rtp包,包内容随意。
RTSP请求与回应
1.RTSP方法一览:
方法 | 方向 | 要求 | 作用 |
---|---|---|---|
DESCRIBE | C->S | 推荐 | 获得会话描述信息 |
ANNOUNCE | C->S,S->C | 可选 | 将请求URL识别的演示或媒体对象描述发给服务器 |
GET_PARAMETER | C->S,S->C | 可选 | 获得会话参数 |
SET_PARAMETER | C->S,S->C | 可选 | 设置会话参数 |
OPTIONS | C->S,S->C | 必要 | 获得服务器的可用方法 |
PAUSE | C->S | 推荐 | 客户端发起暂停播放请求 |
PLAY | C->S | 必要 | 客户端发起播放请求 |
RECORD | C->S | 可选 | 请求录制指定范围的媒体数据 |
REDIRECT | S->C | 可选 | 服务器返回重定向地址 |
SETUP | C->S | 必要 | 客户端请求建立会话 |
TERADOWN | C->S | 必要 | 客户端发起关闭会话请求 |
c: client s: server
2.RTSP请求和回应信息格式
请求和回应的模板如下所示。
在请求和回应的消息头中都有一个CSeq的参数,是为了进行客户端和服务端的同步而设立的。
CSeq初始值为1,客户端每发起一个请求,该值加1。传输正确的情况下,服务端的回应中的CSeq应该与对应请求相等。
- RTSP请求:
[方法] [URI] [RTSP版本]<CR LF>[消息头]<CR LF><CR LF>[消息体]<CR LF>
- RTSP回应:
[RTSP版本] [状态码] [状态码解释]<CR LF>[消息头]<CR LF><CR LF>[消息体]<CR LF>
3. 必要方法
-
OPTIONS
用于请求服务器所支持的所有方法。C->S OPTIONS rtsp://video.foocorp.com:554 RTSP/1.0CSeq: 1 S->C RTSP/1.0 200 OKCSeq: 1Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, RECORD
-
DESCRIBE
用来请求URL指定对象的描述信息,通常描述信息使用SDP(Session Description Protocol)格式。
描述信息中比较重要的是数据传输方式、播放时长以及codec type。C->S DESCRIBE rtsp://video.foocorp.com:554/streams/example.rm RTSP/1.0CSeq: 2S->C RTSP/1.0 200 OKCSeq: 2Content-Type: application/sdpContent-Length: 210 m=video 0 RTP/AVP 96a=control:streamid=0a=range:npt=0-7.741000a=length:npt=7.741000a=rtpmap:96 MP4V-ES/5544a=mimetype:string;"video/MP4V-ES"a=AvgBitRate:integer;304018a=StreamName:string;"hinted video track"m=audio 0 RTP/AVP 97a=control:streamid=1a=range:npt=0-7.712000a=length:npt=7.712000a=rtpmap:97 mpeg4-generic/32000/2a=mimetype:string;"audio/mpeg4-generic"a=AvgBitRate:integer;65790a=StreamName:string;"hinted audio track"
从SDP信息中可以知道码流的元数据信息。
-
SETUP:
用于请求URL使用指定传输格式,必须在PLAY前发出。C->S SETUP rtsp://video.foocorp.com:554/streams/example.rm RTSP/1.0CSeq: 3Transport: rtp/udp;unicast;client_port=5067-5068 S->C RTSP/1.0 200 OKCSeq: 3Session: 12345678Transport: rtp/udp;client_port=5067-5068;server_port=6023-6024
客户端发起的请求说明接收RTP和RTCP数据的端口,一般’-‘前面的是RTP,’-'后面的是RTCP,比如上述请求:
用接收RTP数据(音视频)的本地端口是5067,接收RTCP数据的本地端口是5068
而服务器返回的信息说明服务端对应RTP和RTCP的端口,比如上述响应:
server对应的端口是6023和6024。
重要的是,服务器端还会将该传输会话的ID带给客户端,也就是Session ID,之后客户端的请求都需要带这个唯一标识码。
另外,如果发现setup的client端口已经被强占的话,可以不用关闭会话,只需要再次调用setup来重新配置端口,不过要带上当前的Session ID。
需要说明的是,端口之间是有一定联系的。如下图:
-
PLAY:
用于请求服务器开始传输数据,该请求是需要排队的,执行完一个PLAY请求,再执行下一个。
另外该请求可以带Range关键字,请求不同时间点的数据,单位是秒,相当于seek操作。C->S PLAY rtsp://video.foocorp.com:554/streams/example.rm RTSP/1.0CSeq: 4 Session: 12345678Range: npt=0.000- //设置播放时间的范围,单位是秒,精度小数点后三位User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) S->C RTSP/1.0 200 OKCSeq: 4Session: 12345678Range: npt=0.000000-
如果要实现快进/快退功能,也是通过PLAY cmd向服务器请求,快进/快退倍速通过Scale关键字提供,如下:
C->S PLAY rtsp://video.foocorp.com:554/streams/example.rm RTSP/1.0 CSeq: 4 Session: 12345678 SCALE: 4 // 设置快进/快退倍速 User-Agent: VLC media player (LIVE555 Streaming Media v2005.11.10) S->C RTSP/1.0 200 OK CSeq: 4 Session: 12345678 SCALE: 4
-
TEARDOWN:
用于请求终止会话,停止会话相关码流,并释放资源。C->S TEARDOWN rtsp://video.foocorp.com:554/streams/example.rm RTSP/1.0CSeq: 5Session: 12345678S->C RTSP/1.0 200 OKCSeq: 5
4. 其它方法:
- ANNOUNCE(公布、通知): -->(额 囊 斯 ~)
S --> C: 用于实时更新会话描述。
C --> S: 通知客户端特定媒体事件,如eof。
例:C->S: ANNOUNCE rtsp://video.foocorp.com:554/streams/example.rm RTSP/1.0CSeq: 10Session: 47112344Content-Type: application/sdpContent-Length: 332v=0o=mhandley 2890844526 2890845468 IN IP4 126.16.64.4s=SDP Seminari=A Seminar on the session description protocolu=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.pse=mjh@isi.edu(Mark Handley)c=IN IP4 224.2.17.12/127t=2873397496 2873404696a=recvonlym=audio 3456 RTP/AVP 0m=video 2232 RTP/AVP 31S->C: RTSP/1.0 200 OKCSeq: 10
- GET_PARAMETER:
用于请求URI指定呈现或流的参数值。
返回的内容有待实现,如果不带任何实体主体的GET_PARAMETER可用于测试客户端或者服务器是否"在线"(类似ping)
例:S->C: GET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0CSeq: 431Content-Type: text/parametersSession: 12345678Content-Length: 15packets_receivedjitterC->S: RTSP/1.0 200 OKCSeq: 431Content-Length: 46Content-Type: text/parameterspackets_received: 10jitter: 0.3838
- SET_PARAMETER:
用于设置URI指定呈现或者流的参数值。
每条请求都应当只包含一个参数以允许客户端在设置失败的时候确认失败原因。
如果请求中包含多个参数,服务器必须在所有参数设置成功的情况下生效,否则返回参数错误的键(如下例子)。
服务器应当允许同一参数多次设置同一值,但是可以拒绝设置为不同的值,由服务器根据时机情况而定。
需要注意的是,对于媒体流参数(如端口等)不可通过该方法设置,必须通过SETUP请求来设置。
以下为设置失败的例子,服务器返回"Invalid Parameter"C->S: SET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0CSeq: 421Content-Length: 20Content-type: text/parametersbarparam: barstuff // 格式<key>:<value>S->C: RTSP/1.0 451 Invalid ParameterCSeq: 421Content-Length: 10Content-type: text/parametersbarparam // 返回参数错误的键
- PAUSE:
用于临时中断流传输,如果URL指定的是某一个流(audio or video),则该流的播放和录制都会被暂停。
如果URL指定的是一组流,则呈现或组中所有活动流,都会被暂停。
中断期间,所有服务器资源都会保留;
但是如果SETUP时,请求中有指定延时参数,那么服务器会在pause持续时长达到设置的延时时长后关闭会话并释放资源。
例:C->S: PAUSE rtsp://example.com/fizzle/foo RTSP/1.0CSeq: 834Session: 12345678S->C: RTSP/1.0 200 OKCSeq: 834Date: 23 Jan 1997 15:35:06 GMT
- RECORD:
用于开始录制当前呈现描述中的一段媒体数据,UTC格式的时间戳包含开始录制点和结束录制点。
如果请求中没有提供录制时间范围,则从当前时间点开始录制,直到呈现描述中的结束点为止。
服务器决定将录制数据保存在请求URI还是其他URI。
如果是保存在其他URI,则server返回"201"并包含描述请求状态和录制资源位置信息。
例:C->S: RECORD rtsp://example.com/meeting/audio.en RTSP/1.0CSeq: 954Session: 12345678Conference: 128.16.64.19/32492374
- REDIRECT:
用于提示客户端需要重新连接另一个服务器,响应报文中必须包含Location头,以指明新的服务器URL。
其中还可能包含Range参数,指明何时重定向生效。
如果客户端在SETUP后希望向重定向的URL接收媒体数据,则必须先对当前会话发出TEARDOWN请求,然后重新向目标主机发出SETUP请求新的会话。
例:S->C: REDIRECT rtsp://example.com/fizzle/foo RTSP/1.0CSeq: 732Location: rtsp://bigserver.com:8001Range: clock=19960213T143205Z-
RTP包传输方式
RTP包的传输方式在SETUP cmd中指定,分为两种:
- Over UDP传输,默认传输方式,SETUP带的参数为RTP/AVP/UDP或者RTP/AVP,如下:
可以看到通过UDP传输,RTP接收端口是4588,对应发送端口为6256;RTCP交互端口为4589,对应端口为6257.C->S: SETUP rtsp://example.com/foo/bar/baz.rm RTSP/1.0CSeq: 302Transport: RTP/AVP;unicast;client_port=4588-4589 S->C: RTSP/1.0 200 OKCSeq: 302Date: 23 Jan 1997 15:35:06 GMTSession: 47112344Transport: RTP/AVP;unicast; client_port=4588-4589;server_port=6256-6257
这样的话,对于ts stream,需要创建3个socket(rtsp, ts rtp, ts rtcp);
而对于fMP4,需要创建5个socket(rtsp, audio rtp, audio rtcp, video rtp, video rtcp)。
连接示意图:
- Over TCP传输,SETUP带的参数为RTP/AVP/TCP,如下:
通过TCP传输的话,RTSP cmd、RTP packet和RTCP packet是在同一个TCP连接上传输的,示意图如下:C->S: SETUP rtsp://foo.com/bar.file RTSP/1.0CSeq: 2Transport: RTP/AVP/TCP;interleaved=0-1S->C: RTSP/1.0 200 OKCSeq: 2Date: 05 Jun 1997 18:57:18 GMTTransport: RTP/AVP/TCP;interleaved=0-1
为了区分RTP包和RTCP包,新增了一层RTSP Interleaved Frame:
扩展
-
点播的case,如何判断End of stream?
1> 服务器主动发"ANNOUNCE" cmd告诉player码流传输结束。S->C: ANNOUNCE rtsp://172.16.12.6:5554/… RTSP/1.0CSeq: 4Session: 370384394x-notice: 2101 "End-of-Stream Reached" event-data=20210706T025811Z
2> 可以从DESCRIBE的SDP info中拿到duration,那么播放时长(playtime + 1)达到duration,那就认为数据传输结束。
3> 最新的规范(RTSP 2.0)中,服务器发送"PLAY_NOTIFY"cmd给客户端,通知eos。S->C: PLAY_NOTIFY rtsp://example.com/… RTSP/2.0Cseq:854Notify-Reason: end-of-stream
4>无法拿到duration,那么设置100秒超时,如果100秒内server没有发送播放数据给player,那就认为数据传输结束。
-
RTSP重定向的情况:
DESCRIBE请求返回303说明要进行重定向,响应头中会说明重定向的url。
客户端需要对重定向url重新进行OPTION和DESCRIBE请求。C->S: DESCRIBE rtsp://172.16.74.210:559/2305_3a__3a_MOV00000002305106151_3a__3a_2305106151_f.mpg RTSP/1.0 CSeq: 2 User-Agent: MODPlayerS->C: RTSP/1.0 303 See Other Server: Orbit2x CSeq: 2 Location: rtsp://172.17.178.142:554/2305_3a__3a_MOV00000002305106151_3a__3a_2305106151_f.mpgC->S: OPTIONS rtsp://172.17.178.142:554/2305_3a__3a_MOV00000002305106151_3a__3a_2305106151_f.mpg RTSP/1.0 CSeq: 1 User-Agent: MODPlayerS->C: RTSP/1.0 200 OK Server: Orbit2x CSeq: 1 Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETERC->S: DESCRIBE rtsp://172.17.178.142:554/2305_3a__3a_MOV00000002305106151_3a__3a_2305106151_f.mpg RTSP/1.0 CSeq: 2 User-Agent: MODPlayerS->C: RTSP/1.0 200 OK Server: Orbit2x CSeq: 2 Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER Content-Type: application/sdp Content-Length: 178
-
媒体数据直接基于UDP传输:
transport是RAW/RAW/UDP,传输的数据没有封包为RTP包,直接以UDP包的形式传输。SETUP rtsp://172.17.245.46:554/378289119.ts RTSP/1.0 Transport: RAW/RAW/UDP;unicast;destination=10.134.37.122;client_port=15500 User-Agent: MODPlayer CSeq: 3RTSP/1.0 200 OK Server: Orbit2x CSeq: 3 Session: 26931165;timeout=60 Transport: RAW/RAW/UDP;unicast;destination=10.134.37.122;client_port=15500;source=172.17.245.46;server_port=10000----------------- udp的url是:udp://172.17.245.46:10000 --> 注意这是一个单播地址,不是udp组播地址(224. ~ 239.)
-
SDP:
SDP(Session Description Protocol)是一个用来描述多媒体会话的应用层控制协议,是一个基于文本的协议。
用来会话建立过程中的媒体类型,以及协商编码方案等。
SDP由许多文本行组成,文本行的格式为<类型>=<值>,<类型>是一个字母,<值>是结构化的文本串,其格式视<类型>而定。
SDP文本行例子:v=<version> (协议版本) o=<username> <session id> <version> <network type> <address type> <address> (所有者/创建者和会话标识符) s=<session name> (会话名称) i=<session description> (会话信息) u=<URI> (URI 描述) e=<email address> (Email 地址) p=<phone number> (电话号码) c=<network type> <address type> <connection address> (连接信息) b=<modifier>:<bandwidth-value> (带宽信息) t=<start time> <stop time> (会话活动时间) r=<repeat interval> <active duration> <list of offsets from start-time>(0或多次重复次数) z=<adjustment time> <offset> <adjustment time> <offset> .... k=<method> k=<method>:<encryption key> (加密密钥) a=<attribute> (0 个或多个会话属性行) a=<attribute>:<value> m=<media> <port> <transport> <fmt list> (媒体名称和传输地址)