rtsp概述
rtsp (real-time stream protocol)实时流媒体控制协议。RFC2326:这是RTSP的初始定义版本v1.0,由哥伦比亚大学、网景和RealNetworks公司提交给互联网工程任务组(IETF)作为RFC标准。RFC7826:这是RTSP的后续更新版本v2.0,对RFC2326中的RTSP进行了扩展和更新。
rtsp协议属于基于文本的应用层协议,rtsp的底层协议可以是udp也可以是tcp
ffmpeg 参数
-rtsp_transport tcp
用于指定RTSP会话底层传输协议为TCP,实现 RTSP 的系统必须支持通过 TCP 承载 RTSP,并且可以支持 UDP。 RTSP 服务器的默认端口对于 UDP 和 TCP 都是 554
本身并不传输流媒体数据,只是提供流媒体的控制,实际流媒体的传输使用rtp协议,协议文档可以从资源链接下载rtsp协议中英双文https://download.csdn.net/download/shenhuxi_yu/89358966
使用wireshark rtsp筛选器既可以比较容易的分析rtsp协议内容
如上图是本地使用vlc工具打开远程流的过程中抓到的rtsp包,rtsp报文包括request和response,服务端和客户端都可以法request和response
request 报文分析
以第一个报文为例rtsp报文的格式如下
一个client请求sever的options request的消息格式如下,request-line是request的第一行,CRLF作为行结束符,CSeq 字段指定 RTSP 请求-响应对的序列号。 该字段必须出现在所有请求和响应中。 对于每个包含给定序列号的 RTSP 请求,都会有一个具有相同编号的相应响应。 任何重传的请求必须包含与原始请求相同的序列号(即,序列号不会因相同请求的重传而增加)。SP分隔符具体是指空格字符(Space Character)
C->S: OPTIONS * RTSP/1.0
CSeq: 1
Require: implicit-play
Proxy-Require: gzipped-messages
Request = Request-Line ; Section 6.1
*( general-header ; Section 5
| request-header ; Section 6.2
| entity-header ) ; Section 8.1
CRLF
[ message-body ] ; Section 4.3
Request-Line = Method SP Request-URI SP RTSP-Version CRLF
Method = "DESCRIBE" ; Section 10.2
| "ANNOUNCE" ; Section 10.3
| "GET_PARAMETER" ; Section 10.8
| "OPTIONS" ; Section 10.1
| "PAUSE" ; Section 10.6
| "PLAY" ; Section 10.5
| "RECORD" ; Section 10.11
| "REDIRECT" ; Section 10.10
| "SETUP" ; Section 10.4
| "SET_PARAMETER" ; Section 10.9
| "TEARDOWN" ; Section 10.7
| extension-method
extension-method = token
Request-URI = "*" | absolute_URI
RTSP-Version = "RTSP" "/" 1*DIGIT "." 1*DIGIT
request-header = Accept ; Section 12.1
| Accept-Encoding ; Section 12.2
| Accept-Language ; Section 12.3
| Authorization ; Section 12.5
| From ; Section 12.20
| If-Modified-Since ; Section 12.23
| Range ; Section 12.29
| Referer ; Section 12.30
| User-Agent ; Section 12.41
response 报文分析
第二条报文时response报文类型CSeq与第一个报文相同,因此是对第一个报文的回复
Response = Status-Line ; Section 7.1
*( general-header ; Section 5
| response-header ; Section 7.1.2
| entity-header ) ; Section 8.1
CRLF
[message-body ] ; Section 4.3
Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
response-header = Location ; Section 12.25
| Proxy-Authenticate ; Section 12.26
| Public ; Section 12.28
| Retry-After ; Section 12.31
| Server ; Section 12.36
| Vary ; Section 12.42
| WWW-Authenticate ; Section 12.44
Status-Code状态表如下
客户端使用 OPTIONS 方法查询服务器支持的方法。 服务器使用Public响应头列出它支持的方法。并使用Server响应头报告服务器信息。
rtsp连接过程
从如上的抓包可以看到vlc打开并播放rtsp流的过程的报文以此是OPTIONS-->DESCRIBE-->SETUP-->PLAY,,开始播放后每隔58s通信一次GET_PARAMETER消息。当客户端关闭VLC的时候发送TEARDOWN报文。
这个过程的解释如下
OPTIONS 请求可以在任何时候发出,例如,如果客户端将要尝试一个非标准请求。
它不会影响服务器状态。
DESCRIBE 方法从服务器检索由请求 URL 标识的演示文稿或媒体对象的描述。
它可以使用 Accept 头来指定客户端理解的描述格式。
服务器以所请求资源的描述作为响应。 DESCRIBE 回复-响应对构成了 RTSP 的媒体初始化阶段
SETUP 请求指定用于流媒体的传输机制。 客户端可以对已经播放的流发出 SETUP 请求以更改传输参数,
服务器可以允许。 如果它不允许这样做,它必须以错误“455 Method Not Valid In This State”响应。
为了通过任何中间防火墙,客户端必须指明传输参数,即使它对这些参数没有影响,
例如,服务器在哪里通告固定的多播地址。服务器生成会话标识符以响应 SETUP 请求。
如果对服务器的 SETUP 请求包含会话标识符,则服务器必须将此设置请求捆绑到
现有会话或返回错误“459 不允许聚合操作”
PLAY 方法告诉服务器通过 SETUP 中指定的机制开始发送数据。
在任何未完成的 SETUP 请求被确认为成功之前,客户端不得发出 PLAY 请求。
PLAY 请求将正常播放时间定位到指定范围的开始,并传送流数据直到到达范围结束。
PLAY 请求可能会被流水线化(排队); 服务器必须将 PLAY 请求按顺序执行。
也就是说,在前一个 PLAY 请求仍处于活动状态时到达的 PLAY 请求会被延迟,直到第一个请求完成。
GET_PARAMETER 请求检索 URI 中指定的演示文稿或流的参数值。
回复和响应的内容留给实现。 没有实体主体的 GET_PARAMETER
可用于测试客户端或服务器的活跃度(“ping”)。
TEARDOWN 请求停止给定 URI 的流传输,释放与之关联的资源。
如果 URI 是此演示文稿的演示文稿 URI,则与该会话关联的任何 RTSP 会话标识符都不再有效。
除非所有传输参数都由会话描述定义,否则必须在会话再次播放之前发出 SETUP 请求。
另外在DESCRIBE报文的回复报文中使用了SDP协议报文描述会话信息,在RTSP中,会话指的是客户端和服务器之间建立的一个连接,用于控制多媒体流的传输。这个连接通过一系列的RTSP请求和响应来维护,包括设置参数、播放、暂停、停止等操作。会话的关闭动作是客户端发送TEARDOWN报文发起的。
SETUP报文后会建立客户端与服务端的会话,如下Session字段,建立会话之后的报文都会把Session ID放到报文中
PLAY报文会上报请求播放的时间范围Range
PLAY的response报文会把时间戳和包序号回复过来如下图。seq:表示流的第一个数据包的序列号。 rtptime:表示Range响应头中时间值对应的RTP时间戳。
rtsp的实现
ffmpeg可以推流拉流,ffmpeg中有rtsp客户端的实现,zlmediakit中有rtsp服务端的实现,zlmediakit作为rtsp服务端能够接收客户端(如ffmpeg、VLC等)发送的RTSP请求,如播放、暂停、录制等,并处理这些请求,提供相应的流媒体数据。
rtsp服务端和客户端的代码分析待更新