rtsp(real-time stream protocol)协议是一个基于文本的多媒体播放控制协议,属于应用层。rtsp以客户端方式工作,对流媒体提供播放、暂停、后退、前进等操作。该标准由ietf指定,对应的协议是rfc2326。
rtsp作为一个应用层协议,提供了一个可供扩展的框架,使得流媒体的受控和点播变得可能,它主要用来控制具有实时特性的数据的发送,但其本身并不用于传送流媒体数据,而必须依赖下层传输协议(如rtp/rtcp)所提供的服务来完成流媒体数据的传送。rtsp负责定义具体的控制信息、操作方法、状态码,以及描述与rtp之间的交互操作。rtsp媒体服务协议框架如下:
rtsp包含normal rtsp(数据通过rtp传输,应用厂商有苹果和微软等),以及real-rtsp(数据通过rdt传输)。本篇我们主要讲normal rtsp。
rtsp传输的一般是ts、mp4格式的流,其传输一般需要2~3个通道,命令和数据通道分离。使用rtsp协议传输流媒体数据需要有专门的媒体播放器和媒体服务器,也就是需要支持rtsp协议的客户端和服务器。
客户端要播放rtsp媒体流,就需要知道媒体源的url,rtsp的url格式一般如下:
rtsp://host[:port]/[abs_path]/content_name
host: 有效的域名或ip地址;
port: 端口号,缺省为554,若为缺省可不填写,否则必须写明。
例如,一个完整的rtsp url可写为:
rtsp://192.168.1.67:554/test
又如目前市面上常用的海康网络摄像头的rtsp地址格式为:
rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream
示例: rtsp://admin:[email protected]:554/h264/ch1/main/av_stream
rtsp://admin:[email protected]/mpeg4/ch1/sub/av_stream
对rtsp协议的使用有了一个大概的了解之后,我们来看一下rtsp报文结构。
rtsp是一种基于文本的协议,用crlf(回车换行)作为每一行的结束符,其好处是,在使用过程中可以方便地增加自定义参数,也方便抓包分析。从消息传送方向上来分,rtsp的报文有两类:请求报文和响应报文。请求报文是指从客户端向服务器发送的请求(也有少量从服务器向客户端发送的请求),响应报文是指从服务器到客户端的回应。
rtsp请求报文的常用方法与作用:
一次基本的rtsp交互过程如下,c表示客户端,s表示服务端。
首先客户端连接到流媒体服务器并发送一个rtsp描述请求(describe request),服务器通过一个sdp(session descriptionprotocol)描述来进行反馈(describeresponse),反馈信息包括流数量、媒体类型等信息。客户端分析该sdp描述,并为会话中的每一个流发送一个rtsp连接建立请求(setuprequest),该命令会告诉服务器用于接收媒体数据的端口,服务器响应该请求(setup response)并建立连接之后,就开始传送媒体流(rtp包)到客户端。在播放过程中客户端还可以向服务器发送请求来控制快进、快退和暂停等。最后,客户端可发送一个终止请求(teardown request)来结束流媒体会话。
下面我们通过具体的消息实例来进一步了解一下rtsp的工作过程:
- options
options请求是客户端向服务器询问可用的方法,请求和回复实例如下:
c->s: options rtsp://example.com/media.mp4 rtsp/1.0
cseq: 1
require: implicit-play
proxy-require: gzipped-messages
s->c: rtsp/1.0 200 ok
cseq: 1
public: describe, setup, teardown, play, pause
- describe
客户端向服务器请求媒体资源描述,服务器端通过sdp(session description protocol)格式回应客户端的请求。资源描述中会列出所请求媒体的媒体流及其相关信息,典型情况下,音频和视频分别作为一个媒体流传输。实例如下:
c->s: describe rtsp://example.com/media.mp4 rtsp/1.0
cseq: 2
s->c: rtsp/1.0 200 ok
cseq: 2
content-base: rtsp://example.com/media.mp4
content-type: application/sdp
content-length: 460
m=video 0 rtp/avp 96
a=control:streamid=0
a=range:npt=0-7.741000
a=length:npt=7.741000
a=rtpmap:96 mp4v-es/5544
a=mimetype:string;"video/mp4v-es"
a=avgbitrate:integer;304018
a=streamname:string;"hinted video track"
m=audio 0 rtp/avp 97
a=control:streamid=1
a=range:npt=0-7.712000
a=length:npt=7.712000
a=rtpmap:97 mpeg4-generic/32000/2
a=mimetype:string;"audio/mpeg4-generic"
a=avgbitrate:integer;65790
a=streamname:string;"hinted audio track"
- setup
setup请求确定了具体的媒体流如何传输,该请求必须在play请求之前发送。setup请求包含媒体流的url和客户端用于接收rtp数据(audio or video)的端口以及接收rtcp数据(meta information)的端口。服务器端的回复通常包含客户端请求参数的确认,并会补充缺失的部分,比如服务器选择的发送端口。每一个媒体流在发送play请求之前,都要首先通过setup请求来进行相应的配置。
c->s: setup rtsp://example.com/media.mp4/streamid=0 rtsp/1.0
cseq: 3
transport: rtp/avp;unicast;client_port=8000-8001
s->c: rtsp/1.0 200 ok
cseq: 3
transport: rtp/avp;unicast;client_port=8000-8001;server_port=9000-9001;ssrc=1234abcd
session: 12345678
- play
客户端通过play请求来播放一个或全部媒体流,play请求可以发送一次或多次,发送一次时,url为包含所有媒体流的地址,发送多次时,每一次请求携带的url只包含一个相应的媒体流。play请求中可指定播放的range,若未指定,则从媒体流的开始播放到结束,如果媒体流在播放过程中被暂停,则可在暂停处重新启动流的播放。
c->s: play rtsp://example.com/media.mp4 rtsp/1.0
cseq: 4
range: npt=5-20
session: 12345678
s->c: rtsp/1.0 200 ok
cseq: 4
session: 12345678
rtp-info: url=rtsp://example.com/media.mp4/streamid=0;seq=9810092;rtptime=3450012
- pause
pause请求会暂停一个或所有媒体流,后续可通过play请求恢复播放。pause请求中携带所请求媒体流的url,若参数range存在,则指明在何处暂停,若该参数不存在,则暂停立即生效,且暂停时长不确定。
c->s: pause rtsp://example.com/media.mp4 rtsp/1.0
cseq: 5
session: 12345678
s->c: rtsp/1.0 200 ok
cseq: 5
session: 12345678
- teardown
结束会话请求,该请求会停止所有媒体流,并释放服务器上的相关会话数据。
c->s: teardown rtsp://example.com/media.mp4 rtsp/1.0
cseq: 8
session: 12345678
s->c: rtsp/1.0 200 ok
cseq: 8
- get_parameter
检索指定uri数据中的参数值。不携带消息体的get_parameter可用来测试服务器端或客户端是否可通(类似ping的功能)。
s->c: get_parameter rtsp://example.com/media.mp4 rtsp/1.0
cseq: 9
content-type: text/parameters
session: 12345678
content-length: 15
packets_received
jitter
c->s: rtsp/1.0 200 ok
cseq: 9
content-length: 46
content-type: text/parameters
packets_received: 10
jitter: 0.3838
- set_parameter
用于设置指定媒体流的参数。
c->s: set_parameter rtsp://example.com/media.mp4 rtsp/1.0
cseq: 10
content-length: 20
content-type: text/parameters
barparam: barstuff
s->c: rtsp/1.0 451 invalid parameter
cseq: 10
content-length: 10
content-type: text/parameters
barparam
- redirect
重定向请求,用于服务器通知客户端新的服务地址,客户端需要向这个新地址重新发起请求。重定向请求中可能包含range参数,指明重定向生效的时间。客户端若需向新服务地址发起请求,必须先teardown当前会话,再向指定的新主机setup一个新的会话。
s->c: redirect rtsp://example.com/media.mp4 rtsp/1.0
cseq: 11
location: rtsp://bigserver.com:8001
range: clock=19960213t143205z-
- announce
announce请求有两个用途:(1)c->s:客户端向服务器端发布url指定的媒体信息描述;(2) s->c:实时更新对话描述。若媒体表示中新增了一个媒体流,例如在直播过程中,则整个媒体表示的description都要被重新发送,而不是只发送新增部分。
c->s: announce rtsp://example.com/media.mp4 rtsp/1.0
cseq: 7
date: 23 jan 1997 15:35:06 gmt
session: 12345678
content-type: application/sdp
content-length: 332
v=0
o=mhandley 2890844526 2890845468 in ip4 126.16.64.4
s=sdp seminar
i=a seminar on the session description protocol
u=http://www.cs.ucl.ac.uk/staff/m.handley/sdp.03.ps
[email protected] (mark handley)
c=in ip4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 3456 rtp/avp 0
m=video 2232 rtp/avp 31
s->c: rtsp/1.0 200 ok
cseq: 7
- record
请求录制指定范围的媒体数据,请求中可指定录制的起止时间戳;若未指定时间范围,则使用presentation description中的开始和结束时间,这种情况下,如果会话已开始,则立即启动录制操作。
c->s: record rtsp://example.com/media.mp4 rtsp/1.0
cseq: 6
session: 12345678
s->c: rtsp/1.0 200 ok
cseq: 6
session: 12345678
以上就是rtsp中常用的命令及其实例介绍。最后,来看一段实际使用的rtsp命令交互过程,该过程是通过pc对海康摄像头视频流的拉取和播放,并通过wireshark抓取客户端的数据得到的:
options rtsp://10.3.8.202:554 rtsp/1.0
cseq: 2
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
rtsp/1.0 200 ok
cseq: 2
public: options, describe, play, pause, setup, teardown, set_parameter, get_parameter
date: mon, jan 29 2018 16:56:47 gmt
describe rtsp://10.3.8.202:554 rtsp/1.0
cseq: 3
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
accept: application/sdp
rtsp/1.0 401 unauthorized
cseq: 3
www-authenticate: digest realm="ip camera(10789)", nonce="6b9a455aec675b8db81a9ceb802e4eb8", stale="false"
date: mon, jan 29 2018 16:56:47 gmt
describe rtsp://10.3.8.202:554 rtsp/1.0
cseq: 4
authorization: digest username="admin", realm="ip camera(10789)", nonce="6b9a455aec675b8db81a9ceb802e4eb8", uri="rtsp://10.3.8.202:554", response="3fc4b15d7a923fc36f32897e3cee69aa"
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
accept: application/sdp
rtsp/1.0 200 ok
cseq: 4
content-type: application/sdp
content-base: rtsp://10.3.8.202:554/
content-length: 551
v=0
o=- 1517245007527432 1517245007527432 in ip4 10.3.8.202
s=media presentation
e=none
b=as:5050
t=0 0
a=control:rtsp://10.3.8.202:554/
m=video 0 rtp/avp 96
c=in ip4 0.0.0.0
b=as:5000
a=recvonly
a=x-dimensions:2048,1536
a=control:rtsp://10.3.8.202:554/trackid=1
a=rtpmap:96 h264/90000
a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=z00amp2ocaawabgicaoaaamaagaaawblca==,ao48ga==
a=media_header:mediainfo=494d4b48010200000400000100000000000000000000000000000000000000000000000000000000;
a=appversion:1.0
setup rtsp://10.3.8.202:554/trackid=1 rtsp/1.0
cseq: 5
authorization: digest username="admin", realm="ip camera(10789)", nonce="6b9a455aec675b8db81a9ceb802e4eb8", uri="rtsp://10.3.8.202:554/", response="ddfbf3e268ae954979407369a104a620"
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
transport: rtp/avp;unicast;client_port=57844-57845
rtsp/1.0 200 ok
cseq: 5
session: 1273222592;timeout=60
transport: rtp/avp;unicast;client_port=57844-57845;server_port=8218-8219;ssrc=5181c73a;mode="play"
date: mon, jan 29 2018 16:56:47 gmt
play rtsp://10.3.8.202:554/ rtsp/1.0
cseq: 6
authorization: digest username="admin", realm="ip camera(10789)", nonce="6b9a455aec675b8db81a9ceb802e4eb8", uri="rtsp://10.3.8.202:554/", response="b5abf0b230de4b49d6c6d42569f88e91"
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
session: 1273222592
range: npt=0.000-
rtsp/1.0 200 ok
cseq: 6
session: 1273222592
rtp-info: url=rtsp://10.3.8.202:554/trackid=1;seq=65373;rtptime=3566398668
date: mon, jan 29 2018 16:56:47 gmt
get_parameter rtsp://10.3.8.202:554/ rtsp/1.0
cseq: 7
authorization: digest username="admin", realm="ip camera(10789)", nonce="6b9a455aec675b8db81a9ceb802e4eb8", uri="rtsp://10.3.8.202:554/", response="bb2309dcd083b25991c13e165673687b"
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
session: 1273222592
rtsp/1.0 200 ok
cseq: 7
date: mon, jan 29 2018 16:56:47 gmt
teardown rtsp://10.3.8.202:554/ rtsp/1.0
cseq: 8
authorization: digest username="admin", realm="ip camera(10789)", nonce="6b9a455aec675b8db81a9ceb802e4eb8", uri="rtsp://10.3.8.202:554/", response="e08a15c27d3daac14fd4b4bcab424a5e"
user-agent: libvlc/2.2.8 (live555 streaming media v2016.02.22)
session: 1273222592
rtsp/1.0 200 ok
cseq: 8
session: 1273222592
date: mon, jan 29 2018 16:57:03 gmt