什么是SDP

SDP(Session Description Protocol)是一种通用的会话描述协议,主要用来描述多媒体会话,用途包括会话声明、会话邀请、会话初始化等。

WebRTC主要在连接建立阶段用到SDP,连接双方通过信令服务交换会话信息,包括音视频编解码器(codec)、主机候选地址、网络传输协议等。

下面先简单介绍下SDP的格式、常用属性,然后通过WebRTC连接建立过程生成的SDP实例进行进一步讲解。

协议格式说明

SDP的格式非常简单,由多个行组成,每个行都是如下格式。

<type>=<value>

其中:

  • <type>:大小写敏感的一个字符,代表特定的属性,比如v代表版本;
  • <value>:结构化文本,格式与属性类型有关,UTF8编码;
  • =两边不允许存在空格;
  • =*表示是可选的;

常见属性

以下面的SDP为例:

v=0
o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
s=
c=IN IP4 host.anywhere.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
m=video 51372 RTP/AVP 31
a=rtpmap:31 H261/90000
m=video 53000 RTP/AVP 32
a=rtpmap:32 MPV/90000

协议版本号:v=

格式如下,注意,没有子版本号。

v=0

会话发起者:o

格式如下,其中,username、session-id、nettype、addrtype、unicast-address 一起,唯一标识一个会话。

o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>

各字段含义如下:

  • username:发起者的用户名,不允许存在空格,如果应用不支持用户名,则为-
  • sess-id:会话id,由应用自行定义,规范的建议是NTP(Network Time Protocol)时间戳。
  • sess-version:会话版本,用途由应用自行定义,只要会话数据发生变化时(比如编码),sess-version随着递增就行。同样的,规范的建议是NTP时间戳。
  • nettype:网络类型,比如IN表示Internet
  • addrtype:地址类型,比如IP4IV6
  • unicast-address:域名,或者IP地址。

会话名 s=

必选,有且仅有一个s=字段,且不能为空。如果实在没有有意义的会话名,可以赋一个空格,即s=

s=<session name>

连接数据:c=

格式如下:

c=<nettype> <addrtype> <connection-address>

