Bootstrap

RTSP协议讲解

写在前面

目前正在学习RTSP协议,偶然间发现在这篇文章非常好,故转载学习使用:RTSP协议讲解

一、什么是RTSP协议?

RTSP是一个实时传输流协议,是一个应用层的协议

通常说的RTSP包括RTSP协议、RTP协议、RTCP协议

对于这些协议的作用简单的理解如下

RTSP协议:负责服务器与客户端之间的请求与响应

RTP协议:负责传输媒体数据

RTCP协议:在RTP传输过程中提供传输信息

rtsp承载与rtp和rtcp之上,rtsp并不会发送媒体数据,而是使用rtp协议传输

rtp并没有规定发送方式,可以选择udp发送或者tcp发送

二、RTSP协议详解

rtsp的交互过程就是客户端请求,服务器响应,下面看一看请求和响应的数据格式

2.1 RTSP数据格式

RTSP协议格式与HTTP协议格式类似

  • RTSP客户端的请求格式
method url vesion\r\n
CSeq: x\r\n
xxx\r\n
...
\r\n

method:方法,表明这次请求的方法,rtsp定义了很多方法,稍后介绍

url:格式一般为rtsp://ip:port/session,ip表主机ip,port表端口号,如果不写那么就是默认端口,rtsp的默认端口为554,session表明请求哪一个会话

version:表示rtsp的版本,现在为RTSP/1.0

CSeq:序列号,每个RTSP请求和响应都对应一个序列号,序列号是递增的
例如下面这个真实请求

OPTIONS rtsp://127.0.0.1:8554 RTSP/1.0
CSeq: 2
User-Agent: LibVLC/3.0.16 (LIVE555 Streaming Media v2016.11.28)

这里做如下对应
method -> OPTIONS 方法
url -> rtsp://127.0.0.1:8554
version -> RTSP/1.0
CSeq -> 2
User-Agent -> 这是VLC访问的请求头

  • RTSP服务端的响应格式
vesion 200 OK\r\n
CSeq: x\r\n
xxx\r\n
...
\r\n

version:表示rtsp的版本,现在为RTSP/1.0
CSeq:序列号,这个必须与对应请求的序列号相同
例如下面这个真实响应

RTSP/1.0 200 OK
CSeq: 2
Public: OPTIONS, DESCRIBE, SETUP, PLAY

这里做如下对应
vesion -> RTSP/1.0
CSeq -> 2
可以看出请求和相应的CSeq都是相同的2,\r\n是作为换行字符存在的,在解析时可以依据这一点进行通过格式解析。

2.2 RTSP请求的常用方法方法 描述

OPTIONS获取服务端提供的可用方法
DESCRIBE向服务端获取对应会话的媒体描述信息
SETUP向服务端发起建立请求,建立连接会话
PLAY向服务端发起播放请求
TEARDOWN向服务端发起关闭连接会话请求

2.3 RTSP交互过程

有了上述的知识,我们下面来讲解一个RTSP的交互过程

OPTIONS

  • C–>S
OPTIONS rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 2\r\n
\r\n

客户端向服务器请求可用方法

  • S–>C
RTSP/1.0 200 OK\r\n
CSeq: 2\r\n
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY\r\n
\r\n

服务端回复客户端,当前可用方法OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY

DESCRIBE

  • C–>S
DESCRIBE rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 3\r\n
Accept: application/sdp\r\n
\r\n

客户端向服务器请求媒体描述文件,格式为sdp

  • S–>C
RTSP/1.0 200 OK\r\n
CSeq: 3\r\n
Content-length: 146\r\n
Content-type: application/sdp\r\n
\r\n

v=0\r\n
o=- 91565340853 1 in IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

服务器回复了sdp文件,这个文件告诉客户端当前服务器有哪些音视频流,有什么属性,具体稍后再讲解

这里只需要直到客户端可以根据这些信息得知有哪些音视频流可以发送

SETUP

  • C–>S
SETUP rtsp://192.168.31.115:8554/live/track0 RTSP/1.0\r\n
CSeq: 4\r\n
Transport: RTP/AVP;unicast;client_port=54492-54493\r\n
\r\n

客户端发送建立请求,请求建立连接会话,准备接收音视频数据
解析一下Transport: RTP/AVP;unicast;client_port=54492-54493\r\n
RTP/AVP:表示RTP通过UDP发送,如果是RTP/AVP/TCP则表示RTP通过TCP发送

unicast:表示单播,如果是multicast则表示多播

client_port=54492-54493:由于这里希望采用的是RTP OVER UDP,所以客户端发送了两个用于传输数据的端口,客户端已经将这两个端口绑定到两个udp套接字上,54492表示是RTP端口,54493表示RTCP端口(RTP端口为某个偶数,RTCP端口为RTP端口+1)

  • S–>C
RTSP/1.0 200 OK\r\n
CSeq: 4\r\n
Transport: RTP/AVP;unicast;client_port=54492-54493;server_port=56400-56401\r\n
Session: 66334873\r\n
\r\n

