RTSP+RTP协议浅析

一、概述

        RTSP(Real-time Steaming Protocol,实时流媒体协议)是由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准,编号RFC2326。RTSP是一个基于文本的应用层协议,其在流媒体传输过程中充当网络远程控制的角色,传输的是流媒体的播放控制信令,而把核心的流媒体数据交给RTP来传输

        IETF的多媒体传输工作小组在1996年发布了RFC 1889(旧版RTP),国际电信联盟ITU-T之后也发布了自己的RTP文档,最终编号RFC3550RTP协议是一个基于TCP/UDP的传输层协议,其为流媒体数据提供了具有实时特征的端对端传送服务,应用在组播或单播网络环境下的交互式音视频或流媒体系统中。

        由于RTP(Real-time Transport Protocol,实时传输协议)本身并不提供任何机制来确保及时交付或提供其他服务质量保证,也不假设底层网络是可靠的、按顺序发送数据包,所以在RFC3550修订版中,定义了RTCP(Real-time Transport Control Protocol,实时传输控制协议)这个子协议来监视RTP传输的服务质量,以便调整、控制传输过程。所以,为了提供可靠、高效地传送保障服务,通常需要RTP和RTCP协议一起配合使用

        文章中提到的一些协议在链路中的分布情况如下图:

二、RTSP

        RTSP提供了一个可扩展的框架,以支持控制、按需交付实时音视频数据。该协议旨在控制多个数据传输会话,提供了一种选择传输通道的方法,比如UDP、组播UDP、TCP,并且提供了一种基于RTP的选择传输机制。

        RTSP在功能上与HTTP有一些重叠。 它还可以与HTTP交互,因为与流内容的初次接触通常是通过一个网页进行的。 当前的协议规范旨在允许实现RTSP的web服务器和媒体服务器之间有不同的切换点。 例如,媒体流的信息可以使用HTTP或RTSP检索,这减少了基于web浏览器的场景中的往返,同时也允许完全不依赖HTTP的独立RTSP服务器和客户端。重用HTTP功能至少在两个方面有优势,即安全性和代理。 需求非常相似,因此能够在缓存、代理和身份验证上采用HTTP工作是很有价值的。

        RTSP有意在语法和操作上与HTTP/1.1相似,这样在大多数情况下,HTTP的扩展机制也可以添加到RTSP中。不过RTSP与HTTP还是存在一些不同点:

  • RTSP引入了一些新的请求方法和协议标识符;
  • RTSP服务器需要维护协议会话状态,即RTSP是一个有状态协议,而HTTP是一个无状态协议;
  • RTSP的客户端和服务端都可以发起请求,即请求是双向的,而HTTP是单向的,只能是客户端发送请求;
  • RTSP数据在传输层可以由不同协议传输,而HTTP通常基于TCP;
  • RTSP文本字符使用ISO 10646(UTF-8)而不是ISO 8859-1,并且使用了RFC3550
  • RTSP的请求URL是包含IP的绝对路径,而HTTP/1.1为了兼容低版本,将IP放在单独的HOST报头字段中。这种不同可以使得RTSP服务器的单个IP可以托管多个文件树,可应用虚拟主机;

        2.1、术语解释

  • Aggregate control(聚合控制):服务器使用单一时间轴控制多个流,即对于一个播放内容,可以通过一个PLAY或PAUSE请求,就可以完成对同一内容的多个媒体(视频、音频)流的播放控制;     
  • Conference(会议):一个客户端所请求播放的媒体内容的媒体描述、视频流、音频流可能会在不同的服务器,由这些多方服务器完成客户端的一次完整的RTSP会话时,这些服务器参与了一次会议;
  • Entity(实体):实体由实体报头字段形式的元信息和实体主体形式的内容组成,是请求或响应的有效负载所传输的信息;
  • Presentation description(媒体描述):演示文稿描述文件包含对组成演示文稿的媒体流的描述,包括它们的编码、语言和其他参数,这些参数使客户端能够选择最合适的媒体组合;
  • RTSP session(RTSP协议会话):RTSP控制一个可以通过独立于控制通道的独立协议发送的流。 例如,RTSP控制可能发生在TCP连接上,而数据流通过UDP。 因此,即使媒体服务器没有收到RTSP请求,数据传递也会继续。 此外,在其生命周期内,单个媒体流可能由不同TCP连接上顺序发出的RTSP请求控制。 因此,服务器需要维护“会话状态”,以便能够将RTSP请求与流关联起来。

        2.2、报文格式

请求报文格式
请求行请求方法URLRTSP版本CRLF
请求头头部字段:字段值CRLF
CRLF
请求体消息内容CRLF
响应报文格式
状态行RTSP版本状态码原因描述CRLF
响应头头部字段:字段值CRLF
CRLF
响应体响应内容CRLF

