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。

相關文章
相關標籤/搜索