服务端接收到请求之后,得知客户端要求采用RTP OVER UDP发送数据,单播,客户端用于传输RTP数据的端口为54492,RTCP的端口为54493
服务器也有两个udp套接字,绑定好两个端口,一个用于传输RTP,一个用于传输RTCP,这里的端口号为56400-56401

之后客户端会使用54492-54493这两端口和服务器通过udp传输数据,服务器会使用56400-56401这两端口和这个客户端传输数据

PLAY

  • C–>S
PLAY rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 5\r\n
Session: 66334873\r\n
Range: npt=0.000-\r\n
\r\n

客户端请求播放媒体

  • S–>C
RTSP/1.0 200 OK\r\n
CSeq: 5\r\n
Range: npt=0.000-\r\n
Session: 66334873; timeout=60\r\n
\r\n

TEARDOWN

  • C–>S
TEARDOWN rtsp://192.168.31.115:8554/live RTSP/1.0\r\n
CSeq: 6\r\n
Session: 66334873\r\n
\r\n
  • S–>C
RTSP/1.0 200 OK\r\n
CSeq: 6\r\n
\r\n

2.4 sdp格式

sdp格式由多行的type=value组成

sdp会话描述由一个会话级描述和多个媒体级描述组成。会话级描述的作用域是整个会话,媒体级描述描述的是一个视频流或者音频流

会话级描述由v=开始到第一个媒体级描述结束

媒体级描述由m=开始到下一个媒体级描述结束

下面是上面示例的sdp文件,我们就来好好分析一下这个sdp文件

v=0\r\n
o=- 91565340853 1 in IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

这个示例的sdp文件包含一个会话级描述和一个媒体级描述,分别如下

  • 会话级描述
v=0\r\n
o=- 91565340853 1 IN IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n

v=0
表示sdp的版本

o=- 91565340853 1 IN IP4 192.168.31.115
格式为 o=<用户名> <会话id> <会话版本> <网络类型><地址类型> <地址>
用户名:-
会话id:91565340853,表示rtsp://192.168.31.115:8554/live请求中的live这个会话
会话版本:1
网络类型:IN,表示internet
地址类型:IP4,表示ipv4
地址:192.168.31.115,表示服务器的地址

  • 媒体级描述
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

m=video 0 RTP/AVP 96\r\n

格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:video

端口号:0,为什么是0?因为上面在SETUP过程会告知端口号,所以这里就不需要了

传输协议:RTP/AVP,表示RTP OVER UDP,

如果是RTP/AVP/TCP,表示RTP OVER TCP
媒体格式:表示负载类型(payload type),一般使用96表示H.264

a=rtpmap:96 H264/90000
格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>

a=framerate:25
表示帧率

a=control:track0
表示这路视频流在这个会话中的编号

三、RTP协议

3.1 RTP包格式

rtp包由rtp头部和rtp荷载构成
rtp头部参考这篇文章:RTP头格式简介

  • RTP头部
    在这里插入图片描述
    RTP 报头中各字段的含义如下:
    版本(V):2 个比特,表示RTP 的版本号。
    填充(P):1 个比特,置“1”表示用户数据最后加有填充位,用户数据中最后一个字节是填充位计数,它表示一共加了多少个填充位。在两种情况下可能
    需要填充,一是某些加密算法要求数据块大小固定;二是在一个低层协议数据包中装载多个RTP 分组。
    扩展(X):1 个比特,置“1”表示RTP 报头后紧随一个扩展报头。
    CSRC 计数(CC):4 个比特,表示在定长的RTP 报头后的CSRC 标识符的 数量。
    标记(M):1 个比特,其具体解释由应用文档来定义。例如,对于视频流,它表示一帧的结束,而对于音频,则表示一次谈话的开始。
    载荷类别(PT):7 个比特,它指示在用户数据字段中承载数据的载荷类别。
    序号(SN):2 个字节,每发送一个RTP 数据包该序号增加1。该序号在接收方可用来发现丢失的数据包和对到来的数据包进行排序。
    时间戳(TS):4 个字节,它用来表示RTP 包中用户数据段的第一个字节的采样时刻。时间戳的时间表示应为线性单调递增的,以便完成同步实现和抖动的计算。
    同步源标识符(SSRC):4 个字节,用来标识一个同步源。此标识符是随机选择的,但要保证同一RTP 会话中的任意两个SSRC 各不相同,RTP 必须检测并解决冲突。
    提供源标识符(CSRC):它可有0~15 项标识符,每一项长度为32 比特,其项数由CC 字段来确定。如果提供源多于15 个,则只有15 个被标识。
    为了能满足各种应用的需要,RTP 报头可进一步扩充,其时X 比特将置“1”,扩充的RTP 报头部分则紧随在SCRC 清单之内。

RTP OVER TCP

RTP默认是采用UDP发送的,格式为RTP头+RTP载荷,如果是使用TCP,那么需要在RTP头之前再加上四个字节

第一个字节:$,辨识符

第二个字节:通道,在SETUP的过程中获取

第三第四个字节: RTP包的大小,最多只能12位,第三个字节保存高4位,第四个字节保存低8位

;