WebRTC系列- SDP详解

1.综述

SDP(Session Description Protocol);按照英文全称,它是一种通用的会话描述协议,也就是一种用来描述信息格式的标准,所以它不是一种用于传输的协议而是由 ITEF 组织下的 MMusic 工作组设计的一种会话描述格式,但是可以用其他的传输协议通过sdp来交换必要的信息;
一般常用在实时音视频中用来交换信息,比如在 WebRTC 中,需要通信双方在连接阶段通过已有的信令服务使用 SDP 来协商后续传输过程中使用的音视频编解码器(codec)、ICE Candida、网络传输协议等;
通信双方可以使用 HTTP、WebSocket、socketio 等传输协议来交换各自的SDP 内容,在webrtc中这个过程称叫作 offer/answer 交换,也就是发起方通过webrtc的接口生成offer sdp,然后发送 offer,接收方收到 offer通过接口设置给webrtc后调用接口生成自己的answer SDP,发送给offer端;
SDP 会话描述由会话级部分组成后跟零个或多个媒体级部分,各层包含的主要信息如下图:
在这里插入图片描述
在上图中的媒体层一般都是会有多个的;在RFC中规定了sdp的一般格式:
一个 SDP 会话描述由多行文本组成:<类型>=<值>或<type>=<value>, 其中 是一个区分大小写的字符,并且 是有一定格式的文本,其格式取决于 ;通常, 是区分大小写的由空格或自由格式的单个分隔的多个字段;一般的在=的两侧是不能有空格;

结下来按照章节详细分析

1.SDP的会话层

会话级别部分以 “v=” 行开始并继续到第一个媒体级别部分:示例如下:

v=  (protocol version)  SDP 协议的版本号
o=  (originator and session identifier) 
s=  (session name)    本次会话的标题或会话的名称
i=* (session information)
u=* (URI of description)
e=* (email address)
p=* (phone number)
c=* (connection information -- not required if included in all media)
b=* (zero or more bandwidth information lines)
# 2. 一个或多个时间描述(字段参见下文)
z=* (time zone adjustments)
k=* (encryption key)
a=* (zero or more session attribute lines)
# 3. 零个或多个媒体级别的描述(字段参见下文)
# 时间描述的字段有这些
t=  (time the session is active) 会话的起始时间和结束时间,WebRTC是0
r=* (zero or more repeat times) 

上面的例子中 **=***右边的星号表示这个type是可选的,也就是sdp中不一定需要;除了注释说明的其他的含义如下:

  1. originator and session identifier: 会话所有者有关的参数,包括用户名、session 信息,地址信息等;格式如下:
o=<username> <session-id> <session-version> <nettype> <addrtype> <unicast-address>

  • username: 会话发起者的名称。如果不提供则用"-"表示,用户名不能包含空格;
  • session-id: 主叫方的会话标识符
  • session-version: 会话版本号,一般为 0;
  • nettype: 网络类型,目前仅使用 IN 来表示 Internet 网络类型;
  • addrtype: 地址类型,可以是 IPV4 和 IPV6 两种地址类型;
  • unicast-address:会话发起者的 IP 地址。
  1. session name: 本次会话的标题或名称,可以用-代替;
  2. time the session is active:会话的起始时间和结束时间(Time session starts and stops),如果没有规定这两个时间的话,都写为 0 即可。

2.SDP的媒体层

每个媒体级别部分都以“m=”行开头,继续到下一个媒体级别部分或整个会话结束;

 m=<media> <port> <proto> <fmt> ...
  • media:媒体类型,可以为 “audio”、“video”、“text”、“application”、“message”,表示音频类型、视频类型、文本类型、应用类型、消息类型等,以后也可能扩展其他类型;
  • port: 媒体流发送的传输端口。表示在对应的本地端口上发送流,传输端口的含义取决于在相关的“c=”字段中指定所使用的网络,并在传输在媒体字段的 子字段中定义的协议;媒体应用程序使用的其他端口(例如 (RTCP) 端口) 可以使用同一个(端口复用)或可以在单独的属性中指定“a=rtcp:” );注意单独制定的rtcp端口一般在这个端口上+1;
  • proto:流传输协议。举例说明:
    RTP/SAVPF 表示用 UDP 传输 RTP 包;
    TCP/RTP/SAVPF 表示用 TCP 传输 RTP 包;
    UDP/TLS/RTP/SAVPF 表示用 UDP 来传输 RTP 包,并且使用 TLS 加密;
    最后的 SAVPF 还有其他几种值:AVP, SAVP, AVPF, SAVPF。
    AVP 意为 AV profile
    S 意为 secure
    F 意为 feedback
  • fmt 表示媒体格式描述,它可能是一串数字,代表多个媒体,这个字段的含义与 proto 字段的类型相关。在后面,可以使用"a=rtpmap:"、“a=fmtp:”、“a=rtcp-fb” 等扩展字段来对 fmt 进行说明。
    示例如下:
