WebRTC已成為HTML5標準?是時候開始學習了?

1。什麼是 WebRTC?

WebRTC 是一組 JavaScript API,可以在兩個瀏覽器之間建立點對點連線, 實現音訊和影片等資料的傳輸,可以用它建立有語音/影片通話功能的應用程式。

WebRTC 的特別之處是,一旦建立了連線,就可以直接在瀏覽器之間實時傳輸資料,不需要藉助伺服器,因此降低了延遲,所以使用者都喜歡用 webRTC 直接傳輸音影片。

在WebRTC誕生之前,開發實時音影片應用的成本是非常高,需要考慮的技術問題很多,如音影片的編解碼,

資料傳輸延時、丟包、網路抖動、迴音處理和消除

等,如果要相容瀏覽器端的實時音影片通訊,還需要額外安裝外掛。可喜的是,本文的主角WebRTC在2021年1月被W3C和IETF釋出為正式標準,而且得到了大多數主流瀏覽器的支援。

WebRTC已成為HTML5標準?是時候開始學習了?

CanIUse中WebRTC的瀏覽器支援情況

2。WebRTC 與 WebSockets的區別

在討論 WebRTC 的工作原理之前,先看看 WebRTC 和 WebSockets 的對比,因為很多人都會覺得“聽著跟 WebSockets 一樣,用 WebSockets 就好了,為什麼需要 WebRTC ”?

WebRTC已成為HTML5標準?是時候開始學習了?

使用 websockets 也可以建立點對點連線,實時傳輸資料,但這種連線是在客戶端和伺服器之間。因此,如果我向某一對等點發送訊息,這個訊息會先傳送到伺服器,然後伺服器再把這個訊息傳送給另一個對等點。通常來說,這種傳輸非常快,如果大家傳送的是聊天資訊或某些通知,即使有一些延遲也注意不到。

但如果我們用 websockets 傳輸音影片情況就不一樣了。用 websockets 傳輸音影片時,即使有非常輕微的延遲也會非常明顯,還會導致很多其他問題。當影片資料到達伺服器並返回對等點時,使用者會感覺到明顯的延遲。

而這就是 webRTC 的優勢所在,在兩個瀏覽器之間建立連線並直接交換資料,消除了伺服器可能導致的延遲,WebRTC 還使用了使用者資料報協議(UDP),這些都有利於資料的快速傳輸。

通常WebRTC會與WebSocket配合使用,WebSocket的作用主要是用來交換客戶端的SDP與網路資訊,Websocket傳輸的內容與真正通訊資料無關,只是協助WebRTC建立連線。

3。用 webRTC 傳輸資料這麼快,為什麼還需要 websockets?

webRTC 有一定的侷限性,所以通常會同時使用 webRTC 和 websockets。

首先,webRTC 使用 UDP,但是用 UDP 傳輸重要資料會有點不太可靠。UDP 的優勢在於傳輸資料非常快,劣勢在於它不檢查資料是否被成功接收。所以,可以用 UDP 來傳輸影片,就算傳輸過程中丟失了幾幀,也沒啥大問題;但如果是傳送檔案,丟失幾個位元組的資料就會導致整個檔案的損壞。

另外,WebRTC 沒有內建信令,所以只用 WebRTC 沒法建立點對點的連線,但一旦建立了連線,WebRTC 就可以處理所有問題,至於如何傳輸初始資料來連線兩個對等點則由我們決定。

WebRTC已成為HTML5標準?是時候開始學習了?

4。兩個客戶端之間傳送什麼,如何傳送?

首先,資訊的傳送通常是透過一個叫做信令的過程。由於兩個對等點不瞭解對方的情況,我們通常會使用 WebSockets 或其他第三方信令服務將兩個對等點引入同一個頻道。

當把兩個對等點引入同一個頻道或房間時,他們就可以透過連線細節發出訊號。這些連線細節以會話描述協議(SDP)和 ICE (Interactive Connectivity Establishment,互動式連線建立)候選人的形式出現。

SDP ——會話描述協議(SDP),是一個包含會話連線(如編解碼器、地址、媒體型別、音訊和影片等)資訊的物件。兩個對等點會交換 SDP 來了解如何實現連線。一個是 SDP Offer 形式,另一個是 SDP Answer 形式。

ICE 候選人——ICE 候選人是公共 IP 地址和埠,可以做接收資料的地址。通常來說,每個使用者會有多個 ICE 候選人,這些 ICE 候選人是向 STUN 伺服器發出一系列請求來收集的。

WebRTC已成為HTML5標準?是時候開始學習了?

5。事件發生順序

首先,兩個對等點會使用某種信令方法來傳輸 SDP。一旦兩個 SDP 傳輸完成,對等點就連線成功,但這時還不能傳輸資料。

要在兩個對等點之間交換資料,我們要先傳輸資料。問題是,現在大多數裝置都位於防火牆和 NAT 裝置後面,因此,為了協調公共 IP 地址的發現,我們使用 ICE (Interactive Connectivity Establishment,互動式連線建立)方法。

一旦後臺傳輸了 SDP 提議,每個對等點就會向 STUN 伺服器發出一系列請求,該伺服器會生成一個 ICE 候選人列表。STUN 伺服器的成本很低,並且容易維護,有非常多的免費服務,所以大家可以設定一個。

