RTSP Spec中文版(1-11)
RTSP Spec中文版(12-16)
RTSP Spec中文版(附录)
附录A: RTSP协议状态机(RTSP Protocol State Machines)
RTSP客户端和服务器状态机描述了从RTSP会话初始化到结束的所有行为。
状态定义在每个对象的基础上,每个对象通过流URL和RTSP会话标识符进行唯一标识。任何使用聚合URL的请求/回复会作用于构成其呈现的所有流上。举个例子,如果呈现/movie中包含两个流,分别为/movie/audio和/movie/video,那么下列命令:
PLAY rtsp://foo.com/movie RTSP/1.0
CSeq: 559
Session: 12345678
会同时改变/movie/audio和/movie/video的状态。
请求方法中OPTIONS,ANNOUNCE,DESCRIBE,GET_PARAMETER,SET_PARAMETER对客户端或服务器状态并不会有任何影响,因此并未再状态表中列出。
A.1 客户端状态机(Client State Machine)
客户端会有如下状态:
-
Init
SETUP已发出,等待回复 -
Ready
已接收SETUP回复或播放中收到PAUSE回复 -
Playing
已接收PLAY回复 -
Recording
已接收RECORD回复
通常,客户端会在收到请求回复情况下改变状态。注意有些请求会在将来的某一时间或位置生效(如PAUSE),那么状态也会对应再发生改变。如果对象不需要显式SETUP(如多播组中可行的),状态从Ready开始。该情况下,只有两种有效状态,Ready和PLAYING。当请求中Range结尾点抵达后,客户端状态同样会从Playing/Recording切换至Ready。
“next state”栏表示收到成功回复(2xx)后将会切换至的目标状态。如果请求响应的是3xx的状态码,那么状态会切换至Init,而状态码4xx时不会做出任何改变。未列出的消息中,除了之前提到不会影响状态的消息,其他均不应该由该状态客户端发出。
*从服务器接收到REDIRECT等同于从服务器收到收到3xx重定向状态。 *
state | message sent | next state after response |
---|---|---|
Init | SETUP | Ready |
TEARDOWN | Init | |
Ready | PLAY | Playing |
RECORD | Recording | |
TEARDOWN | Init | |
SETUP | Ready | |
Playing | PAUSE | Ready |
TEARDOWN | Init | |
PLAY | Playing | |
SETUP | Playing(changed transport) | |
Recording | PAUSE | Ready |
TEARDOWN | Init | |
RECORD | Recording | |
SETUP | Recording(changed transport) |
A.2 服务器状态机(Server State Machine)
服务器有如下状态:
-
Init
初始化状态,未收到有效SETUP请求 -
Ready
完成上一次SETUP接收,已回复或在playing后回复;
完成上一次PAUSE接收,已回复 -
Playing
完成上一次PLAY接收,已回复,数据已发送 -
Recording
服务器正在录制媒体数据
通常来讲,服务器在接收请求后会改变状态。如果服务器处于单播模式的Playing或Recording状态时,如未收到健康信息(如定义好的从客户端以多少间隔发送的RTSP报告或RTSP命令,该间隔默认为1分钟),它可能回退到Init或退出RTSP会话。服务器可在会话回复头中修改延时值。如果服务器处于Ready状态,它可能会在指定间隔或超过一分钟内未收到RTSP请求后回退到Init。注意有些命令将在将来的某一时间或位置才生效,此时服务器会在合适时间转换状态。当请求中Range结尾点抵达后,服务器会从Playing或Recording状态切换为Ready状态。
发送REDIRECT消息后,将会立即生效,除非消息中带有Range头以指定生效时间。这种情况下,服务器状态也会在合适时间进行切换。
如果对象没有要求显式SETUP,那么状态从Ready开始,且只有两种有效状态:Ready和Playing。
“next state”栏表示收到成功回复(2xx)后将会切换至的目标状态。如果请求结果状态码为3xx,状态切换为Init。状态码为4xx的结果不会引起任何变化。
state | message received | next state |
---|---|---|
Init | SETUP | Ready |
TEARDOWN | Init | |
Ready | PLAY | Playing |
SETUP | Ready | |
TEARDOWN | Init | |
RECORD | Recording | |
Playing | PLAY | Playing |
PAUSE | Ready | |
TEARDOWN | Init | |
SETUP | Playing | |
Recording | RECORD | Recording |
PAUSE | Ready | |
TEARDOWN | Init | |
SETUP | Recording |
附录B:与RTP交互
RTSP允许媒体客户端控制选择的、非连续的媒体呈现块,并将这些流交给RTP媒体层处理。RTP流的媒体层处理不应受NPT跳跃的影响。也就是说,RTP序号和RTP时间戳都应该是连续的、单调递增的,即使跨越了非连续的NPT。
举个例子,假设一个时钟频率为8000Hz,分组间隔为100ms,初始序号和时间戳均为0。首先我们播放NPT 10至15,然后跳至18至20。第一段RTP分组中序号从0到49,时间戳则从0到39,200。第二段序号从50开始到69,时间戳从40,000到55,200。
我们不能假定RTSP客户端可以与RTP媒体代理沟通,因为两者可能是独立进程。如果RTP时间戳缺口和NPT一致,媒体代理会认定呈现中存在pause操作。如果NPT中的缺口足够大,RTP时间戳可能roll over,媒体代理会判定滞后的分组为已经播放过的副本。
对于具体数据类型,RTSP层和RTP层之间进行紧密联系可能是必需的。没有方法可以排除上下属限制,组合了RTSP/RTP媒体的客户端应使用RTP-Info域来决定收到的RTP分组是在seek前还是滞后发出的。
对于连续音频,服务器应当在新的PLAY请求中设置RTP标志位,从而允许客户端处理播放延时。
对于scaling(见12.34小节),RTP时间戳应当参照播放时间线。比如说,当以两倍速率播放一个30帧视频时,服务器每秒需要每隔一帧进行丢弃以按正常时间戳传送视频帧,但NPT仍然需以每视频帧1/15秒的幅度进行增加。
客户端可通过重组后的第一个到达的分组RTP时间戳值来达成在NPT的正确播放,RTP-Info中的序列号提供了下一个分段中的第一个分组序列号。
附录C: RTSP会话描述中SDP的使用
会话描述协议(SDP, Session Description Protocol)可能会在RTSP中用于描述流或呈现。使用场景仅限于为如下应用指定获取编码的方法:
-
聚合控制
呈现中的流来自不同服务器时将不支持聚合操作,这样的描述通常也是通过HTTP或其他非RTSP方法获取。当然,也可以通过ANNOUNCE方法获得。 -
非聚合操作
由同一服务器中的多个流组成的呈现支持聚合操作,这样的描述通常通过DESCRIBE URL请求获取,或者通过ANNOUNCE方法进行获取
该附录描述了SDP文件如何接收,例如,通过HTTP。SDP文件决定了RTSP会话的操作,它还描述了客户端如何解析DESCRIBE回复中的SDP内容。SDP未提供无需人参与情况下,客户端应如何在多个同时呈现的媒体流间进行区分的机制或是其他备选方案(如两个不同语言的音频流)。
C.1 定义(Definitions)
本文中涉及的“session-level”, "media-level"及其他key/attribute名称和值均定义于SDP(RFC 2327)中。
C.1.1 控制URL(ControlURL)
"a=control:"属性用于转换控制URL,该属性同时用于会话和媒体描述。如用于单独媒体,它表示控制特定媒体流的URL,如果在会话级别有该关键字,则表示URL用于聚合操作。
e.g.
a=control:rtsp://example.com/foo
该属性中可能包含相对或绝对URL,紧跟RFC 1808中定义的规则和约定。实现时应按如下顺序查找基础URL:
- RTSP Content-Base 域
- RTSP Content-Location 域
- RTSP request URL
如概述性只包含"*",则URL被视为空的嵌入式URL,即继承了整个base URL。
C.1.2 媒体流
“m=”域用于枚举媒体流,理想情况下所有指定流哦都会被合适同步处理。如果会话是单播,那么服务器提供给客户端的port值仅作为建议值,客户端仍然需要在SETUP请求中包含它,并有可能忽略该建议。如果服务器没有优先值,则应设置port值为0。
e.g.
m=audio 0 RTP/AVP 31
C.1.3 负载类型
负载类型在"m="域中指定,当负载类型是RFC 1890中的静态负载类型时,无需其他信息。而如果是一个动态负载类型,"rtpmap"中的 "encoding name"必须为RFC 1890中指定的属性之一,或是SDP中以“X-”作为前缀实验性编码方法。编码器相关的特定参数将在此处指定,而是在后面要讲到的"fmtp"属性中讨论。注册新编码方式时应遵循RFC 1890中的流程。如果媒体类型不适于任何RTP AV profile,那么推荐创建新的合适的profile,其名称需在"RTP/AVP"中"m="域内标明。
C.1.4 格式特定参数( Format-specific parameters)
格式特定的参数使用"fmtp"媒体属性进行传输,"fmtp"属性语法用于指定相关的编码方法。注意分组间隔通过"ptime"属性传递。
C.1.5 呈现范围(Range of presentation)
"a=range"属性定义了存储会话的总时间范围(活跃会话的长度可从"t"和"r"参数推导得出),除非呈现中包含了不同duration的媒体流,否则range属性是一个会话级别的属性。range单位需先指定,然后紧跟范围值。
e.g.
a=range:npt=0-34.4368
a=range:clock=19971113T2115-19971113T2203
C.1.6 可用时间(Time of availability)
"t="域中必须包含合适的值,以为聚合或非聚合流操作提供起止时间。
在聚合操作中,服务器应给出一个终止时间,该时间等于其可确保描述可用的时间;同时各处一个起始时间,该时间等于或小于接收到DESCRIBE请求的时间。如这两个值为0,则表示会话将一直有效。
在费聚合操作中,起止时间应能反映出会话可通过SDP语义,而不是依赖其他方式(如存有描述的网页生命周期)维持可用的实际时间周期。
C.1.7 连接信息(Connection Information)
在SDP中,"c="域中包含了媒体流的目标地址。对于点播(单播)流和一些多播流而言,目标地址是通过客户端的SETUP请求确定的。除非媒体内容有一个固定的目标地址,此时"c="域将被设置为合适的控制。如对于“IP4”类型该空值为"0.0.0.0"。
C.1.8 实体标签(Entity Tag)
可选的"a=etag"属性标识了会话描述的版本,它对于客户端是不透明的。SETUP请求中可能在"If-Match"域中包含该标识符,以只在版本匹配当前描述时建立会话。该属性值是不透明的,其中可能包含SDP属性值所允许的任何字符。
e.g.
a=etag:158bb3e7c7fd62ce67f12b533f06b83a
One could argue that the "o=" field provides identical
functionality. However, it does so in a manner that would put
constraints on servers that need to support multiple session
description types other than SDP for the same piece of media
content.
C.2 不支持聚合操作
如果一个呈现不支持聚合操作且已制定多个媒体段,每段必须通过"a=control:"属性制定其控制URL。
e.g.
v=0
o=- 2890844256 2890842807 IN IP4 204.34.34.32
s=I came from a web page
t=0 0
c=IN IP4 0.0.0.0
m=video 8002 RTP/AVP 31
a=control:rtsp://audio.com/movie.aud
m=audio 8004 RTP/AVP 3
a=control:rtsp://video.com/movie.vid
注意控制URL中的位置表示客户端向服务器audio.com和video.com分别建立独立的RTSP控制会话。
即使SDP文件通过非RTSP方式传给客户端时,也推荐其中包含所有媒体初始化信息。这在无法通知客户端需通过DESCRIBE进一步获取详细媒体流信息时非常有用。
C.3 支持聚合操作
在这种情况下,服务器上有可被作为整体控制的多个流。此时既有针对流URL的"a=control:"属性,也有支持聚合操作的向会话层的"a=control:"属性。如果媒体层(media-level)URL是相对URL,则应参照C.1.1小节转换为绝对URL。
如呈现仅有一个流组成,媒体层的"a=control:"属性会被同时省略,而当包含多个流时,每个媒体流段必须包含各自的"a=control"属性。
e.g.
v=0
o=- 2890844256 2890842807 IN IP4 204.34.34.32
s=I contain
i=<more info>
t=0 0
c=IN IP4 0.0.0.0
a=control:rtsp://example.com/movie/
m=video 8002 RTP/AVP 31
a=control:trackID=1
m=audio 8004 RTP/AVP 3
a=control:trackID=2
上面例子中,客户端向服务器请求建立一个简单RTSP会话,并使用URL "rtsp://example.com/movie/trackID=1"和"rtsp://example.com/movie/trackID=2"来设置音视频流,而URL "rtsp://example.com/movie/"则控制整个影片。
附录D: 极简RTSP实现
D.1 客户端
客户端实现必须支持如下功能:
- 生成如下请求:SETUP,TEARDOWN,PLAY/RECORD之一。如果实现了RECORD,则也必须实现ANNOUNCE
- 在请求中包含如下头:CSeq,Connection,Session,Transport。如果实现了ANNOUNCE,也必须支持Content-Language,Content-Encoding,Content-Length以及Content-Type也必须实现
- 解析并支持回复中的如下头:CSeq,Connection,Session,Transport,Content-Language,Content-Encoding,Content-Length,Content-Type。如果实现了录制,则Location也必须支持。RTP兼容的实现还必须实现RTP-Info
- 理解错误状态码类别并在状态码为4xx或5xx时通知用户。消息通知可配置,以避免用户不希望在出现哪些状态码时收到通知
- 回复来自服务器的异步请求,如ANNOUNCE。并不是说客户端就必须实现ANNOUNCE方法,而是说在收到服务器请求后,必须给出否定或肯定回复
尽管并非必须,如下内容也强烈建议实现以完整良好交互:
- 支持通过RTP/AVP/UDP传输
- 包含User-Agent头
- 理解附录C中的SDP会话描述
- 接收从标准输入、命令行或其他可行方式接收媒体初始化格式(如SDP)
D.1.1 Basic Playback
为了支持媒体流点播功能,客户端应添加如下支持:
- 生成PAUSE请求
- 实现REDIRECT方法,以及Location头
D.1.2 Authentication-enabled
为了实现在访问RTSP服务器上媒体呈现时需要认证,客户端必须添加如下支持:
- 识别401状态码
- 解析和包含 WWW-Authenticate头
- 实现Basic认证和Digest认证
D.2 服务器
一个最精简的服务器至少应当实现如下内容:
- 实现如下方法:SETUP,TEARDOWN,OPTIONS,PLAY或RECORD之一。如果实现了RECORD,ANNOUNCE也必须被实现
- 回复中包含如下头:Connection,Content-Length,Content-Type,Content-Language,Content-Encoding,Transport,Public。如实现了RECORD,则必须实现Location头。RTP兼容版本同时还需要实现RTP-Info域
- 解析并恰当地回复请求中的如下头:Connection,Session,Transport,Require
尽管并非必须,如下内容也强烈建议实现以完整良好交互:
- 支持RTP/AVP/UDP传输
- 包含Server头
- 实现DESCRIBE方法
- 生成附录C中定义的SDP会话描述
D.2.1 Basic Playback
为了支持媒体流点播,服务器必须额外支持如下内容:
- 识别Range头,并在seeking操作不支持时返回错误
- 实现PAUSE方法
此外,为了实现通用用户接口特性,强烈建议在点播媒体服务器上实现如下内容:
- 包含并解析NPT单位的Range参数,如有可能,支持SMPTE单位Range更佳
- 在媒体初始化信息中包含媒体呈现Length
- 支持从数据指定的时间戳映射为NPT。使用RTP时,RTP-Info域中的rtptime可能用于将RTP时间戳映射为NPT
客户端可能使用Length确定分段是否支持seek,并对不支持Length信息的分段在视觉效果上禁用seek特性。通常呈现长度会用于实现滑动条,一方面提供当前进度,另一方面提供时间位置信息。
从RTP时间戳映射至NPT在确保滑动条位置正确时是必需的。
D.2.2 Authentication-enabled
为了正确处理客户端认证,服务器必须额外添加如下实现:
- 当资源必须认证时生成401状态码
- 解析并包含WWW-Authenticate头
- 实现Basic认证和Digest认证
网友评论