m=  (media name and transport address)

i=* (media title)

c=* (connection information -- optional if included at session level)
b=* (zero or more bandwidth information lines)

k=* (encryption key)

a=* (zero or more media attribute lines)

a 字段是扩展 SDP 的主要方式,有会话层属性和媒体层属性。会话层的属性应用于所有的媒体流,媒体层的属性只应用于当前的媒体流。 type a 的常用属性如下表:
在这里插入图片描述

4.SDP 示例

// sdp版本号为0
v=0

// o=<username> <session-id> <session-version> <nettype> <addrtype> <unicast-address>
// 用户ID或者企业标识,如果不需要写成‘-’,会话id是8100750360520823155,当前会话版本是2,(后面如果有类似改变编码的操作,session-version加1),地址类型为IP4,地址为127.0.0.1(这里可以忽略)
o=- 6413499524467085832 2 IN IP4 127.0.0.1
// 会话名可以不用设置, 使用‘-’代替
s=-
// 会话的起始时间,都为0表示没有限制,即时通讯 基本都是0
t=0 0
a=ice-lite
// 音频、视频的传输的传输采取多路复用,通过同一个RTP通道传输音频、视频,如果后续还有其他的媒体,这里可以增加
// 例如 group:BUNDLE 1 2 3 分别 表示 音 视频 数据通道,老版本这里 可能是 audio video datachannal
// 可以参考 https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54
a=group:BUNDLE 0 1 2

// 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 ARDAMS
// m=<media> <port> <proto> <fmt> ...
// 本次会话有音频,端口为9(可忽略,端口9为Discard Protocol专用)9是一个特殊端口(1024以下的端口由系统控制),表示不使用本端口发送数据;采用UDP传输经过TLS加密的RTP包,并使用基于SRTCP的音视频反馈机制来提升传输质量SAVPF中s是safe的含义av是audio/video,p是protocol,f是family;111(一般是opus)、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链路检查的时候对链路的有效性进行验证,通过交换后进行双方验证, ice-ufrag、ice-pwd 分别为ICE协商用到的认证信息
a=ice-ufrag:58142170598604946
a=ice-pwd:71696ad0528c4adb02bb40e1
// 以前使用ICE进行端口收集需要在sdp交换之前完成,这种方式需要等待,trickle表示sdp交换的时候不进行收集, 是在setlocaldes 发送完sdp之后进行收集,没发送一个进行ice连同检测,以提高效率;
a=ice-options:trickle
// 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=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
// 告诉对方我这里既可以发送音频,也可以接收音频;
a=sendrecv
// 接下来都是 rtcp相关的
// 表示启用多路复用,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

// minptime 最小的音频打包时间 
 // useinbandfec 指定解码器具有利用Opus带内FEC的能力
 // stereo 指定解码器接收立体声信号还是单声道信号,其中1表示首选立体声信号,0表示仅首选单声道信号
 // sprop-stereo sprop-stereo	指定发送方是否可能产生立体声音频。其中1指定可能发送立体声信号,0指定发送方可能仅发送单声道
 // maxaveragebitrate 指定会话的最大平均平均接收比特率,以每秒比特数(b/s)
a=fmtp:111 minptime=10;useinbandfec=1;stereo=1; sprop-stereo=1;maxaveragebitrate = 8000
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:102 ILBC/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
// 跟前面的rtpmap类似
a=rtpmap:126 telephone-event/8000