每个SDP至少需要包含一个会话级别的c=字段,或者在每个媒体描述后面各包含一个c=字段。(媒体描述后的c=会覆盖会话级别的c=

  • nettype:网络类型,比如IN,表示 Internet。
  • addrtype:地址类型,比如IP4IP6
  • connection-address:如果是广播,则为广播地址组;如果是单播,则为单播地址;

举例01:

c=IN IP4 224.2.36.42/127

举例02:

c=IN IP4 host.anywhere.com

媒体描述:m=

SDP可能同时包含多个媒体描述。格式如下:

m=<media> <port> <proto> <fmt> ...

其中:

  • media:媒体类型。包括 video、audio、text、application、message等。
  • port:传输媒体流的端口,具体含义取决于使用的网络类型(在c=中声明)和使用的协议(proto,在m=中声明)。
  • proto:传输协议,具体含义取决于c=中定义的地址类型,比如c=是IP4,那么这里的传输协议运行在IP4之上。比如:
    • UDP:传输层协议是UDP。
    • RTP/AVP:针对视频、音频的RTP协议,跑在UDP之上。
    • RTP/SAVP:针对视频、音频的SRTP协议,跑在UDP之上。
  • fmt:媒体格式的描述,可能有多个。根据 proto 的不同,fmt 的含义也不同。比如 proto 为 RTP/SAVP 时,fmt 表示 RTP payload 的类型。如果有多个,表示在这次会话中,多种payload类型可能会用到,且第一个为默认的payload类型。

举例,下面表示媒体类型是视频,采用SRTP传输流媒体数据,且RTP包的类型可能是122、102...119,默认是122。

m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119

对于 RTP/SAVP,需要注意的是,payload type 又分两种类型:

  1. 静态类型:参考 RTP/AVP audio and video payload types
  2. 动态类型:在a=fmtp:里进行定义。(a=为附加属性,见后面小节)

举例,下面的SDP中:

  1. 对于audio,111 是动态类型,表示opus/48000/2
  2. 对于video,122 是动态类型,表示H264/90000
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 126
a=rtpmap:111 opus/48000/2
m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119
a=rtpmap:122 H264/90000

附加属性:a=

作用:用于扩展SDP。

有两种作用范围:会话级别(session-level)、媒体级别(media-level)。

  1. 媒体级别:媒体描述(m=)后面可以跟任意数量的 a= 字段,对媒体描述进行扩展。
  2. 会话级别:在第一个媒体字段(media field)前,添加的 a= 字段是会话级别的。

有如下两种格式:

a=<attribute>
a=<attribute>:<value>

格式1举例:

a=recvonly

格式2举例:

a=rtpmap:0 PCMU/8000

时间:t=

作用:声明会话的开始、结束时间。

格式如下:

t=<start-time> <stop-time>

如果<stop-time>是0,表示会话没有结束的边界,但是需要在<start-time>之后会话才是活跃(active)的。如果<start-time>是0,表示会话是永久的。

举例:

t=0 0

WebRTC实例

下面例子来自腾讯云WebRTC服务的远端offer。

// sdp版本号为0
v=0
// o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
// 用户名为空,会话id是8100750360520823155,会话版本是2(后面如果有类似改变编码的操作,sess-version加1),地址类型为IP4,地址为127.0.0.1(这里可以忽略)
o=- 7595655801978680453 2 IN IP4 112.90.139.105
// 会话名为空
s=-
// 会话的起始时间,都为0表示没有限制
t=0 0
a=ice-lite
// 音频、视频的传输的传输采取多路复用,通过同一个RTP通道传输音频、视频,可以参考 https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54
a=group:BUNDLE 0 1
// WMS是WebRTC Media Stram的缩写,这里给Media Stream定义了一个唯一的标识符。一个Media Stream可以有多个track(video track、audio track),这些track就是通过这个唯一标识符关联起来的,具体见下面的媒体行(m=)以及它对应的附加属性(a=ssrc:)
// 可以参考这里 http://tools.ietf.org/html/draft-ietf-mmusic-msid
a=msid-semantic: WMS 5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV
// m=<media> <port> <proto> <fmt> ...
// 本次会话有音频,端口为9(可忽略,端口9为Discard Protocol专用),采用UDP传输加密的RTP包,并使用基于SRTCP的音视频反馈机制来提升传输质量,111、103、104等是audio可能采用的编码(参见前面m=的说明)
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 126
// 音频发送者的IP4地址,WebRTC采用ICE,这里的 0.0.0.0 可直接忽略
c=IN IP4 0.0.0.0
// RTCP采用的端口、IP地址(可忽略)
a=rtcp:9 IN IP4 0.0.0.0
// ice-ufrag、ice-pwd 分别为ICE协商用到的认证信息
a=ice-ufrag:58142170598604946
a=ice-pwd:71696ad0528c4adb02bb40e1
// DTLS协商过程的指纹信息
a=fingerprint:sha-256 7F:98:08:AC:17:6A:34:DB:CF:3B:EC:93:ED:57:3F:5A:9E:1F:4A:F3:DB:D5:BF:66:EE:17:58:E0:57:EC:1B:19
// 当前客户端在DTLS协商过程中,既可以作为客户端,也可以作为服务端,具体可参考 RFC4572
a=setup:actpass
// 当前媒体行的标识符(在a=group:BUNDLE 0 1 这行里面用到,这里0表示audio)
a=mid:0
// RTP允许扩展首部,这里表示采用了RFC6464定义的针对audio的扩展首部,用来调节音量,比如在大型会议中,有多个音频流,就可以用这个来调整音频混流的策略
// 这里没有vad=1,表示不启用这个音量控制
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
// 表示既可以发送音频,也可以接收音频
a=sendrecv
// 表示启用多路复用,RTP、RTCP共用同个通道
a=rtcp-mux
// 下面几行都是对audio媒体行的补充说明(针对111),包括rtpmap、rtcp-fb、fmtp
// rtpmap:编解码器为opus,采样率是48000,2声道
a=rtpmap:111 opus/48000/2
// rtcp-fb:基于RTCP的反馈控制机制,可以参考 https://tools.ietf.org/html/rfc5124、https://webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02/
a=rtcp-fb:111 transport-cc
a=rtcp-fb:111 nack
// 最小的音频打包时间
a=fmtp:111 minptime=20
// 跟前面的rtpmap类似
a=rtpmap:126 telephone-event/8000
// ssrc用来对媒体进行描述,格式为a=ssrc:<ssrc-id> <attribute>:<value>,具体可参考 RFC5576
// cname用来唯一标识媒体的数据源
a=ssrc:16864608 cname:YZcxBwerFFm6GH69
// msid后面带两个id,第一个是MediaStream的id,第二个是audio track的id(跟后面的mslabel、label对应)
a=ssrc:16864608 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 128f4fa0-81dd-4c3a-bbcd-22e71e29d178
a=ssrc:16864608 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV
a=ssrc:16864608 label:128f4fa0-81dd-4c3a-bbcd-22e71e29d178
// 跟audio类似,不赘述
m=video 9 UDP/TLS/RTP/SAVPF 122 102 125 107 124 120 123 119
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:58142170598604946
a=ice-pwd:71696ad0528c4adb02bb40e1
a=fingerprint:sha-256 7F:98:08:AC:17:6A:34:DB:CF:3B:EC:93:ED:57:3F:5A:9E:1F:4A:F3:DB:D5:BF:66:EE:17:58:E0:57:EC:1B:19
a=setup:actpass
a=mid:1
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:122 H264/90000
a=rtcp-fb:122 ccm fir
a=rtcp-fb:122 nack
a=rtcp-fb:122 nack pli
a=rtcp-fb:122 goog-remb
a=rtcp-fb:122 transport-cc
a=fmtp:122 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=122
a=rtpmap:125 H264/90000
a=rtcp-fb:125 ccm fir
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=rtcp-fb:125 goog-remb
a=rtcp-fb:125 transport-cc
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=125
a=rtpmap:124 H264/90000
a=rtcp-fb:124 ccm fir
a=rtcp-fb:124 nack
a=rtcp-fb:124 nack pli
a=rtcp-fb:124 goog-remb
a=rtcp-fb:124 transport-cc
a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d0032
a=rtpmap:120 rtx/90000
a=fmtp:120 apt=124
a=rtpmap:123 H264/90000
a=rtcp-fb:123 ccm fir
a=rtcp-fb:123 nack
a=rtcp-fb:123 nack pli
a=rtcp-fb:123 goog-remb
a=rtcp-fb:123 transport-cc
a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032
a=rtpmap:119 rtx/90000
a=fmtp:119 apt=123
a=ssrc-group:FID 33718809 50483271
a=ssrc:33718809 cname:ovaCctnHP9Asci9c
a=ssrc:33718809 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 1d7fc300-9889-4f94-9f35-c0bcc77a260d
a=ssrc:33718809 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV
a=ssrc:33718809 label:1d7fc300-9889-4f94-9f35-c0bcc77a260d
a=ssrc:50483271 cname:ovaCctnHP9Asci9c
a=ssrc:50483271 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 1d7fc300-9889-4f94-9f35-c0bcc77a260d
a=ssrc:50483271 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV
a=ssrc:50483271 label:1d7fc300-9889-4f94-9f35-c0bcc77a260d

写在后面

SDP协议格式本身很简单,难点一般在于应用层在不同场景下扩展出来的属性,以及不同扩展属性对应的含义。比如上面举的例子,扩展属性、属性值的说明分散在数十个RFC里,查找、理解都费了一番功夫。

如有错漏,敬请指出。

相关链接

SDP: Session Description Protocol

Annotated Example SDP for WebRTC

WebRTC:会话描述协议SDP的更多相关文章

  1. 会话描述协议(SDP)介绍

    1.SDP的引入 SDP最初用于Mbone(组播骨干网)上的多媒体会议.Mbone 是Internet 的一部分,它的主要特征是对IP组播技术的使用.IP组播技术比较适合实现多方会话. 基于组播的会议 ...

  2. [百科] - SIP(会话发起协议)

    SIP(会话发起协议)SIP是类似于HTTP的基于文本的协议.SIP可以减少应用特别是高级应用的开发时间.由于基于IP协议的SIP利用了IP网络,固定网运营商也会逐渐认识到SIP技术对于他们的深远意义 ...

  3. SIP协议 会话发起协议(一)

    会话发起协议(SIP)是VoIP技术中最常用的协议之一.它是一种应用层协议,与其他应用层协议协同工作,通过Internet控制多媒体通信会话. SIP - 概述 以下是有关SIP的几点注意事项 - S ...

  4. 【转】SIP协议 会话发起协议

    转自:https://www.cnblogs.com/gardenofhu/p/7299963.html 会话发起协议(SIP)是VoIP技术中最常用的协议之一.它是一种应用层协议,与其他应用层协议协 ...

  5. SIP会话发起协议 - 先知道是什么(一)

    少年,思无邪,最最动人. 协议概述 SIP会话发起协议是VoIP技术中最常用的协议之一.它是一种应用层协议,与其它应用层协议协同工作,通过Internet控制多媒体通信会话. SIP采用SDP(会话描 ...

  6. webrtc vp8与h264 sdp文件解读

    参考地址:https://blog.csdn.net/zhangjikuan/article/details/27367437, https://www.cnblogs.com/idignew/p/7 ...

  7. Android呼叫管理服务之会话发起协议(SIP)API

    原文:http://android.eoe.cn/topic/android_sdk Android提供了一个支持会话发起协议(SIP)的API,这可以让你添加基于SIP的网络电话功能到你的应用程序. ...

  8. Android网络功能之会话发起协议SIP

    原文:http://android.eoe.cn/topic/android_sdk * 会话发起协议* Android提供了一个支持会话发起协议(SIP)的API,这可以让你添加基于SIP的网络电话 ...

  9. SIP(Session Initiation Protocol,会话初始协议)

    SIP(Session Initiation Protocol,会话初始协议)的开发目的是用来帮助提供跨越因特网的高级电话业务.因特网电话(IP电话)正在向一种正式的商业电话模式演进,SIP就是用来确 ...

随机推荐

  1. Spark之常用操作

    -- 筛选 val rdd = sc.parallelize(List("ABC","BCD","DEF")) val filtered = ...

  2. 【vue系列】Virtual DOM 真的比操作原生 DOM 快吗?

    一.前言 网上都说操作真实dom怎么怎么慢,这儿有个例子:http://chrisharrington.github.io/demos/performance/,例子循环2000个随机数组,点击按钮重 ...

  3. js简单对象List自定义属性排序

    简单对象List自定义属性排序 <script type="text/javascript"> var objectList = new Array(); functi ...

  4. Spark2.4.0源码——DAGScheduler

    前言 Spark会将用户提交的作业看作一个job,在提交的时候首先将job转换为一系列的RDD,并按照RDD之间的依赖关系构建DAG(有向无环图),DAGScheduler会按照RDD依赖的不同将DA ...

  5. 基于STM32之UART串口通信协议(三)接收

    一.前言 1.简介 回顾上一篇UART发送当中,已经讲解了如何实现UART的发送操作了,接下来这一篇将会继续讲解如何实现UART的接收操作. 2.UART简介 嵌入式开发中,UART串口通信协议是我们 ...

  6. C++类的完美单元测试方案——基于C++11扩展的friend语法

    版权相关声明:本文所述方案来自于<深入理解C++11—C++11新特性解析与应用>(Michael Wong著,机械工业出版社,2016.4重印)一书的学习. 项目管理中,C语言工程做单元 ...

  7. 用.NET Core实现一个类似于饿了吗的简易拆红包功能

      需求说明 以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了. 点餐结束后,会有一个好友分享 ...

  8. Google play中下载apk

    在 Google play中下载apk:先在Google play中找到该apk,再去找APK downloader(https://www.allfreeapk.com/),Google play的 ...

  9. SQL Server温故系列(4):SQL 查询之集合运算 & 聚合函数

    1.集合运算 1.1.并集运算 UNION 1.2.差集运算 EXCEPT 1.3.交集运算 INTERSECT 1.4.集合运算小结 2.聚合函数 2.1.求行数函数 COUNT 2.2.求和函数 ...

  10. vboxnetctl: no such file or directory

     sudo /Library/StartupItems/VirtualBox/VirtualBox restart sudo /Library/StartupItems/VirtualBox/Vir ...