如上所示分别是RTSP请求报文和响应报文格式,其中:

  • 表格最左侧一列标注报文的不同部分,每一部分的结尾都会有个回车换行符(CRLF);
  • 和HTTP一样,RTSP的报文头部和数据主体之间也是以回车换行符分割;
  • 剩余的单元格表示以空格分割各个单元格中的内容;
  • 一般请求头和响应头会有多行头部字段和对应字段值的键值对;

        上面的格式描述可能有些抽象,如下图是IPTV工作场景中的实际RTSP报文,参照实际报文应该会好理解一些。图中红色部分是请求报文,蓝色部分是该请求对应的响应报文,马赛克隐去的是相关IP地址。

        其中红色部分的请求行中,请求方法是DESCRIBE,空格之后的URL看起来很长,但其实是同一行。RTSP的请求URL一般是以"rtsp://""rtspu://"起始,紧接着就是马赛克遮住的目标主机IP,紧挨着IP的冒号(":")后面跟随着端口号,端口号可以双方商定,也可以使用默认的554端口。端口号后面跟随着斜杠("/")分割的目标资源在目标主机上的相对路径,路径末尾的问号("?")后面跟随着符号("&")分割的实际业务参数键值对。最后,请求行末尾的"RTSP/1.0"表示使用的RTSP协议版本。

        请求行后面跟随着按行分割的请求头部字段键值对,图中的"CSeq"、"Accept"、"User-Agent"、"Timeshift"、"x-NAT"所在的行都是头部字段键值对。请求头和请求体之间以CRLF代表的空行分割,由于该请求报文未携带请求体,所以空行后面跟随的就是响应报文了。

        响应行的"RTSP/1.0"依然代表协议版本,之后空格分割的"200"和"OK"分别表示状态码和对应状态的原因描述。响应行后面的响应头部也是一行行头部字段键值对,响应头和响应体之间以CRLF代表的空行分割,响应体中的内容是以会话描述协议SDP表示的媒体信息,其基本格式说明如下(其中带星号*的是可选项):

        会话描述:

  • v=<version>  //指定协议版本号;
  • o=<username> <session id> <version> <network type> <address type> <address>  //Origin,指定媒体源服务器网络会话信息;
  • s=<session name> //会话名称;
  • i=*<session information>  //会话信息;
  • u=*<URI>  //统一资源标识符;
  • e=*<email address>  //邮件地址;
  • p=*<phone number> //手机号码;
  • c=*<network type> <address type> <connection address> //Connection,连接数据;
  • b=*<modifier>:<bandwidth-value>  //带宽信息;
  • z=*<adjustment time> <offset> <adjustment time> <offset>…  //时区调整;
  • k=*<method>:<encryption key>  //加密密钥;
  • a=*<attribute>/<attribute>:<value>  //附加属性行;

        时间描述:

  • t=<start time> <stop time>  //会话的起始和结束时间;
  • r=*<repeat interval> <active duration> <list of offsets from start- time>  //session的有效、持续、重复时间;

        媒体描述:

  • m=<media> <port> <transport> <fmt list> //第一个参数media可取值"audio"、"video"、"application"、"data"、“control”,第三个参数指定使用的传输协议,第四个参数指定媒体格式类型;

        2.3、请求方法

方法名请求方向操作对象选用限制
DESCRIBEC->SP,S推荐
ANNOUNCEC->S, S->CP,S可选
GET_PARAMETERC->S, S->CP,S可选
OPTIONSC->S, S->CP,S必选(S->C: 可选)
PAUSEC->SP,S推荐
PLAYC->SP,S必选
RECORDC->SP,S可选
REDIRECTS->CP,S可选
SETUPC->SS必选
SET_PARAMETERC->S, S->CP,S可选
TEARDOWNC->SP,S必选

        其中请求方法中的C代表客户端(Client),S代表服务端(Server),操作对象中的P代表媒体描述(Presentation),S代表媒体流(Stream)。上表中罗列对比了所有的请求方法,下面逐一来介绍一下。

        2.3.1、OPTIONS

        该请求可以在任何时刻发出,其一般用于获取服务器支持的请求方法,请求与响应举例如下:

C->S:   OPTIONS * 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

         2.3.2、DESCRIBE

        一般在RTSP会话起始阶段,会先发出DESCRIBE请求,即该请求往往最先发出。该请求用于从服务器检索URL标识的媒体内容或媒体对象的描述,请求报文中通过头部字段Accept来指定客户端可以理解的描述格式,服务器一般响应的是SDP描述的媒体资源信息,且该响应必须包含它所描述资源的所有媒体初始化信息。播放端获取媒体初始化信息的方式除了RTSP协议的DESCRIBE请求外,还有另外两种获取方式:1)、通过其他协议,比如HTTP、邮件协议;2)、通过命令行和标准输入;

C->S:   DESCRIBE rtsp://server.example.com/fizzle/foo RTSP/1.0
        CSeq: 312
        Accept: application/sdp, application/rtsl, application/mheg