// ssrc用来对媒体进行描述,格式为a=ssrc:<ssrc-id> <attribute>:<value>,具体可参考 RFC5576
// cname用来唯一标识媒体的数据源 ,一般和ssrc对应,这里came是为了防止ssrc重复
a=ssrc:3111117364 cname:yf5j55RzgCyvZVkp
// msid后面带两个id,第一个是MediaStream的id,第二个是audio track的id(跟后面的mslabel、label对应)
a=ssrc:3111117364 msid:ARDAMS ARDAMSa0
a=ssrc:3111117364 mslabel:ARDAMS
a=ssrc:3111117364 label:ARDAMSa0
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 123 125 122 124 107 108
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:c0UT
a=ice-pwd:lttpyY+EYi08FyK76ZuKX9eA
a=ice-options:trickle renomination
a=fingerprint:sha-256 96:CA:48:3B:8F:7C:F7:48:F7:08:DF:02:3D:A0:08:BD:F7:27:40:44:7A:15:BF:DC:82:AA:E6:C9:F2:E0:E5:4A
a=setup:actpass
a=mid:2
a=extmap:14 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:2 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=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:9 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07
a=extmap:10 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=sendrecv
a=rtcp-mux
//rtcp消息是否可以减少, 表示对方只定时发送丢失的包数据
a=rtcp-rsize
// 对paload type的补充说明
a=rtpmap:96 H264/90000
// 接收端带宽评估;
a=rtcp-fb:96 goog-remb
// 发送端带宽评估,有些浏览器可能不支持
a=rtcp-fb:96 transport-cc
// 编码控制 codec control message。可以发送一个完整的内部帧请求;当对方缺少包,可以发送rtcp是fir类型的,这时候发送端可以发送一个i帧
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
// pli 丢失一个帧,可以重新请求
a=rtcp-fb:96 nack pli
// h264 编码的补充,其中通过profile-level-id可以知道使用h264的版本级别等信息;
// 后面几个是限制 视频传输的最大,最小带宽,以及开始带宽(浮动的时候不大于最最大值,不小于最小值)
a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f;x-google-max-bitrate=655;x-google-min-bitrate=120;x-google-start-bitrate=492
// 表示用于h264(96)重传的包,rtx 有自己的ssrc通常和对应的编码的
a=rtpmap:97 rtx/90000
// 这里表示 9796 关联的,也就是说97是96的重传包;
a=fmtp:97 apt=96
a=rtpmap:98 H264/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e02a
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 VP9/90000
a=rtcp-fb:127 goog-remb
a=rtcp-fb:127 transport-cc
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack
a=rtcp-fb:127 nack pli
a=rtpmap:123 rtx/90000
a=fmtp:123 apt=127
a=rtpmap:125 H265/90000
a=rtcp-fb:125 goog-remb
a=rtcp-fb:125 transport-cc
a=rtcp-fb:125 ccm fir
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=rtpmap:122 rtx/90000
a=fmtp:122 apt=125
// red表示 需要数据包可以有冗余数据,如果发生丢包,可以通过冗余包尝试找回数据;
a=rtpmap:124 red/90000
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=124
// fec的增强版本
a=rtpmap:108 ulpfec/90000
// 这个表示有联播, 71691508 1172020434 3648770906 三个ssrc分别表示三路编码的流
a=ssrc-group:SIM 71691508 1172020434 3648770906
// 表示这两个是一组,也就是RTX和关联的编码
a=ssrc-group:FID 71691508 3328952084
a=ssrc-group:FID 1172020434 2049989829
a=ssrc-group:FID 3648770906 1147330493
// cname channel name。表示传输通道的名字,webrtc是通道复用的,所以在这个sdp中能看到不管是音频的ssrc、视频的ssrc,还是rtx的ssrc、联播的ssrc都是一个cname
a=ssrc:71691508 cname:yf5j55RzgCyvZVkp
// media track ID 表示ARDAMSv0这个视频是在ARDAMS流
a=ssrc:71691508 msid:ARDAMS ARDAMSv0
a=ssrc:71691508 mslabel:ARDAMS
a=ssrc:71691508 label:ARDAMSv0
a=ssrc:1172020434 cname:yf5j55RzgCyvZVkp
a=ssrc:1172020434 msid:ARDAMS ARDAMSv0
a=ssrc:1172020434 mslabel:ARDAMS
a=ssrc:1172020434 label:ARDAMSv0
a=ssrc:3648770906 cname:yf5j55RzgCyvZVkp
a=ssrc:3648770906 msid:ARDAMS ARDAMSv0
a=ssrc:3648770906 mslabel:ARDAMS
a=ssrc:3648770906 label:ARDAMSv0
a=ssrc:3328952084 cname:yf5j55RzgCyvZVkp
a=ssrc:3328952084 msid:ARDAMS ARDAMSv0
a=ssrc:3328952084 mslabel:ARDAMS
a=ssrc:3328952084 label:ARDAMSv0
a=ssrc:2049989829 cname:yf5j55RzgCyvZVkp
a=ssrc:2049989829 msid:ARDAMS ARDAMSv0
a=ssrc:2049989829 mslabel:ARDAMS
a=ssrc:2049989829 label:ARDAMSv0
a=ssrc:1147330493 cname:yf5j55RzgCyvZVkp
a=ssrc:1147330493 msid:ARDAMS ARDAMSv0
a=ssrc:1147330493 mslabel:ARDAMS
a=ssrc:1147330493 label:ARDAMSv0

猜你喜欢

转载自blog.csdn.net/lym594887256/article/details/124442674