RTSP 消息 :
RTSP 是一种基于文本的协议,使用 UTF-8 编码的 ISO 10646 字符集(RFC 2279 [21])。行以 CRLF 作为结束符,但接收方也应该准备好将 CR 和 LF 单独作为行结束符进行解释。
基于文本的协议使得以自描述的方式添加可选参数变得更加容易。由于参数的数量和命令的频率较低,处理效率不是一个问题。基于文本的协议,如果设计得当,还可以轻松地使用诸如 Tcl、Visual Basic 和 Perl 等脚本语言实现研究原型。
10646 字符集避免了复杂的字符集切换,但只要使用 US-ASCII,它对应用程序是不可见的。这也是 RTCP 使用的编码。ISO 8859-1 可以直接转换为 Unicode,其高位字节为零。ISO 8859-1 中最高有效位为 1 的字符表示为 1100001x 10xxxxxx。(参见 RFC 2279 [21])
RTSP 消息可以通过任何 8 位透明的下层传输协议传输。请求包含方法、方法操作的对象以及进一步描述方法的参数。除非另有说明,方法是幂等的。方法的设计还旨在使媒体服务器几乎不需要或不需要进行状态维护。
下面的消息类型和和头部等介绍,有些地方是参考http协议的。
Message Types:
HTTP 消息由客户端向服务器发送的请求和服务器向客户端发送的响应组成。
HTTP-message = Request | Response ; HTTP/1.1 messages
请求(第5节)和响应(第6节)消息使用RFC 822 [9]的通用消息格式来传输实体(即消息的有效负载)。这两种类型的消息都包含一个起始行、零个或多个头字段(也称为“头部”)、一个空行(即,前面没有任何内容的CRLF行)以指示头字段的结束,并可能包含一个消息体。
generic-message = start-line *(message-header CRLF) CRLF [ message-body ] start-line = Request-Line | Status-Line
为了增强稳健性,服务器应当忽略在期望请求行的地方接收到的任何空行。换句话说,如果服务器在读取消息开头的协议流并首先接收到一个CRLF,它应忽略该CRLF。
某些存在漏洞的HTTP/1.0客户端实现会在POST请求后生成额外的CRLF。再次重申BNF明确禁止的内容,HTTP/1.1客户端不得在请求之前或之后添加额外的CRLF。
Message Headers:
HTTP头字段,包括通用头(第4.5节)、请求头(第5.3节)、响应头(第6.2节)和实体头(第7.1节)字段,遵循RFC 822 [9] 第3.1节中给出的通用格式。每个头字段由一个名称、一个冒号(“:”)和字段值组成。字段名称不区分大小写。字段值前可以有任意数量的线性空白(LWS),尽管建议使用一个空格(SP)。头字段可以通过在每行前添加至少一个空格(SP)或水平制表符(HT)来扩展到多行。在生成HTTP构造时,应用程序应遵循“常用格式”(如果已知或有指示),因为某些实现可能无法接受超出常用格式的内容。
message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content =
字段内容不包括任何前导或尾随的线性空白(LWS):即,出现在字段值第一个非空白字符之前或最后一个非空白字符之后的线性空白。这样的前导或尾随LWS可以被移除,而不会改变字段值的语义。字段内容之间出现的任何LWS可以在解释字段值或将消息向下传递之前替换为一个空格(SP)。
接收到不同字段名称的头字段的顺序无关紧要。然而,"良好的做法"是先发送通用头字段,然后是请求头或响应头字段,最后是实体头字段。
只有当整个字段值被定义为逗号分隔列表(即,#(values))时,消息中可以出现具有相同字段名称的多个消息头字段。通过将每个后续字段值用逗号分隔并附加到第一个字段值上,可以将多个头字段合并成一个“字段名:字段值”对,而不改变消息的语义。因此,接收到的具有相同字段名称的头字段的顺序对于合并字段值的解释是有意义的,因此代理在转发消息时不得更改这些字段值的顺序。
Message Body:
HTTP消息的消息体(如果有)用于携带与请求或响应关联的实体主体。只有在应用了传输编码时,消息体才不同于实体主体,这由传输编码头字段(第14.41节)指示。
message-body = entity-body |
传输编码必须用于指示应用程序为确保消息的安全和正确传输而应用的任何传输编码。传输编码是消息的属性,而不是实体的属性,因此可以由请求/响应链中的任何应用程序添加或删除。(不过,第3.6节对某些传输编码的使用时间进行了限制。)消息中允许消息体的规则在请求和响应中有所不同。
请求中是否包含消息体通过在消息头中包含Content-Length或Transfer-Encoding头字段来表明。如果请求方法的规范(第5.1.1节)不允许在请求中发送实体主体,则不得在请求中包含消息体。服务器应当读取并转发任何请求中的消息体;如果请求方法不包含实体主体的定义语义,则在处理请求时应当忽略消息体。
对于响应消息,是否包含消息体取决于请求方法和响应状态码(第6.1.1节)。所有对HEAD请求方法的响应不得包含消息体,尽管实体头字段的存在可能会让人误以为包含消息体。所有1xx(信息性)、204(无内容)和304(未修改)响应不得包含消息体。所有其他响应都包含消息体,尽管其长度可能为零。
message length:
当消息包含消息体时,其长度通过以下方法之一确定(按优先顺序排列):
-
任何不得包含消息体的响应消息(如1xx、204和304响应)总是在头字段后的第一个空行处终止,无论消息中是否存在实体头字段。(注意:空行仅包含CRLF。)
-
如果存在Content-Length头字段(第12.14节),其值(以字节为单位)表示消息体的长度。如果该头字段不存在,则假定长度为零。
-
通过服务器关闭连接来表示结束。(关闭连接不能用于指示请求体的结束,因为这样会导致服务器无法返回响应。)
需要注意的是,RTSP当前不支持HTTP/1.1的“chunked”传输编码(参见[H3.6]),并要求Content-Length头字段的存在。
由于返回的描述内容较短,服务器应始终能够确定其长度,即使是动态生成的内容,也无需使用chunked传输编码。尽管任何实体主体存在时Content-Length必须存在,以上规则确保了即使未明确给出长度时也能合理运作。
通用头字段 (General Header Fields) :
参见[H4.5],但不包括Pragma、Transfer-Encoding和Upgrade头字段,这些字段未定义:
general-header = Cache-Control ; | Connection ; | Date ; | Via ;
Request(请求):
从客户端到服务器(或反之)的请求消息在消息的第一行中包含要应用于资源的方法、资源的标识符以及正在使用的协议版本。
Request = Request-Line ; *( general-header ; | request-header ; | entity-header ) ; CRLF [ message-body ] ;
Request Line:
请求行的格式如下:
Request-Line = Method SP Request-URI SP RTSP-Version CRLF
-
Method:要应用于资源的请求方法。
-
SP:空格(Space)。
-
Request-URI:资源的标识符(URI)。
-
RTSP-Version:使用的协议版本。
-
CRLF:表示行的结束。
- extension-method = token
用于定义扩展方法,表示请求的自定义方法名称。
- Request-URI = "*" | absolute_URI
表示请求的URI,可以是通配符"*"或一个绝对URI(absolute_URI)。
- RTSP-Version = "RTSP" "/" 1DIGIT "." 1DIGIT
表示RTSP协议的版本号,其中“RTSP”后跟“/”,后面是一个或多个数字(表示主版本号),再接一个“.”,以及一个或多个数字(表示次版本号)。
Request Header Fields:
需要注意的是,与HTTP/1.1 [2]不同,RTSP请求始终包含完整的绝对URL(即包括协议、主机和端口),而不仅仅是绝对路径。HTTP/1.1要求服务器能够理解绝对URL,但客户端应使用Host请求头字段。这仅是为了与HTTP/1.0服务器的向后兼容,而这种考虑并不适用于RTSP。
在Request-URI中使用星号“*”表示该请求并不针对某个特定资源,而是针对服务器本身,并且仅在所用方法不一定适用于资源时才允许使用。例如:
OPTIONS * RTSP/1.0
Response(响应):
[H6]适用,但将HTTP-Version替换为RTSP-Version。此外,RTSP定义了额外的状态码,并且未定义部分HTTP状态码。有效的响应码及其可用于的请求方法在表1中定义。在接收到并解析请求消息后,接收方会以RTSP响应消息进行回复。
Status-Line(状态行):
响应消息的第一行是状态行(Status-Line),由协议版本、数值状态码和与该状态码相关的文本描述短语组成,每个元素之间用空格(SP)分隔。除了最后的CRLF序列外,不允许使用CR或LF字符。格式如下:
Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
-
RTSP-Version:使用的RTSP协议版本。
-
Status-Code:数值状态码,用于表示响应结果。
-
Reason-Phrase:状态码的文本描述,用于解释状态码的含义。
-
CRLF:表示行的结束。
状态码(Status Code)和原因短语(Reason Phrase)
状态码(Status-Code)元素是一个三位数整数,用于表示对请求的理解和处理结果。这些代码在第11节中有详细定义。原因短语(Reason-Phrase)用于对状态码进行简短的文本描述。状态码主要供自动程序使用,而原因短语供人类用户参考。客户端不要求检查或显示原因短语。状态码的首位数字表示响应的类别,后两位数字则没有分类作用。首位数字有五种可能的值:
-
1xx:信息性 - 请求已接收,正在继续处理。
-
2xx:成功 - 操作已成功接收、理解并接受。
-
3xx:重定向 - 需要进一步操作以完成请求。
-
4xx:客户端错误 - 请求包含错误语法或无法满足。
-
5xx:服务器错误 - 服务器无法满足明显有效的请求。
以下是为RTSP/1.0定义的数值状态码及其对应的原因短语示例。这里列出的原因短语只是推荐内容——可以替换为本地等效短语而不影响协议。注意,RTSP采用了大部分HTTP/1.1状态码,并添加了从x50开始的RTSP特定状态码,以避免与新定义的HTTP状态码冲突。
Response Header Fields(响应头字段):
响应头字段允许请求的接收方传递有关响应的附加信息,这些信息无法放在状态行中。这些头字段提供有关服务器的信息以及进一步访问由Request-URI标识的资源的信息。
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
响应头字段名称只有在协议版本更改的情况下才能可靠地扩展。然而,如果通信中的所有各方都将新的或实验性的头字段视为响应头字段,则可以赋予它们响应头字段的语义。未识别的头字段将被视为实体头字段。
Entity(实体):
请求和响应消息可以传输一个实体,但前提是请求方法或响应状态码没有对此进行限制。一个实体由实体头字段和实体主体组成,但某些响应可能只包含实体头字段而不包含实体主体。在本节中,发送方和接收方可以指客户端或服务器,具体取决于谁发送和接收实体。
Entity Header Fields:
实体头字段定义了关于实体主体的可选元信息,或者在没有主体的情况下,定义了关于请求标识的资源的元信息。
扩展头机制允许在不更改协议的情况下定义额外的实体头字段,但不能假设接收方能识别这些字段。接收方应当忽略未识别的头字段,且代理应转发这些字段。
Entity Body:
通过HTTP请求或响应发送的实体主体(如果有)采用由实体头字段定义的格式和编码。
entity-body = *OCTET
实体主体仅在消息包含消息体时存在,如第4.3节所述。实体主体通过对消息体进行解码以移除任何已应用的传输编码(Transfer-Encoding)获得,以确保消息安全、正确地传输。
Connections(连接):
RTSP请求可以通过以下几种方式进行传输:
-
使用持久传输连接来处理多个请求-响应事务;
-
每个请求/响应事务使用一个连接;
-
无连接模式。
传输连接的类型由RTSP URI定义(第3.2节)。对于“rtsp”方案,假设使用持久连接,而“rtspu”方案则要求在不建立连接的情况下发送RTSP请求。
与HTTP不同,RTSP允许媒体服务器向媒体客户端发送请求。然而,这仅在持久连接中受支持,因为在其他情况下媒体服务器无法可靠地联系客户端。此外,媒体服务器向客户端发送请求的方式也是穿越防火墙的唯一可行途径。
Pipelining(管道化)
支持持久连接或无连接模式的客户端可以“管道化”其请求(即,在未等待每个响应的情况下发送多个请求)。服务器必须按照接收到请求的顺序发送这些请求的响应。
在RTSP中,管道化允许客户端在不等待前一个请求完成的情况下,连续发送多个请求,从而提高传输效率。这使得多个请求可以同时进行处理和传输,减少了往返延迟(RTT)。
与HTTP管道化类似,RTSP的管道化可以在持久连接上实现,但要求服务器按照请求的顺序发送响应,以避免客户端对响应的混淆。
可靠性和确认(Reliability and Acknowledgements):
请求通常会得到接收方的确认,除非它们被发送到多播组。如果没有确认,发送方可以在一个往返时间(RTT)后重新发送相同的消息。RTT的估计方法与TCP(RFC 1123)一致,初始值为500毫秒。实现中可以缓存上次测量的RTT值作为未来连接的初始值。
如果使用可靠的传输协议(如TCP)来传输RTSP,请求不得重传;RTSP应用程序应依赖底层传输协议来提供可靠性。
- 如果底层的可靠传输协议(如TCP)和RTSP应用程序都进行请求重传,每次丢包可能导致双重重传。接收方通常无法利用应用层的重传,因为传输栈不会在第一次尝试到达之前递送应用层的重传。如果丢包是由于拥塞引起的,不同层级的多次重传会加剧拥塞。
- 在小RTT的局域网中使用RTSP时,可采用T/TCP(RFC 1644)等方法来优化TCP初始RTT估计。
Timestamp头(第12.38节)用于避免重传歧义问题,无需使用Karn算法。每个请求在CSeq头(第12.17节)中携带一个序列号,每发送一个新的请求,此序列号递增1。若因缺乏确认而重发请求,该请求必须携带原始序列号(即,不增加序列号)。
实现RTSP的系统必须支持通过TCP传输RTSP,可以支持UDP。RTSP服务器的默认端口在UDP和TCP上均为554。
多个发往同一控制端点的RTSP数据包可以打包在一个较低层的PDU中或封装到TCP流中。RTSP数据可以与RTP和RTCP数据包交错传输。与HTTP不同的是,每当RTSP消息包含负载时,消息必须包含Content-Length头。否则,RTSP消息在最后一个消息头之后的空行处终止。
Method Definitions:
方法令牌表示要在Request-URI标识的资源上执行的操作。方法名区分大小写,并且未来可能定义新的方法。方法名称不得以“$”字符(十进制24)开头,且必须为一个令牌。以下是方法的概述(见表2):
表2:RTSP方法概述、方向及操作的对象(P:表示,S:流) 表2备注:PAUSE是推荐的,但并非必需,例如,对于直播流,完全可以构建一个不支持该方法的服务器。如果服务器不支持某个特定方法,它必须返回“501 未实现”,客户端应当避免再次尝试该方法。
OPTIONS:
该行为等同于[H9.2]中描述的内容。可以在任何时候发出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
请注意,这些特性是虚构的(希望我们不会故意忽略真正有用的特性,只是为了在本节中提供一个有力的示例)。
DESCRIBE:
DESCRIBE方法用于从服务器检索由请求URL标识的展示或媒体对象的描述。可以使用Accept头来指定客户端支持的描述格式。服务器将返回请求资源的描述。DESCRIBE请求-响应对构成RTSP的媒体初始化阶段。
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
DESCRIBE响应必须包含其描述的资源的所有媒体初始化信息。如果媒体客户端从其他来源(如HTTP或电子邮件附件)获取了完整的媒体初始化参数,则应当使用这些参数,不需要再通过RTSP请求相同媒体的描述。
此外,服务器不应使用DESCRIBE响应作为媒体间接引用的手段。
为了确保客户端清楚何时通过DESCRIBE请求媒体初始化信息,DESCRIBE响应应包含描述的所有流的媒体初始化信息,且不建议将DESCRIBE用于媒体间接引用。这避免了其他方法可能导致的循环问题。
媒体初始化是任何基于RTSP的系统的要求,但RTSP规范并未强制要求使用DESCRIBE方法来实现这一点。RTSP客户端可以通过以下三种方式接收初始化信息:
-
使用RTSP的DESCRIBE方法;
-
通过其他协议(如HTTP或电子邮件附件);
-
通过命令行或标准输入(例如,作为浏览器辅助应用程序,用SDP文件或其他媒体初始化格式启动)。
为实现实际的互操作性,建议最基本的服务器支持DESCRIBE方法,并建议基本的客户端支持作为“辅助应用程序”的功能,即通过标准输入、命令行或客户端操作环境中的其他合适方式接受媒体初始化文件。
ANNOUNCE:
ANNOUNCE方法具有两个用途:
-
客户端到服务器:当从客户端发送到服务器时,ANNOUNCE将请求URL标识的展示或媒体对象的描述发送到服务器。
-
服务器到客户端:当从服务器发送到客户端时,ANNOUNCE实时更新会话描述。
如果在展示中添加了新的媒体流(例如,在直播展示期间),应重新发送整个展示描述,而不仅仅是附加的部分,以便可以删除已存在的组件。
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
此示例中,客户端将媒体描述发送到服务器,服务器回复“200 OK”确认接收。
SETUP:
SETUP请求用于指定URI的流媒体传输机制。客户端可以针对正在播放的流发出SETUP请求以更改传输参数,服务器可以允许这种更改;如果不允许,则必须返回“455 方法在此状态无效”错误。为了有利于任何中间防火墙,客户端必须指明传输参数,即使这些参数不可更改,例如当服务器指定了一个固定的多播地址时。
由于SETUP包含所有的传输初始化信息,防火墙和其他需要这些信息的中间网络设备无需执行复杂的DESCRIBE响应解析任务,DESCRIBE响应仅用于媒体初始化。
Transport头指定客户端可接受的数据传输参数;服务器响应中将包含其选择的传输参数。
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
服务器会在响应SETUP请求时生成会话标识符。如果SETUP请求包含会话标识符,服务器必须将该请求合并到现有会话中,或者返回“459 聚合操作不允许”错误(参见第11.3.10节)。
PLAY:
PLAY方法用于告诉服务器根据SETUP中指定的机制开始发送数据。在所有待处理的SETUP请求被确认成功之前,客户端不得发出PLAY请求。
PLAY请求将常规播放时间设置为指定范围的开始,并传输流数据直到达到范围的结束。PLAY请求可以进行管道化(队列化);服务器必须按顺序执行PLAY请求。如果在之前的PLAY请求仍处于活动状态时接收到新PLAY请求,则会将其延迟至第一个请求完成。
这样可以实现精确的编辑。例如,无论下面的两个PLAY请求到达的间隔多短,服务器将先播放第10至15秒,然后紧接播放第20至25秒,最后播放第30秒至结束。
C->S: PLAY rtsp://audio.example.com/audio RTSP/1.0 CSeq: 835 Session: 12345678 Range: npt=10-15 C->S: PLAY rtsp://audio.example.com/audio RTSP/1.0 CSeq: 836 Session: 12345678 Range: npt=20-25 C->S: PLAY rtsp://audio.example.com/audio RTSP/1.0 CSeq: 837 Session: 12345678 Range: npt=30-
请参见PAUSE请求的描述获取更多示例。
-
无Range头的PLAY请求:合法,会从开头开始播放,除非流已暂停。若流通过PAUSE暂停,则从暂停点恢复播放。如果流正在播放,则此类PLAY请求无进一步操作,客户端可以用来测试服务器是否存活。
-
Range头的time参数:指定UTC时间的播放开始时间,若在指定时间后接收到消息,立即开始播放。time参数可用于同步来自不同来源的流。
对于点播流,服务器返回实际播放的范围。如果需要将请求的范围对齐到有效的帧边界,这个范围可能会与请求范围不同。如果请求中未指定范围,回复中返回当前的位置。回复中的范围单位与请求中的相同。
播放指定范围后,展示会自动暂停,就如同发出了PAUSE请求一样。
以下示例从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格式,可以支持clock和smpte格式。
PAUSE:
PAUSE请求用于临时中断流的传输(暂停)。如果请求URL指定的是单个流,则仅该流的播放或录制会被暂停。例如,对于音频流,这相当于静音。如果请求URL指定的是一个展示或流组,则该展示或组中的所有当前活动流都会被暂停。在恢复播放或录制后,轨道的同步必须得到保持。服务器会保留资源,但在暂停超过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头,指定流或展示的暂停时间点(称为“暂停点”)。Range头必须包含一个时间值而非时间范围。流的正常播放时间设定为暂停点。如果在当前挂起的任何PLAY请求中遇到此时间点,PAUSE请求生效。如果Range头指定了超出当前PLAY请求范围的时间,则返回“457 无效范围”错误。若某一媒体单元(如音频或视频帧)恰好在暂停点开始展示,则不会播放或录制。若Range头缺失,则接收到消息后立即暂停,并将暂停点设为当前正常播放时间。
PAUSE请求会清除所有排队的PLAY请求,但必须保持媒体流中的暂停点。随后无Range头的PLAY请求将从暂停点恢复。例如,如果服务器有10到15和20到29的播放请求,随后收到NPT 21的PAUSE请求,则会开始播放第二个范围并在NPT 21暂停。若PAUSE请求为NPT 12,而服务器正在NPT 13播放第一个请求范围,则立即停止播放。若PAUSE请求为NPT 16,服务器将在完成第一个播放请求后暂停,并丢弃第二个播放请求。
在另一个示例中,如果服务器收到播放范围10到15和13到20的请求(即重叠范围),则NPT=14的PAUSE请求会在服务器播放第一个范围时生效,第二个PLAY请求被忽略(假设PAUSE请求在服务器开始播放第二个范围之前到达)。无论PAUSE请求何时到达,都会将NPT设置为14。
如果服务器已经发送了超出Range头指定时间的数据,PLAY请求将会从该时间点继续播放,因为假设客户端已丢弃该点之后的数据。这确保了暂停/播放循环之间没有间隔。
TEARDOWN:
TEARDOWN请求用于停止给定URI的流传输,并释放与之相关的资源。如果URI是该展示的展示URI,则与会话相关的任何RTSP会话标识符将不再有效。除非会话描述中定义了所有传输参数,否则在会话可以再次播放之前,需要发出SETUP请求。
C->S: TEARDOWN rtsp://example.com/fizzle/foo RTSP/1.0 CSeq: 892 Session: 12345678 S->C: RTSP/1.0 200 OK CSeq: 892
GET_PARAMETER:
GET_PARAMETER请求用于检索指定URI的展示或流的参数值。回复内容和响应内容由实现决定。没有实体主体的GET_PARAMETER请求可用于测试客户端或服务器的存活状态("ping")。
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
其中,text/parameters是参数的示例类型。此方法特意定义得较为宽泛,以便在进一步实验后明确回复和响应的内容。
SET_PARAMETER:
SET_PARAMETER方法用于设置指定URI的展示或流的参数值。
请求应当只包含一个参数,以便客户端能明确判断特定请求失败的原因。如果请求包含多个参数,则服务器必须仅在所有参数都能成功设置的情况下才执行该请求。服务器必须允许参数重复设置相同值,但可以禁止更改参数值。
注意:媒体流的传输参数只能使用SETUP命令进行设置。
将传输参数的设置限制在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
text/parameters部分仅为参数的示例类型。此方法定义较宽泛,以便在进一步实验后明确回复和响应内容。
REDIRECT:
REDIRECT请求用于通知客户端必须连接到另一个服务器位置。该请求包含必需的Location头,指示客户端应向该URL发出请求。它还可以包含Range参数,指示重定向生效的时间点。如果客户端希望继续发送或接收此URI的媒体,必须为当前会话发出TEARDOWN请求,并在指定主机上为新会话发出SETUP请求。
示例请求将此URI的流量重定向到指定播放时间的新服务器:
S->C: REDIRECT rtsp://example.com/fizzle/foo RTSP/1.0 CSeq: 732 Location: rtsp://bigserver.com:8001 Range: clock=19960213T143205Z-
RECORD:
RECORD方法用于根据展示描述录制一段媒体数据。时间戳表示开始和结束时间(UTC)。如果未提供时间范围,则使用展示描述中给出的开始或结束时间。如果会话已开始,则立即开始录制。
服务器决定是将录制的数据存储在请求URI下还是另一个URI下。如果服务器未使用请求URI,响应应当返回201(Created),并包含描述请求状态和指向新资源的实体,以及Location头。
支持直播展示录制的媒体服务器必须支持时钟范围格式;smpte格式不适用。
示例中,媒体服务器此前已被邀请参加指定的会议。
C->S: RECORD rtsp://example.com/meeting/audio.en RTSP/1.0 CSeq: 954 Session: 12345678 Conference: 128.16.64.19/32492374
Embedded (Interleaved) Binary Data:
某些防火墙设计及其他情况可能会强制服务器在RTSP方法和流数据之间进行交错。除非必要,应避免这种交错操作,因为它会增加客户端和服务器的操作复杂性及额外的开销。仅在RTSP通过TCP传输时应当使用交错的二进制数据。
流数据(例如RTP数据包)通过一个ASCII美元符号(十六进制24)封装,接着是一个字节的通道标识符,然后是封装的二进制数据的长度(以网络字节顺序表示的两个字节整数)。流数据紧随其后,没有CRLF,但包含上层协议头。每个“$”块包含一个完整的上层协议数据单元,例如一个RTP数据包。通道标识符在Transport头中通过interleaved参数定义(第12.39节)。
当选择RTP作为传输时,RTCP消息也会通过TCP连接由服务器交错传输。默认情况下,RTCP数据包发送到比RTP通道高的第一个可用通道。客户端可以在Transport头的interleaved参数中指定两个通道,以显式请求在另一个通道上接收RTCP数据包。
RTCP用于当两个或更多流以这种方式交错时的同步。这还提供了一种便捷的方法,可以在网络配置要求时通过TCP控制连接隧道传输RTP/RTCP数据包,并在可能时将其转发到UDP。
C->S: SETUP rtsp://foo.com/bar.file RTSP/1.0 CSeq: 2 Transport: RTP/AVP/TCP;interleaved=0-1 S->C: RTSP/1.0 200 OK CSeq: 2 Date: 05 Jun 1997 18:57:18 GMT Transport: RTP/AVP/TCP;interleaved=0-1 Session: 12345678 C->S: PLAY rtsp://foo.com/bar.file RTSP/1.0 CSeq: 3 Session: 12345678 S->C: RTSP/1.0 200 OK CSeq: 3 Session: 12345678 Date: 05 Jun 1997 18:59:15 GMT RTP-Info: url=rtsp://foo.com/bar.file; seq=232433;rtptime=972948234 S->C: $\000{2字节长度}{"长度"字节的数据,包含RTP头} S->C: $\000{2字节长度}{"长度"字节的数据,包含RTP头} S->C: $\001{2字节长度}{"长度"字节的RTCP数据包}
在示例中,交错传输的RTP数据使用“$”符号表示通道标识符和数据长度,每个块包含一个完整的数据包。