一旦對等點 1 從 STUN 伺服器獲得這些 ICE 候選人,就會把這些候選人傳送給對等點 2,讓網路決定要使用的最佳候選人。對等點 2 會進行同樣的操作,請求 ICE 候選人,然後將其傳送給等點 1。

當這些候選人傳輸成功並發現一條最佳路徑時,資料就可以開始在兩個對等點之間流動。

5。WebRTC API呼叫

5。1 RTCPeerConnection

RTCPeerConnection用於點對點之間建立連線以傳輸音影片資料流,這是RTCPeerConnection的任務,為此需要藉助一個信令伺服器(signaling server)來進行,信令包括3種類型的資訊:

Session control messages: 初始化和關閉通訊,及報告錯誤;

Network configuration: 雙方的IP地址和埠號(區域網內部IP地址需轉換為外部的IP地址);

Media capabilities: 雙方的瀏覽器支援使用何種編碼以及多高的影片解析度。

var PeerConnection = window。RTCPeerConnection || window。mozRTCPeerConnection || window。webkitRTCPeerConnection;navigator。getUserMedia = navigator。getUserMedia ? “getUserMedia” : navigator。mozGetUserMedia ? “mozGetUserMedia” : navigator。webkitGetUserMedia ? “webkitGetUserMedia” : “getUserMedia”;var v = document。createElement(“video”);// 建立信令(createOffer)var pc = new PeerConnection();pc。addStream(video);pc。createOffer(function(desc) { pc。setLocalDescription(desc, function() { // send the offer to a server that can negotiate with a remote client });})// 建立回覆(createAnswer)var pc = new PeerConnection();pc。setRemoteDescription(new RTCSessionDescription(offer), function() { pc。createAnswer(function(answer) { pc。setLocalDescription(answer, function() { // send the answer to the remote connection }); });})

5。2 RTCDataChannel

RTCDataChannel 介面代表在兩者之間建立了一個雙向資料通道的連線,可以用 RTCPeerConnection。createDataChannel() 或者在現有的 RTCPeerConnection 上用 RTCDataChannelEvent 型別的 datachannel 事件接收,創建出 RTCDataChannel 型別的物件。

var pc = new RTCPeerConnection();// 獲取RTCPeerConnection物件var dc = pc。createDataChannel(“my channel”);// 建立DataChannel物件dc。onmessage = function (event) { console。log(“received: ” + event。data);};dc。onopen = function () { console。log(“datachannel open”);};dc。onclose = function () { console。log(“datachannel close”);};

5。3 訪問使用者攝像頭及麥克風getUserMedia

WebRTC支援直接傳輸音訊流和影片流(https://appr。tc/):

const pc = new RTCPeerConnection() ;// 獲取RTCPeerConnectionnavigator。getUserMedia({ video: true }, stream => { // 新增影片流到會話中 stream。getTracks()。forEach(track => pc。addTrack(track, stream)) // 在網頁中預覽自己攝像頭拍攝到的內容,其中$localVideo表示一個Video物件 $localVideo。srcObject = stream; })

navigator。getUserMedia()還可以和web Audio API相結合,用來處理音訊效果:

var range = document。querySelector(‘input’);window。AudioContext = window。AudioContext || window。webkitAudioContext;var audioCtx = new AudioContext();navigator。getUserMedia({ audio: true}, function(stream) { // 建立音訊流 var source = audioCtx。createMediaStreamSource(stream); // 雙二階濾波器 var biquadFilter = audioCtx。createBiquadFilter(); biquadFilter。type = ‘lowshelf’; biquadFilter。frequenc。value = 1000; biquadFilter。gain。value = range。value; source。connect(biquadFilter); biquadFilter。connect(audioCtx。destination);}, function(error) { console。log(error);});

其實,WebRTC並不只是用來做影片、音訊,它還可以用來傳輸任意資料,包括檔案,文字等。上面程式碼示例可以看到,WebRTC規定了

dataChannel

這個雙工資料通道,而https://snapdrop。net/這個網站就是透過WebRTC進行檔案分享。

const pc = new RTCPeerConnection() const dataChannel = pc。createDataChannel(‘chat’) // 監聽datachannel事件pc。addEventListener(‘datachannel’, event => { // 接收通訊方傳送過來的資料 event。channel。addEventListener(‘message’, event => { console。log(‘message’, event。message) }) }) dataChannel。addEventListener(‘open’, () => { // 傳送資料,可傳送任意資料 dataChannel。send(‘Hi!’) }) dataChannel。addEventListener(‘close’, event => { })

參考資料

https://medium。com/agora-io/how-does-webrtc-work-996748603141

https://www。agora。io/cn/community/blog/24640

https://www。yuque。com/guiqulaixi-2ciw1/ltzgfd/xqgx3h9zdwxxszd9

https://developer。mozilla。org/en-US/docs/Web/API/RTCDataChannel

https://caniuse。com/?search=WebRTC

https://www。jianshu。com/p/1022f559a805

https://zhuanlan。zhihu。com/p/421503695

https://github。com/nashaofu/webrtc-demo

https://blog。csdn。net/xyphf/article/details/107297616