S->C: RTSP/1.0 200 OK
        CSeq: 312
        Date: 23 Jan 1997 15:35:06 GMT
        Content-Type: application/sdp
        Content-Length: 376

        v=0
        o=mhandley 2890844526 2890842807 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
        e=mjh@isi.edu (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
        m=whiteboard 32416 UDP WB
        a=orient:portrait

         2.3.3、ANNOUNCE

        当该方法是从客户端发送到服务端时,会将URL标识的媒体对象的描述发送到服务器;当是从服务端发送到客户端时,该方法会更新会话描述;

C->S:   ANNOUNCE rtsp://server.example.com/fizzle/foo RTSP/1.0
        CSeq: 312
        Date: 23 Jan 1997 15:35:06 GMT
        Session: 47112344
        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
        e=mjh@isi.edu (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: 312

        2.3.4、SETUP

         SETUP请求用于指定流媒体的传输机制,请求报文头部的Transport字段指定客户端可接受的传输参数,响应报文则会通过Transport字段指定服务器所选择的传输参数。客户端可以对已经播放的流发出SETUP请求来改变传输参数,服务端如果不支持这样做,就需要响应"455 Method Not Valid In This State"错误。服务器响应时还会通过Session字段下发一个会话标识符以响应当前SETUP请求,但如果SETUP请求中携带了会话标识符,那么服务器就必须将这个设置请求绑定到现有的会话中,否则响应"459 Aggregate Operation Not Allowed"错误。

C->S:   SETUP rtsp://example.com/foo/bar/baz.rm RTSP/1.0
        CSeq: 302
        Transport: RTP/AVP;unicast;client_port=4588-4589

S->C:   RTSP/1.0 200 OK
        CSeq: 302
        Date: 23 Jan 1997 15:35:06 GMT
        Session: 47112344
        Transport: RTP/AVP;unicast;
        client_port=4588-4589;server_port=6256-6257

         2.3.5、PLAY

        客户端需要等SETUP请求响应成功后才能发送PLAY请求,PLAY请求用来告诉服务器开始使用SETUP响应报文中指定的传输方式开始传输数据。

        当PLAY请求头部携带Range字段时,该字段表示客户端所请求的媒体源的播放范围,该字段可以采用"npt=xxx-xxx"这样的取值格式,其中npt表示正常播放时间(normal play time),等号后面的取值为播放时间范围。服务器对于同一个客户端的多个PLAY请求需要通过队列方式按顺序处理,即在前一个PLAY请求仍然处于活动状态时,直到该请求结束前,后续来的PLAY请求都需要处于被延迟状态。比如如下所示的PLAY请求报文中,如果两个PLAY请求的Range字段的值分别取"npt=10-15"或"npt=20-25"时,那么无论这两个PLAY请求到达服务器的间隔有多近,服务器都将先播放10到15秒,然后再播放20到25秒。

C->S:   PLAY rtsp://audio.example.com/audio RTSP/1.0
        CSeq: 835
        Session: 12345678
        Range: npt=xxx-xxx

         Range字段的取值格式也可以是一个UTC时间参数,用于指定在这个时间开始播放,该格式也可以用来同步不同来源的媒体流。如果在这个时间之后收到消息,则应该立即开始播放。在下面的例子中,播放将从SMPTE时间=0:10:20开始播放,直到结束,回放将从1997年1月23日15时36分开始。

C->S:   PLAY rtsp://audio.example.com/twister.en RTSP/1.0
        CSeq: 833
        Session: 12345678
        Range: smpte=0:10:20-;time=19970123T153600Z

S->C:   RTSP/1.0 200 OK
        CSeq: 833
        Date: 23 Jan 1997 15:35:06 GMT
        Range: smpte=0:10:22-;time=19970123T153600Z

         为了能回放直播内容,可能需要如下所示的时钟单元格式:

C->S:   PLAY rtsp://audio.example.com/meeting.en RTSP/1.0
        CSeq: 835
        Session: 12345678
        Range: clock=19961108T142300Z-19961108T143520Z

S->C:   RTSP/1.0 200 OK
        CSeq: 835
        Date: 23 Jan 1997 15:35:06 GMT

        对于仅支持回放的媒体服务器,必须支持npt格式的Ranage字段值,可以选择支持UTC和SMPTE格式。无论Range字段值取的是什么格式,响应中的Range字段值应该和请求中是相同类型,且单位相同。当到达Range字段值的末尾时,播放将自动停止,就像发出了PAUSE请求一样。

        对于按需播放的媒体流请求, 服务器将用播放的实际范围进行响应。如果媒体源要求请求的范围与有效的帧边界对齐,那么响应可能与请求的范围不同;当PLAY请求头部没有携带Ranage字段时,此时表示将从媒体流的起始位置开始播放。这种场景下,如果一个媒体流正在播放,那么为了服务端的灵活性,同样的PLAY请求就不应该再触发更多的操作了。如果媒体流已通过PAUSE暂停,那么恢复时将从暂停点恢复传递媒体流。

        2.3.6、PAUSE

        如果PAUSE请求的URL指定了某一个具体的流,那么就只有这个流的播放和录制会被停止(比如只停掉视频中的音频流,视频仍在播放,只是没声音);如果PAUSE请求暂停的是一组流,那么该组中所有流的数据传输都将被暂停。在暂停后,只有当(SETUP请求中Session字段的timeout参数指定的)有效时间结束后,服务器才可以关闭会话,并释放资源。否则,服务器的会话和资源都应该保留。

C->S:   PAUSE rtsp://example.com/fizzle/foo RTSP/1.0
        CSeq: 834
        Session: 12345678

S->C:   RTSP/1.0 200 OK
        CSeq: 834
        Date: 23 Jan 1997 15:35:06 GMT

         PAUSE请求可以携带一个Range字段来指定什么时候停止播放,此时该字段取值必须是一个具体的时间点,而不是一个时间范围。当服务器在PLAY请求指定的时间范围内第一次遇到PAUSE请求指定的暂停时间点时,播放就会停止。如果暂停时间点超出了播放时间范围,则返回“457 Invalid Range”错误。

        PAUSE请求会丢弃暂停点之后的所有正在排队的PLAY请求,不过需要保持后续媒体流中的暂停点,后续没有携带Range头部字段的PLAY请求会从暂停点恢复播放。无论暂停点的位置和播放进度如何,恢复播放时PLAY请求都应该从暂停点开始恢复播放,这样才能确保连续的暂停/播放循环没有间隔。

        我们以某个媒体源10秒到20秒之间的播放为例,在服务器连续收到了10~14秒和16~20秒两个PLAY请求情况下,收到的是NPT 12秒的PAUSE请求,而播放只进行到11秒,那么就会在第12秒暂停,并丢弃第二个PLAY请求;如果收到的是NPT 12秒的PAUSE请求,而播放已经进行到了第13秒,那么播放立即停止;如果收到的是NPT 15秒的PAUSE请求,那么服务器在完成第一个PLAY请求后暂停,并丢弃第二个PLAY请求;如果收到的是NPT 17秒的PAUSE请求,那么会直接播放第二个范围并在第17秒的时候暂停;

        2.3.7、TEARDOWN

        TEARDOWN请求会停止指定媒体流的播放和流传输,并释放相关资源,并且与之相关的会话标识符将失效。

C->S:   TEARDOWN rtsp://example.com/fizzle/foo RTSP/1.0
        CSeq: 892
        Session: 12345678

S->C: RTSP/1.0 200 OK
        CSeq: 892

        2.3.8、GET_PARAMETER

        GET_PARAMETER请求用来获取URL指定流的参数值,响应内容由具体实现商定。

S->C:   GET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0
        CSeq: 431
        Content-Type: text/parameters
        Session: 12345678
        Content-Length: 15

        packets_received
        jitter

C->S:   RTSP/1.0 200 OK
        CSeq: 431
        Content-Length: 46
        Content-Type: text/parameters

        packets_received: 10
        jitter: 0.3838

        2.3.9、 SET_PARAMETER

        该请求用于为URL指定的流设置参数值,一个请求应该只能对一个参数进行设置。除非是原子设置,并且服务器必须在所有参数都能成功设置的情况下,才能对多个参数设置请求进行操作,因为其中的操作失败将难以排查。需要注意的是,媒体流的传输参数只能通过SETUP请求来设置,这样的限制是出于防火墙考虑。

C->S:   SET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0
        CSeq: 421
        Content-length: 20
        Content-type: text/parameters

        barparam: barstuff

S->C:   RTSP/1.0 451 Invalid Parameter
        CSeq: 421
        Content-length: 10
        Content-type: text/parameters

        barparam

        2.3.10、REDIRECT

        REDIRECT请求通知客户端必须连接到另外一个服务器地址,该请求头部强制包含Location字段,以表明客户端应该正确访问的URL地址。该请求头部也可以包含Range字段,以表明重定向生效的时间。客户端收到如下所示的重定向请求后,为了能正常播放目标媒体流,客户端需要先通过TEARDOWN请求终止"rtsp://example.com/fizzle/foo"这个URL会话,然后使用Location字段提供的新URL,通过SETUP请求建立新的会话。

S->C:   REDIRECT rtsp://example.com/fizzle/foo RTSP/1.0
        CSeq: 732
        Location: rtsp://bigserver.com:8001
        Range: clock=19960213T143205Z

        2.3.11、RECORD

        RECORD请求根据播放内容描述开始录制媒体数据,用时间戳表示录制开始和结束时间(UTC格式)。如果没有给时间范围,那么就用媒体描述中的开始和结束时间,如果会议已经开始,则立即开始录制。支持直播录制的媒体服务器必须支持时钟(clock)范围格式,smpte格式没有意义。

        服务器决定录制的数据存储在RECORD请求的URL还是另外一个URL,如果服务器不使用请求URL,响应应该是201 (Created),并包含一个描述请求状态和引用新资源的实体,以及一个Location头部字段。

C->S:   RECORD rtsp://example.com/meeting/audio.en RTSP/1.0
        CSeq: 954
        Session: 12345678
        Conference: 128.16.64.19/32492374

        2.4、头部字段

        如下表列出了所有的头部字段信息,其中类型列中的"请求"类型表示当前字段出现在请求报文中,"响应"类型出现在响应报文中,"通用"类型在请求和响应报文中都会出现,"实体"类型出现在消息体的实体报文中。支持列表示服务器对当前字段的支持情况,"可选"表示该字段可以选择性支持,"必须"表示必须支持该字段,但这并不意味着该字段一定要出现在报文中。

字段类型支持说明
Accept请求可选

指定客户端可以接受的响应报文中的内容描述类型,例如:

Accept: application/rtsl, application/sdp;level=2

Accept-Encoding请求可选可接受的编码格式;
Accept-Language请求可选可接受的编码语言,这里指的是响应报文中媒体描述信息和响应行的原因解释;
Allow响应可选

服务端支持的请求方法,例如:Allow: SETUP, PLAY, RECORD, SET_PARAMETER

Authorization请求可选用来上传认证信息;
Bandwidth请求可选指定客户端可用的带宽,单位为bps,例如:Bandwidth: 4000
Blocksize请求可选该字段取值为十进制,以字节为单位,用于向服务器请求特定大小的媒体包。服务器可以灵活响应低于该字段中指定大小的块,可以将包的大小截断为最接近该字段取值倍数的最小值,必要时对于特殊媒体可以覆盖该字段的值;
Cache-Control通用可选

        用于指定请求/响应链上所有缓存机制必须遵守的指令。因为指令可能适用于请求/响应链上的所有接收者,所以缓存指令必须通过代理或网关应用程序传递,即该字段应该只在SETUP请求和它的响应中指定。

        需要注意的是,Cache-Control不像HTTP那样控制响应体的缓存,而是控制由SETUP请求标识的媒体,除了对DESCRIBE的响应外,对RTSP其他请求的响应都是不可缓存的;

Conference请求可选

该请求报头字段在预先建立的会话和RTSP流之间建立了一个逻辑连接,该字段取值是会议ID(Conference -id),同一个RTSP会话不能修改Conference-id。例如:

Conference: 199702170042.SAA08642@obiwan.arl.wustl.edu%20Starr

Connection通用必须该字段主要用于控制长连接,取值有close和Keep-Alive;
Content-Encoding实体必须该字段会告知客户端服务器对实体的主体部分选用的内容编码方式,主要的取值有:gzip、compress、deflate、identity;
Content-Language实体必须该字段用于告知客户端实体主体使用的语言;
Content-Length实体必须与HTTP相比,该字段指定的仅是消息体的字节长度,不包含消息头;
Content-Location实体可选

与Location字段相比,该字段仅指定消息主体内容资源的URI,用于请求的URL和实际所访问的资源不一致的情况,比如一般HTTP请求某个网站首页,但实际访问的是首页URL后面跟随的index.html文件;

Content-Type实体必须指定实体主体内对象的媒体类型,类似Accept字段,但实际RTSP应用中该字段取值可能仅限于媒体描述和参数值类型;
CSeq通用必须该字段必须出现在所有的请求和响应头中,用于指定RTSP请求和响应对应的序列号。对于每个给定序列号的RTSP请求,将会有一个相同序列号的响应。任何重传请求必须包含与原始请求相同的序列号,即同一请求的重传序列号不递增;
Date通用可选指定当前报文创建的日期和时间;
Expires实体可选指定当前资源描述或媒体流的过期时间;
From请求可选指定服务器使用用户代理的用户的电子邮件地址;
If-Modified-Since请求可选在DESCRIBE和SETUP请求头部字段中,该字段指定一个时间,如果在该时间内服务器资源没有发生变化,那么下一个对同一资源的请求,服务器会响应没有消息体的"304 Not Modified",表示之前客户端或代理所拥有的资源依然有效;
Last-Modified实体可选指定服务器媒体描述和媒体流最后被修改的日期和时间;
Proxy-Require请求必须指定代理必须支持的特性,类似Require字段;
Range请求、响应可选指定了smpte、npt、clock这几种单位的时间范围,细节可以看2.3.5小节相关说明。注意是时间范围,而不是HTTP中的与之类似的字节范围;
Referer请求可选指定当前URL是从哪个地址跳转而来的;
Require请求必须该字段被客户端用来查询服务器可能支持或不支持的选项,服务器必须通过使用Unsupported报头来响应这个报头,以否定地确认那些不支持的选项;
Retry-After响应可选指定客户端应该在多久之后再次发送请求,主要配合503或3xx响应一起使用;
RTP-Info响应必须

该字段被用于在PLAY响应报文中设置RTP指定的参数,RTP-Info:url;seq|rtptime,eg:

RTP-Info:url=rtsp://foo.com/bar.avi/streamid=0;seq=45102,  

               url=rtsp://foo.com/bar.avi/streamid=1;seq=30211

Scale请求、响应可选指定媒体播放速度,取0.5时表示速度为正常播放速度的一半(即慢放),取1时表示正常播放,取2、4、8、16等正值时表示倍速播放,取负值时表示倒退播放;
Session请求、响应必须

        该字段标识了一个RTSP会话,该会话由媒体服务器在SETUP响应中启动,并在表示URL上以TEARDOWN结束,通常需要该字段来区分来自同一客户端相同URL的多个不同请求;

        该字段的timeout参数只能在响应头中使用,表示当前会话的有效持续时间,默认60秒,如果会话标识符过期无效,服务器应该响应"454 Session Not Found";

        需要注意的是会话标识符是跨传输会话和连接的,即多个RTSP URL的控制消息可以在单个RTSP会话中发送,因此只要所有的流都来自同一个服务器,客户端就有可能使用同一个会话来控制组成媒体的多个流。但是,来自同一客户端的同一个URL的多个“用户”会话必须使用不同的会话标识符;

Server响应可选用来告知客户端当前服务器上安装的RTSP服务器应用程序的信息;
Speed请求、响应可选指定数据流的传输速率,例如取2时表示正常传输速率的两倍,取0时无效;
Transport请求、响应必须

        该字段指示使用哪种传输协议,并为单个流配置传输参数,其所配置的是媒体描述尚未确定的参数,比如目标IP地址、目标端口、压缩、组播,这些参数用逗号分割,按优先级顺序排列;

        客户端SETUP请求携带该字段表明自身可以接受的传输参数列表,服务端SETUP响应会在该字段选择其中一种方式响应客户端,该字段也可以用来更改当前播放的传输参数;

Unsupported响应必须服务器使用该字段响应客户端不支持的Require字段特性;
User-Agent请求可选指定创建请求的浏览器和用户代理名称等信息;
Via通用可选报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发,是为了追踪客户端与服务器之间的请求和响应报文的传输路径,避免请求死循环;
WWW-Authenticate响应可选该字段用于 HTTP 访问认证,其会告知客户端适用于访问请求URI所指定资源的认证方案(Basic/Digest)和带参数提示的质询(challenge);

        其中Transport字段取值的语法格式如下图所示:

  •  其中"lower-transport"指定传输层的协议,取值TCP或UDP,默认UDP;
  • 组播(multicast)或单播(unicast)是指网络层的传输方式,默认是组播;
  • "destination"是指目标主机IP;
  • "interleaved"表示在控制流使用的协议中混合媒体流和控制流,其取值指定流中使用的通道号,比如interleaved=4-5;
  • "ttl"是指"multicast time-to-live";
  • "layers"指定媒体流的组播层数;
  • "port"为RTP/RTCP提供端口对,比如"port=3456-3457";
  • "ssrc"参数表示媒体服务器应该在请求或响应中使用的RTP ssrc值,用来确定要与媒体流相关联的同步源,该参数只对单播有效;
  • "mode"参数指定当前会话支持的方法,取值为"PLAY"或"RECORD",默认为"PLAY";
  • 如果"mode"参数取值为"RECORD",则"append"参数表示媒体数据应该附加到现有资源,而不是覆盖它。如果服务器不支持追加请求,就必须拒绝请求,而不是覆盖由URI标识的资源。如果mode参数不包含RECORD,则append参数将被忽略;

        2.5、响应码

状态码原因短句解释说明
1XXInformational信息性状态码,表示接收的请求正在处理;
100Continue客户端应当继续发送请求;
2XXSuccess成功状态码,表示请求正常处理完毕;
200OK从客户端发来的请求在服务端正常处理;
201Created服务器对RECORD请求的响应用的不是同一个URL时,会响应描述请求状态和引用新资源的实体,以及一个新的URL;
250Low on Storage Space服务器在收到RECORD请求,如果由于存储空间不足而可能无法完全满足该请求时返回此警告,如果可能的话,服务器应该使用Ranage字段来指示它还可以记录的时间段;
3XXRedirection重定向状态码,表示已完成请求但需要附加操作;
300Multiple Choices表示该请求具有多个可能的响应,用户代理或用户应该选择其中的一个;
301Moved Permanently永久重定向;
302Moved Temporarily临时重定向;
303See Other由于对应的资源存在着另一个uri,应定向获取请求的资源;
304Not Modified表示客户端或代理缓存的资源未修改,不需要重新传输请求的资源;
305Use Proxy被请求的资源必须通过指定的代理才能被访问,Location字段中将给出指定的代理所在的URI信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源,只有源服务器才能创建305响应;
4XXClient Error客户端错误状态码,表示服务器无法处理客户端请求;
400Bad Request请求报文中存在语法错误,客户端不应未经修改就重复此错误请求;
401Unauthorized发送的请求需要通过http认证(BASIC或DIGEST)的认证信息,如果前面已经请求过一次,说明认证失败;
402Payment Required非标准状态码,为了将来可能的需求而预留的;
403Forbidden请求资源的访问被服务器拒绝;
404Not Found服务器无法找到请求的资源;
405Method Not Allowed表示在当前使用的请求方法中不应该访问URL标识的资源,响应必须携带一个Allow头部字段,以包含能请求该资源的方法列表;
406Not Acceptable请求的资源的内容特性无法满足请求头中Accept-Language等字段条件,因而无法生成响应实体;
407Proxy Authentication Required与401响应码类似,只不过这里是缺少中间代理服务器的认证,代理服务器必须返回一个Proxy-Authenticate用以进行身份询问;
408Request Timeout请求超时,客户端没有在服务器预备等待的时间内完成一个请求的发送,服务器会在响应头部的Connection字段取值"close",代表将要关闭这个未使用的连接;
410Gone请求的资源在服务器上已经不再可用,而且没有任何已知的重定向地址;
411Length Required服务器拒绝在没有定义Content-Length头的情况下接受请求;
412Precondition Failed服务器在验证请求头部字段中给出的先决条件时,没能满足其中的一个或多个;
413Request Entity Too Large该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围,此种情况下,服务器可以关闭连接以免客户端继续发送此请求,如果这个状况是临时的,服务器应当返回一个 Retry-After 的响应头,以告知客户端可以在多少时间以后重新尝试;
414Request-URI Too Large请求的URL长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务;
415Unsupported Media Type请求中要求的媒体资源格式并不是服务器中所支持的格式;
451Parameter Not Understood请求的接收者不支持请求中包含的一个或多个参数;
452Conference Not Found请求中头部字段Conference标识的会议在服务器中未定义;
453Not Enough Bandwidth请求因为没有足够的带宽而被拒绝;
454Session Not Found请求中头部字段Session字段标识的会话标识符是错误的、或丢失的、或超时失效的;
455Method Not Valid in This State客户端或服务器无法在其当前状态下处理此请求;
456Header Field Not Valid for Resource服务器无法处理请求携带的头部字段;
457Invalid Range请求中给定的Range值超出了范围;
458Parameter Is Read-OnlySET_PARAMETER请求设置的参数只能读取,不能修改;
459Aggregate Operation Not Allowed请求的方法可能不会应用于对应URL,因为是一个聚合URL;
460Only Aggregate Operation Allowed请求的方法可能不会应用于对应URL,因为是一个聚合URL;
461Unsupported TransportTransport字段不包含能支持的传输方式;
462Destination Unreachable由于无法到达客户端地址,无法建立数据传输通道,该错误很可能是由于客户端试图在“Transport”字段中放置无效的“Destination”参数造成的;
5XXServer Error服务端错误状态码,表示服务器处理请求出错;
500Internal Server Error服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理;
501Not Implemented表示服务器无法识别请求的方法,并且无法支持其对任何资源的请求;
502Bad Gateway作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应;
503Service Unavailable由于临时的服务器维护或者过载,服务器当前无法处理请求,这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个Retry-After头用以标明这个延迟时间;如果没有给出这个 Retry-After 信息,那么客户端应当以处理500响应的方式处理它;
504Gateway Time-out作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器或辅助服务器(例如DNS)收到响应;
505RTSP Version not supported服务器不支持,或者拒绝支持在请求中使用的RTSP版本,响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体;
551Option not supported表示不支持Require或Proxy-Require字段中给出的选项,响应中应该返回Unsupported字段,说明不支持的选项;

        2.6、举例说明

C->W:   GET /twister.sdp HTTP/1.1
        Host: www.example.com
        Accept: application/sdp

W->C:   HTTP/1.0 200 OK
        Content-Type: application/sdp
        v=0
        o=- 2890844526 2890842807 IN IP4 192.16.24.202
        s=RTSP Session
        m=audio 0 RTP/AVP 0
        a=control:rtsp://audio.example.com/twister/audio.en
        m=video 0 RTP/AVP 31
        a=control:rtsp://video.example.com/twister/video

C->A:   SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0
        CSeq: 1
        Transport: RTP/AVP/UDP;unicast;client_port=3056-3057

A->C:   RTSP/1.0 200 OK
        CSeq: 1
        Session: 12345678
        Transport: RTP/AVP/UDP;unicast;client_port=3056-3057;
        server_port=5000-5001

C->V:   SETUP rtsp://video.example.com/twister/video RTSP/1.0
        CSeq: 1
        Transport: RTP/AVP/UDP;unicast;client_port=3058-3059

V->C:   RTSP/1.0 200 OK
        CSeq: 1
        Session: 23456789
        Transport: RTP/AVP/UDP;unicast;client_port=3058-3059;
        server_port=5002-5003

C->V:   PLAY rtsp://video.example.com/twister/video RTSP/1.0
        CSeq: 2
        Session: 23456789
        Range: smpte=0:10:00-

V->C:   RTSP/1.0 200 OK
        CSeq: 2
        Session: 23456789
        Range: smpte=0:10:00-0:20:00
        RTP-Info: url=rtsp://video.example.com/twister/video;seq=12312232;rtptime=78712811

C->A:   PLAY rtsp://audio.example.com/twister/audio.en RTSP/1.0
        CSeq: 2
        Session: 12345678
        Range: smpte=0:10:00-

A->C:   RTSP/1.0 200 OK
        CSeq: 2
        Session: 12345678
        Range: smpte=0:10:00-0:20:00
        RTP-Info: url=rtsp://audio.example.com/twister/audio.en;seq=876655;rtptime=1032181

C->A:   TEARDOWN rtsp://audio.example.com/twister/audio.en RTSP/1.0
        CSeq: 3
        Session: 12345678

A->C:   RTSP/1.0 200 OK
        CSeq: 3

C->V:   TEARDOWN rtsp://video.example.com/twister/video RTSP/1.0
        CSeq: 3
        Session: 23456789

V->C:   RTSP/1.0 200 OK
        CSeq: 3

        在如上的例子中客户端C要播放一部电影,该电影的音频部分存储在音频服务器A,视频部分存储在视频服务器V。电影的媒体描述信息存储在WEB服务器W,所以例子中媒体描述信息的获取由DESCRIBE方法改为了HTTP方式向WEB服务器请求。

        IPTV实际业务中常见的RTSP会话流程主要是DESCRIBE >> SETUP >> PLAY >> TEARDOWN,首先是通过DESCRIBE方法(也可以是其他协议或方式)获取媒体描述信息,然后通过SETUP请求确定媒体流传输参数,之后通过PLAY请求控制传输媒体流并开始播放,最终要结束播放时通过TEARDOWN请求结束该RTSP会话并释放相关资源。

三、RTP

        3.1、术语说明

        Mixer(混合器):从一个或多个媒体源接收RTP包的中继系统,这个混合器可能会改变数据格式,然后转发一个新的RTP包出去。由于多个媒体源之间的时序通常不会同步,而混合器可以在流之间进行时序调整,并为合并的流生成自己的时序,因而所有源自混合器的数据包将被认为有混合器作为它们的同步源。举一个可以使用混合器的例子,比如在一个城市中,大部分区的用户使用的网络环境良好、带宽高,而某一个区因为某些原因不得不使用低带宽网络,那么总不能因为这一个区的网络环境差,而让整个城市用户访问低码率、低质量的视频,所以便需要对这个区做单独处理,方法便是在这个区部署一个混合器,这个混合器将接收到的高码率音视频流转化为低码率并重新打包,使其能在低带宽网络环境下传输。另外一个例子就是音频会议,混合器接收到参加会议的每个人的音频流后,混音并重新打包组合成一个RTP包传输给每个与会者。

        Translator(翻译器):也是一个中继系统,但是只是完好无损的转发或转换,并不会更改源数据。依然举例音频会议,音频会议的一些与会者可能能连接到高带宽链路,但可能无法通过IP多播直接到达,例如,它们可能位于不允许任何IP包通过的应用程序级防火墙之后。在这种情况下,混合可能没有必要,但可以使用另一种称为翻译器的rtp级中继。即安装两个翻译程序,分别在防火墙的两边,它们可以安全连接通讯(即穿过防火墙),外部程序将接收到的所有组播数据包汇集在一起发送到内部程序,内部程序将它们作为组播包再次发送到内部网络。

        3.2、报文头部

        如下所示的两个表格分别是RTP报文头部格式表和字段解释表,前12个字节(即SSRC之前的,包括SSRC)的内容会出现在每个RTP报文头部,当使用混合器(mixer)时CSRC才会出现。

 RTP报文头部格式表
01234567890123456789012345678901
VPXCCMPTsequence number
timestamp
synchronization source (SSRC) identifier
contributing source (CSRC) identifiers
……
RTP报文头部字段解释表
字段大小(bit)说明
Version(V)2标识RTP版本,RFC3550版本该字段取值为2;
Padding(P)1填充标志位,置位时在RTP包的末尾会包含一个或多个额外填充字节,这些填充字节不属于有效负载,填充部分的最后一个字节说明了应该忽略多少填充的字节,包括它自己所在的字节;
Extension(X)1扩展标志位,置位时报头CSRC列表后面必须紧跟一个变长扩展报头;
CSRC Count(CC)4指定固定头部后面CSRC标识符的数量;
Marker(M)1标记标志位,置位时允许包含重要事件的标记,比如在数据流中包含帧边界标记;
Payload Type(PT)7指定RTP有效负载中媒体流的类型代码,类型代码到媒体格式的映射参考RFC3551
Sequence Number16处于安全考虑,序列号的初始值应该是随机的,每个RTP报文的RTP数据包递增1。客户端可以用序列号来检测丢包情况,以及对乱序数据包进行排序;
Timestamp32时间戳反应了RTP数据包中第一个字节的采样瞬间,和序列号一样,时间戳的初始值也应该是随机的;
Synchronization Source(SSRC)32

        取值为随机选择的同步源标识符,用来指定RTP包中流的源,以便不依赖网络地址。来自同一个同步源的所有数据包都属于相同时间和序列号空间的一部分,因此接收端根据同步源对数据包进行分组,以便播放;

        同步源的概念可以理解为一个能把信号源(比如麦克风、摄像机)产生的媒体流数据发送出去的推送者,如果一个参与者在一个RTP会话中产生多个流(比如有多个摄像头参与),那么每个都必须被标识为一个不同的SSRC;

        该字段的目的是在同一个RTP会话中没有两个同步源具有相同的SSRC标识符,尽管多个源选择相同SSRC标识符的概率很低,但所有的RTP实现都必须准备好检测和解决冲突,RFC3550中给出了生成随机标识符的实例算法,以及一种解决冲突和基于SSRC标识符唯一性检测rtp级别转发环路的机制;

Contributing Source(CSRC)32

        混合器产生的组合流一般由多个单一流组成,所以混合器将每个单一流的SSRC标识符插入到组合流所在的RTP包头中,组成CSRC列表。列表中单一流的数量由CC字段指定,因为CC字段只有4bit空间,所以CSRC列表的大小的取值空间就是0~15;

        举个音频会议的例子,混音器将所有讲话者的语音混合成一个音频流传输,此时CSRC列表中列出的就是每个讲话者的标识符;

        3.3、举例说明

        下面是一个实际RTP数据流,第一个字节"0x80"的二进制格式"1000 0000"包含了前四个字段的取值。字段Version所在的前两个比特"10"表示使用的RTP协议版本为2;字段Padding所在的第三个比特"0"表示当前RTP包末尾不包含填充字节;字段Extension所在的第四个字节"0"表示当前RTP包不包含扩展报头;字段CSRC Count所在的4~8比特"0000"表示当前RTP报文头部中的CSRC列表的大小为0;

        第二个字节"0x21"的二进制格式为"0010 0001",字段Marker所在第一个比特"0"表示当前RTP流中不包含特别标记,字段Payload Type所在的第2~8比特"010 0001"的十进制值为33,根据类型代码映射,表示当前RTP负载传输的媒体流封装格式为MPEG-2 TS;

        字段Sequence Number所在的第3~4两个字节"0x6e 52"表示当前RTP包的序列号为十进制的"28242";字段Timestamp所在的第5~8四个字节"0x78 63 9c 3a"表示时间戳为十进制2019793978;字段SSRC所在的第9~12四个字节"0x 00 00 00 00"未指出同步源;因为前面CSRC Count字段值为0,所以就不存在CSRC列表,之后便是负载传输的TS媒体流了。

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值