SDP(Session Description Protocol)是为了描述多媒体会话而设计的,主要用来描述会话通告,会话邀请或者其他形式的多媒体会话初始化。为了初始化多媒体会话,需要对参与者提供媒体信息、传输地址以及其他与会话有的描述性的源数据,SDP为了描述这些信息提供了一个标准的形式。SDP只是一个单纯的会话描述的格式,他并不包括传输协议,在不同的场合SDP可以应用于不同的传输协议,如SIP,RTP等等;在网络流媒体中,常见于SIP和RTSP使用SDP描述。一般来说,SDP会话描述包含以下基本内容:
一个SDP会话描述是通过“application/sdp”来标识的,SDP会话采用UTF8编码,一个SDP会话描述一般包括如下若干行文本形式:
<type>=<value>
其中,type是一个区分大小写的字母的形式,value是一个结构化的文本,其形式取决于type,通常,value是由若干分隔符分开的字段组成,或者是一个字符串,其中“=”两边都不能有空格。一个SDP包含一个会话层部分,后续跟0个或者多个媒体层部分,会话起始于“v=”行,直到第一个媒体层部分。每个媒体层起始于“m=”行,直到下一个媒体层的开始或者直到SDP结束,通常,会话层的属性是全局的,除非媒体层被重写。
SDP会话某些行是必选的,某些行是可选的,但是出现的顺序必须如下所示,可以行用 * 标识。
会话描述:
v= (协议版本)
o= (会话标识符)
s= (会话名称)
i=* (会话信息)
u=* (URI标识)
e=* (邮箱地址)
p=* (电话号码)
c=* (连接信息,)
b=* (带宽信息)
z=* (时域调整)
k=* (加密秘钥)
a=* (0个或者多个会话属性)
时间描述:
t= (会话有效时间)
r=* (0个或者多个重复时间)
媒体描述:
m= (媒体名字和传输地址)
i=* (媒体标题)
c=* (连接信息)
b=* (带宽信息)
k=* (加密秘钥)
a=* (媒体属性)
注意:
<type>的字母为小写字母并且不可扩展,SDP解析器如果碰到不认识的<type>,必须忽略它,属性机制(“a=”)是SDP扩展的主要手段。某些属性是已经被定义好的,而另外的则是在特定应用、媒体格式规范中才进行定义。SDP解析器必须忽略它不认识的属性。
下面对SDP协议各个字段详细介绍:
v=0
"v="字段给出了SDP的版本,当前规范的版本是0,这个版本没有小版本号。
o=<用户名><会话ID><会话版本><网络类型><地址类型><单播地址>
"o="字段给出了当前会话的发起者,会话标志和版本号的信息。
s=<会话名字>
字段"s="是文本类型的会话名字,每个会话描述有且仅有一个"s="字段,"s="字段不能为空,并且应该为ISO 10646字体。如果一个会话没有有意义的名字,则此字段应该为一个空格。
i=<会话描述>
"i="字段提供会话的文本信息,在会话层和媒体层最多出现一次。
URI是统一资源描述符,用户www的客户端。URI标志的是有关会话信息的外部的一个指针。这个字段是可选的。但是如果一旦出现,就必须先于第一个媒体轨出现,并且不能多于一个。
e=<电子邮件地址>
p=<电话号码>
这两个字段描述了会议拥有者的联系信息。这个并不一定标识的是发起会话的那个人,这两个字段都是可选的,需要注意的是在前一个版本的规范中,这两个字段必须出现一个,但是现在这个版本中,这个限制去掉了。如果出现两个字段,则必须先于第一个媒体轨出现,这两个字段都可以出现多次。
c=<网络类型><地址类型><连接地址>
这个字段包含连接数据,一个会话描述必须在每个媒体层都包含"c="字段或者在会话层包含一个"c="字段。如果这两个层都出现的话,则媒体层出现的"c="会覆盖会话层出现的"c="字段的值。
b=<带宽类型>:<带宽值>
这个字段的意识是本会话或者媒体需要占用的带宽
t=<起始时间><结束时间>
"t=“子弹标志了会话的起始时间和结束时间,如果会话在不规则的多个时间段内有效,则可能会出现多个字段的"t=”。如果时间段是规则的,则应该使用"r="字段,后面将会介绍。
r=<重复的间隔><持续时长><相对起始时间的偏移链表>
字段"r="标志会话的重复时间。例如:一个会话的有效时间为每个星期一早上10点和星期二上午11点,每次持续一个小时,总共三个月。则字段"r="的<起始时间>为第一个星期一的早上10点,<重复间隔>为一个星期,<有效时长>为1个小时,<相对起始时间的偏移链表>为0和25。字段"t="的<结束时间>为三个月后。缺省情况下,单位都为s。
因此"r="和"t="字段如下:
t=3034423619 3042462419
r=604800 3600 0 90000
通常为了紧凑的表示,也可以使用天、小时、分钟为单位例如r=7d 1h 25h
为了在夏令时和标准时间之间转换,有必要知道对基准时间的偏移量。为了标识一个会话在夏天和冬天的一个时间,有必要指出是哪个时域的。"z="字段允许列举一系列基于基准时间的调准时刻及其偏移量。如:
z=2882844526 -1h 2898848070 0
这表示在时刻2882844526,基准时刻需要往前调1个小时;在时刻2898848070则不需要调准。
k=<方法>
k=<方法>:<秘钥>
如果在一个安全信道上进行传输,则可以通过SDP来传达秘钥,最简单的方式采用字段"k="来协商,不过这种方式已经是不推荐的了。
字段"k="可以在所有媒体轨之前,这表示应用于所有的媒体轨,或者单独用于某个媒体轨,本规范定义了如下几种方式:
a=<属性>
a=<属性>:<值>
属性是扩展SDP的主要方式,有会话层属性和媒体层属性。会话层的属性应用于所有的媒体轨,媒体层的属性只应用于当前的媒体轨。
属性有两种方式:
m=<媒体类型><端口><协议><格式类型>
一个会话描述可能包括多个媒体描述。每个媒体描述都以"m="字段开始的,结束于下一个"m="或者整个会话结束。
除了我们前面介绍的会话描述和媒体描述说明以外,SDP以支持了特征属性的拓展,通过拓展的属性可以支持更多的属性参数。SDP属性支持了会话级和媒体级属性两种。会话级属性顾名思义,它是针对会话层级的属性,媒体级属性针对媒体属性设置所设置的属性。下面介绍几种常用的扩展属性。
下面是GB28181使用sdp协议发送的数据格式,可以参考上述讲解进行分析:
v=0
o=34020000001320000001 0 0 IN IP4 172.16.10.22
s=Play
c=IN IP4 172.16.10.22
t=0 0
m=video 15062 RTP/AVP 96
a=setup:active
a=sendonly
a=rtpmap:96 PS/90000
a=username:34020000001320000001
a=password:12345678
a=filesize:0
y=0365961830
参考文档:
《RFC4566 https://datatracker.ietf.org/doc/html/rfc4566》