WebRTC-Android 探索 - 建立 P2P 链接中的那些东西都是啥

在上一篇文章介绍在 Android 中建立简单音视频通话程序时提到了建立链接的流程,其中里边含有 SDP、IceCandidate 等概念。本篇文章将会介绍这些概念都是些啥,切均以 Android 开发者的角度进行阐述(实际上是个人 C++ 还正在学习中,具体 Native 我也不少不明白的地方,但愿你们多交流 :D )。

建立 P2P 链接的过程

引用我上篇文章的一幅图:html


很明显,建立 P2P 链接进行通话无非就是如下流程:web

  • 建立 offer 并以信令的方式发送
  • 接受 offer 并建立 answer 且以信令的方式发送
  • 接受 answer
  • 双方以信令的形式交换 candidate
  • 建立 P2P 链接成功,可开始数据交换

其中建立的 offer 和 answer 其实就是 SDP, SDP 其实就是一个字符串,其在 Android 中其实就是由 PeerConnection 的 MediaConstraints 以及以前的 VideoTrack、 AudioTrack 等一些东西决定的,在这些影响下建立初始 SDP 成功时在 SdpObserver#onCreateSuccess 会将编解码相关信息添加进去, setLocalDescription 和 setRemoteDescription 就是将 offer 和 answer 的 SDP 设置到本地,并以此来建立 IceCandidate。bash

什么是 SDP

SDP 的全称为 Session Description Protocol,即会话描述协议,其在 IETF RFC 4566 中定义。WebRTC 使用 SDP 来协商会话的参数,固然因为 WebRTC 是没有信令的,这部份内容须要经过信令服务器传输。SDP 在 WebRTC 会话的设置中起着核心做用。SDP 是用于在 SIP 端点之间交换媒体信息的协议,而且 IETF 和 W3C 也选择它用于在 WebRTC 中交换媒体信息。WebRTC 使用 SDP 通知另外一端在媒体会话中使用哪些传输协议、端口、编解码器和其余参数。如下是一个 SDP 的样例:服务器

v=0
o=-
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS 273ddd94-6b94-4120-9c9a-15fbf94e621d f2a32375-1e7f-4c11-b4ec-557cf1302001
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 102 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:G3gC
a=ice-pwd:UomU3F+mw85MIbCtEvgcdaD6
a=ice-options:trickle renomination
a=fingerprint:sha-256 48:85:66:B4:F4:9F:58:05:99:D2:0F:91:63:A6:B0:B4:78:DD:EA:2A:FA:EE:95:B2:06:86:B2:E9:D3:85:DE:CC
a=setup:actpass
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: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
a=ssrc:1844961268 cname:BKLU8fq6dBaXdEIX
a=ssrc:1844961268 msid:273ddd94-6b94-4120-9c9a-15fbf94e621d ARDAMSa0
a=ssrc:1844961268 mslabel:273ddd94-6b94-4120-9c9a-15fbf94e621d
a=ssrc:1844961268 label:ARDAMSa0
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:G3gC
a=ice-pwd:UomU3F+mw85MIbCtEvgcdaD6
a=ice-options:trickle renomination
a=fingerprint:sha-256 48:85:66:B4:F4:9F:58:05:99:D2:0F:91:63:A6:B0:B4:78:DD:EA:2A:FA:EE:95:B2:06:86:B2:E9:D3:85:DE:CC
a=setup:actpass
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=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:10 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07
a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/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=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 red/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:127 ulpfec/90000
a=ssrc-group:FID 927647579 3068521629
a=ssrc:927647579 cname:BKLU8fq6dBaXdEIX
a=ssrc:927647579 msid:f2a32375-1e7f-4c11-b4ec-557cf1302001 ARDAMSv0
a=ssrc:927647579 mslabel:f2a32375-1e7f-4c11-b4ec-557cf1302001
a=ssrc:927647579 label:ARDAMSv0
a=ssrc:3068521629 cname:BKLU8fq6dBaXdEIX
a=ssrc:3068521629 msid:f2a32375-1e7f-4c11-b4ec-557cf1302001 ARDAMSv0
a=ssrc:3068521629 mslabel:f2a32375-1e7f-4c11-b4ec-557cf1302001
a=ssrc:3068521629 label:ARDAMSv0复制代码

SDP 由文本行组成,每行内容都是 <type>=<value> , type 是一个字母, value 是结构化文本,格式由 type 决定。 具体可见:tools.ietf.org/html/rfc456…app

在此我介绍一下主要的 SDP Attributes:tcp

rtpmap: a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters>]ide

rtcp-fb: 支持的 RTCP Feedback 类型学习

fmtp: a=fmtp:<format> <format specific parameters>测试

msid: a=msid-semantic: WMS <label> google

candidate: 定义 ICE 链接的候选地址和端口 a=candidate:<foundation> <component-id> <transport> <proiority> <connection-address> <port> <cand-type> <network-id> <network-cost>

ssrc: a=ssrc:<attribute> a=ssrc:<attribute>:<value> 这里表明一路 media stream

什么是 IceCandidate

在现实中有不少缘由能致使简单的端到端直连不能直接完成,须要绕过阻止创建链接的防火墙,给设备分配一个惟一可见的地址(一般状况下咱们的大部分设备没有一个固定的公网地址),若是路由器不容许主机直连,还得经过一台服务器转发数据。ICE 就是用于简历链接的 NAT 穿透协议,它会利用 TURN/STUN 协议进行穿透,ICE 服务可让客户端拿到 TURN/ STUN 地址信息便可。

TURN 是经过服务器中转全部数据来达到连通的一种协议,显然服务器开销是很是大的,因此咱们通常在 STUN 无法作到连通的时候才选择它来进行连通。

An interaction between two users of a WebRTC application involving STUN and TURN servers.

STUN 是一个容许位于 NAT 后的客户端找出本身的公网地址来判断路由器阻止直连的限制方法的协议。客户端经过给公网的STUN服务器发送请求得到本身的公网地址信息,Google提供了一个 STUN/ TURN 的实现Coturn。一个免费可用的 STUN 服务:stun:stun.l.google.com:19302

An interaction between two users of a WebRTC application involving a STUN server.

关于 TURN/ STUN/ ICE 更多详细阅读:www.52im.net/thread-557-…

IceCandidate 会在 SDP 中拼上候选的地址和端口并在交换后进行连通测试。连通测试经过后会在 PeerConnection.Observer#onIceConnectionChange 进行回调当前状态。Candidate 就是候选地址和端口了,双方交换后会以此检查连通性。检查连通性完毕后,就能够开始端对端直接交换音视频数据信息啦

关于更多

WebRTC 建立链接的关键就在于 SDP 的建立了,其实 SDP 就是一个字符串而已,因此若是想要作更多自定义的东西,能够直接本身拼接字符串。可能看文档会以为很难理解,你们能够访问 webrtchacks.com/sdp-anatomy… 来理解 SDP。

WebRTC 的核心就在于端对端 P2P 的链接,你们能够去查阅相关 P2P 的资料来理解 WebRTC 的建立原理,好比 NAT 打洞原理。欢迎更多朋友一块儿交流 WebRTC 相关知识,如有错误也但愿各位指正,个人邮箱/QQ:me@york1996.com。

相关文章
相关标签/搜索