课程地址:零声学院 WebRTC入门与提高 https://ke.qq.com/course/435382?tuin=137bb271
技术支持QQ群:782508536
简介
SDP 完全是一种会话描述格式 ― 它不属于传输协议 ― 它只使用不同的适当的传输协议,包括会话通知协议(SAP)、会话初始协议(SIP)、实时流协议(RTSP)、MIME 扩展协议的电子邮件以及超文本传输协议(HTTP)。SDP协议是也是基于文本的协议,这样就能保证协议的可扩展性比较强,这样就使其具有广泛的应用范围。SDP 不支持会话内容或媒体编码的协商,所以在流媒体中只用来描述媒体信息。媒体协商这一块要用RTSP来实现.
当发起多媒体电话会议,IP语音呼叫时,流媒体视频或其他会话,需要传达媒体细节,传输地址和其他会话描元数据给参与者。SDP 为此类信息提供了标准。SDP纯粹是会话描述的格式,它不包含传输协议。
WebRTC 会话就是由 SDP 描述的。对于 WebRTC 来说,最重要的是 SDP 中的媒体和传输信息。
媒体信息包括:
媒体类型(视频,音频)
传输协议(RTP/UDP/IP,H.320等)
媒体格式(H.261视频,MPEG视频等)
传输信息包括:
媒体的远程地址
媒体的远程传输端口
该地址和端口取决于媒体和传输协议定义。但需要注意的是,因为存在网络地址转换(NAT)和防火墙,所以传输过程比较复杂,在 SDP 中没有定义相关的实现。WebRTC 中使用 ICE 协议来解决 NAT 的问题。
SDP 格式
SDP会话描述是由多行文本组成表格。由会话级部分(session-level)和多个媒体级(media-level)部分组成。会话级部分以”v =”行开始,到第一个媒体级部分结束。每个媒体级部分以”m =”行开始,持续到下一个媒体级。
下面是所有的字段描述,可选项目标有”*”。
会话描述
v =(协议版本)
o =(发起者和会话标识符)
s =(会话名称)
i = *(会话信息)
u = *(描述的URI)
e = *(电子邮件地址)
p = *(电话号码)
c = *(连接信息 - 如果包含在内,则不需要所有媒体)
b = *(零个或多个带宽信息行)
一个或多个时间描述("t ="和"r ="行;见下文)
z = *(时区调整)
k = *(加密密钥)
a = *(零个或多个会话属性行)零个或多个媒体描述
时间描述
t =(会话活动时间)
r = *(零个或多个重复次数)
媒体描述
m =(媒体名称和传输地址)
i = *(媒体标题)
c = *(连接信息 - 如果包含在内,则为可选项会话级别)
b = *(零个或多个带宽信息行)
k = *(加密密钥)
a = *(零个或多个媒体属性行)
下面是一个基本的 SDP 描述:
v=0
o=- 3925575362227037542 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS 735174861
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:KZ8M
a=ice-pwd:NZ1R3TFbpF9ZqEyg5PNSoM85
a=fingerprint:sha-256 7B:0B:B7:6C:C2:82:77:D2:70:18:3F:DD:18:98:AB:22:07:0E:5D:5B:6D:30:C0:05:42:50:C0:D7:53:AF:3E:9F
a=setup:active
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/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
a=ssrc:889008008 cname:JQsS3I1VR6oT0wUw
a=ssrc:889008008 msid:735174861 6446c8d1-1db2-4024-b0bd-1e03304810fe
a=ssrc:889008008 mslabel:735174861
a=ssrc:889008008 label:6446c8d1-1db2-4024-b0bd-1e03304810fe
m=video 9 UDP/TLS/RTP/SAVPF 98 96 100 127 99 97 101
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:KZ8M
a=ice-pwd:NZ1R3TFbpF9ZqEyg5PNSoM85
a=fingerprint:sha-256 7B:0B:B7:6C:C2:82:77:D2:70:18:3F:DD:18:98:AB:22:07:0E:5D:5B:6D:30:C0:05:42:50:C0:D7:53:AF:3E:9F
a=setup:active
a=mid:video
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:98 H264/90000
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtpmap:100 red/90000
a=rtpmap:127 ulpfec/90000
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=ssrc-group:FID 687692313 4175760292
a=ssrc:687692313 cname:JQsS3I1VR6oT0wUw
a=ssrc:687692313 msid:735174861 54bc6a42-f281-4d75-ac41-ab709717abdb
a=ssrc:687692313 mslabel:735174861
a=ssrc:687692313 label:54bc6a42-f281-4d75-ac41-ab709717abdb
a=ssrc:4175760292 cname:JQsS3I1VR6oT0wUw
a=ssrc:4175760292 msid:735174861 54bc6a42-f281-4d75-ac41-ab709717abdb
a=ssrc:4175760292 mslabel:735174861
a=ssrc:4175760292 label:54bc6a42-f281-4d75-ac41-ab709717abdb
"
s=-
会话名,没有的话使用-代替
a=group
需要共用一个传输通道传输的媒体,如果没有这一行,音视频,数据就会分别单独用一个udp端口来发送
在同一个RTP会话中多路复用几个媒体流,也就是在后面以”m =”开始的媒体段
a=msid-semantic
WMS是WebRTC Media Stream简称,这一行定义了本客户端支持同时传输多个流,一个流可以包括多个track。
在PeerConnection生命周期内为 WebRTC Media Stream (WMS) 定义一个唯一的标识符,用于确定其他独立的RTP媒体流(下面以”m = “开始的媒体段)属于该 WMS。
接下来是三个以 “m = “开始的媒体段,分别是audio、video、application。
m =
后面跟着四个参数
是媒体类型,包括audio, video, text, application, message
是发送媒体流的传输端口
是传输协议
是媒体格式说明,有效负载类型
有效负载类型可以看 这篇文档。其中0-95是静态负载类型,96-127是动态负载类型,需要使用”a = rtpmap:”属性指定格式参数。
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126
m=audio说明本会话包含音频,9代表音频使用端口9来传输,但是在webrtc中一现在一般不使用,如果设置为0,代表不传输音频,UDP/TLS/RTP/SAVPF是表示用户来传输音频支持的协议,udp,tls,rtp代表使用udp来传输rtp包,并使用tls加密
SAVPF代表使用srtcp的反馈机制来控制通信过程,后台111 103 104 9 0 8 106 105 13 126表示本会话音频支持的编码,后台几行会有详细补充说明
c=IN IP4 0.0.0.0
c 字段中包含了连接数据,但这一个地址不会被实际使用,只有 ICE 候选项中的 IP 地址和端口才会用于建立对话。
a=rtcp:9 IN IP4 0.0.0.0
用来传输rtcp地地址和端口,webrtc中不使用
a=ice-ufrag
a=ice-pwd
指定了用于ICE的用户名片段和密码,不同的媒体段会使用不同的用户名和密码。
a=fingerprint
指纹是用于建立DTLS连接的自签名证书的SHA-256散列,这行是dtls协商过程中需要的认证信息
a=setup:active
以上这行代表本客户端在dtls协商过程中,可以做客户端也可以做服务端,参考rfc4145 rfc4572
a=mid:audio
在前面BUNDLE这一行中用到的媒体标识
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
上一行指出我要在rtp头部中加入音量信息,参考 rfc6464
a=sendrecv
上一行指出我是双向通信,另外几种类型是recvonly,sendonly,inactive
a=rtcp-mux
上一行指出rtp,rtcp包使用同一个端口来传输
a = rtpmap
参数为 <payload type> <encoding name> / <clock rate> [/ <encoding parameters>]
对于 a=rtpmap:111 opus/48000/2 ,就是对应”m =”中的有效负载111,使用Opus编解码器,采样频率48kHz,立体声。
一般每个媒体段会有多条”a=rtpmap”字段,位于前面的编解码器具有较高的优先级。
a=fmtp:111 minptime=10;useinbandfec=1
这里讲一下a=fmtp:参数设置,这里讲音频的
将有效负载111,即 Opus 数据包的最短分时时间设置为10ms,且使用in-band FEC(前向纠错编码)
a=rtcp-fb:111 transport-cc
以上这行说明opus编码支持使用rtcp来控制拥塞,参考https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=rtcp-fb
反馈消息,接收方向发送方发送的反馈消息
a=ssrc
同步源标识符,用于在使用多个源时表示不同源的属性
a=extmap
RTP 扩展项,接收者可以自己解码获取里面的数据
a=rtcp-mux
支持对RTP的同一端口多路复用RTCP
b=
该属性在上面没有列出,可以自己添加
格式为<bwtype>:<bandwidth>
可以为CT或AS,CT是所有媒体的总带宽上限,AS是指定单个媒体的带宽
a=ssrc:18509423 cname:sTjtznXLCNH7nbRw
cname用来标识一个数据源,ssrc当发生冲突时可能会发生变化,但是cname不会发生变化,也会出现在rtcp包中SDEC中,用于音视频同步
a=ssrc:18509423 msid:h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C 15598a91-caf9-4fff-a28f-3082310b2b7a
以上这一行定义了ssrc和WebRTC中的MediaStream,AudioTrack之间的关系,msid后面第一个属性是stream-d,第二个是track-id
m=video 9 UDP/TLS/RTP/SAVPF 98 96 100 127 99 97 101
是对视频的编码设置,在这里,你可以指定是使用H264编码还是使用VP8编码。如96代表VP8编码,98代表H264编码,如果你要指定编码方式为VP8就将96放在前面,指定H264,就将98放在前面
a=rtpmap:98 H264/90000
每个codec都有类似的描述都有以下类似的描述
a=rtcp-fb:98 ccm fir
ccm是codec control using RTCP feedback message简称,意思是支持使用rtcp反馈机制来实现编码控制,fir是Full Intra Request
简称,意思是接收方通知发送方发送幅完全帧过来
a=rtcp-fb:98 nack
支持丢包重传,参考rfc4585
a=rtcp-fb:98 nack pli
支持关键帧丢包重传,参考rfc4585
a=rtcp-fb:98 goog-remb
支持使用rtcp包来控制发送方的码流
a=rtcp-fb:98 transport-cc
参考上面opus
注意
- 由于H264的rtp中不能区分视频流中是否每一帧的图像都连续,对于丢帧的情况无法处理,所以fec+nack会导致fec包丢失后,nack去申请重传fec的包.造成带宽的浪费。
- WebRTC对FEC的冗余度计算是动态的, 会根据丢包情况和网络带宽估计(BWE)的结果动态调整冗余度,
内部会维护一个静态的冗余度表. 冗余度范围: 0-255.(255相当于100%冗余度) - ULPFEC: Uneven Level Protection FEC.
将需要保护的媒体流按照重要性分成若干区域(section),
不同的区域使用不同的保护级别(levels),每个ulpfec可以携带多个级别的保护区域。