淺談 WebRTC 技術原理與應用

一、技術背景

自 2010 年至今,WebRTC 的出現和發展簡要背景

(線上實時音視頻交互)

(圖引用自 W3C 重點報告,2021.10 版 [7])

二、簡要特徵

WebRTC 內容豐富,主要的技術特徵包含以下幾點:

1. 實時通訊

是一項實時通訊技術,允許網絡應用或者站點,在不借助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現視頻流和(或)音頻流或者其他任意數據的傳輸。

2. 無依賴 / 插件

WebRTC 包含的這些標準使用戶在無需安裝任何插件或者第三方的軟件的情況下,創建點對點(Peer-to-Peer)的數據分享和電話會議成爲可能。

3. 協議棧 衆多

它並不是單一的協議,包含了媒體、加密、傳輸層等在內的多個協議標準以及一套基於 JavaScript 的 API,它包括了音視頻的採集、編解碼、網絡傳輸、顯示等功能。通過簡單易用的 JavaScript API ,在不安裝任何插件的情況下,讓瀏覽器擁有了 P2P 音視頻和數據分享的能力。

(WebRTC 依賴衆多協議棧圖)

TTpdI5

同時 WebRTC 並不是一個孤立的協議,它擁有靈活的信令,可以便捷的對接現有的 SIP 和電話網絡的系統。

三、兼容覆蓋

主流瀏覽器的兼容情況

(瀏覽器兼容性覆蓋圖)

四、技術框架

結合技術框架圖來認知和理解官方技術框架的基本內容

如下圖的技術框架描述了 WebRTC 的核心內容和麪向不同開發者的 API 設計。

(技術框架圖)

五、核心內容

從上述框架中看到,主要有音頻、視頻引擎和傳輸三部分主要內容,其中又包含衆多的協議和方法等

  1. Voice Engine(音頻引擎)

  2. Voice Engine 包含 iSAC/iLBC Codec(音頻編解碼器,前者是針對寬帶和超寬帶,後者是針對窄帶)

  3. NetEQ for voice(處理網絡抖動和語音包丟失)

  4. Echo Canceler(回聲消除器)/ Noise Reduction(噪聲抑制)

  5. Video Engine(視頻引擎)

  6. VP8 Codec(視頻圖像編解碼器)

  7. Video jitter buffer(視頻抖動緩衝器,處理視頻抖動和視頻信息包丟失)

  8. Image enhancements(圖像質量增強)

  9. Transport

六、實現原理

  1. SRTP(安全的實時傳輸協議,用於音視頻流傳輸)

  2. Multiplexing(多路複用)

  3. P2P,STUN+TURN+ICE(用於 NAT 網絡和防火牆穿越的)

  4. 除此之外,安全傳輸可能還會用到 DTLS(數據報安全傳輸),用於加密傳輸和密鑰協商

  5. 整個 WebRTC 通信是基於 UDP 的

不細緻介紹音視頻採集、編碼和處理等內容,僅介紹實時通訊的建立過程原理的核心內容

1. 公網 IP 映射:明確網絡定位信息

(STUN 服務器用於輔助內網穿透得到對應主機的公網網絡地址和端口信息圖)

2. 信令服務器:網絡協商與信息交換

(概念圖)

(信令服務器信息交互過程圖)

3. 會話描述協議 SDP:統一的媒體協商方式

//SDP的結構體
Session description(會話級別描述)
         v=  (protocol version)
         o=  (originator and session identifier)
         s=  (session name)
         c=(connection information -- not required if included in all media)
         One or more Time descriptions ("t=" and "r=" lines; see below)
         a=(zero or more session attribute lines)
         Zero or more Media descriptions

Time description
         t=  (time the session is active)

Media description(媒體級別描述), if present
         m=  (media name and transport address)
         c=(connection information -- optional if included at session level)
         a=(zero or more media attribute lines)
v=0 //代表版本,目前一般是`v=0`.
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0 //會話處於活動狀態的時間
a=group:BUNDLE audio video //:描述服務質量,傳輸層複用相關信息
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126 // ... 

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh81

4. 一對一連接建立過程

以建立一對一的 Web RTC 連接過程爲

(一對一過程圖)

(簡要過程圖)

(工作流程圖)

  1. A 和 B 雙方先調用 getUserMedia 打開本地攝像頭,作爲本地待輸出媒體流;

  2. 向信令服務器發送加入房間請求;

  3. Peer B 接收到 Peer A 發送的 offer SDP 對象,並通過 PeerConnection 的 SetLocalDescription 方法保存 Answer SDP 對象並將它通過信令服務器發送給 Peer A。

  4. 在 SDP 信息的 offer/answer 流程中,Peer A 和 Peer B 已經根據 SDP 信息創建好相應的音頻 Channel 和視頻 Channel,並開啓 Candidate 數據的收集,Candidate 數據(本地 IP 地址、公網 IP 地址、Relay 服務端分配的地址)。

  5. 當 Peer A 收集到 Candidate 信息後通過信令服務器發送給 Peer B。同樣的過程 Peer B 對 Peer A 也會再發送一次。

6. 多對多的建立

(多對多建立點到點連接概念圖,以三個用戶點對點的連接爲例)

7. JavaScript 主要接口

//請求媒體類型
const constraints = {
  video: true
  audio:true
};

const video = document.querySelector('video');

//掛載流到相應dom展示本地媒體流
function handleSuccess(stream) {
  video.srcObject = stream;
}

function handleError(error) {
  console.error('getUserMedia error: ', error);
}
//利用攝像頭捕獲多媒體流
navigator.mediaDevices.getUserMedia(constraints).
  then(handleSuccess).catch(handleError);
// 允許 RTC 服務器配置。
const server = { 
    "iceServers": 
            [{ "urls""stun:stun.stunprotocol.org"}] 
};

// 創建本地連接
const localPeerConnection = new RTCPeerConnection(servers);

// 收集Candidate 數據
localPeerConnection.onicecandidate=function(event){
    ...
}
// 監聽到媒體流接入時的操作
localPeerConnection.ontack=function(event){
    ...
}
const pc = new RTCPeerConnection();
const dc = pc.createDataChannel("my channel");
//接受數據
dc.onmessage = function (event) {
  console.log("received: " + event.data);
};
//打開傳輸
dc.onopen = function () {
  console.log("datachannel open");
};
//關閉傳輸
dc.onclose = function () {
  console.log("datachannel close");
};

七、應用案例

多人視頻案例爲實踐應用

1. 設計框架

(多人視頻基本框架圖)

2. 關鍵代碼

1.1 媒體捕獲

//攝像頭兼容性處理
navigator.getUserMedia = ( navigator.getUserMedia ||
               navigator.webkitGetUserMedia ||
               navigator.mozGetUserMedia ||
               navigator.msGetUserMedia);
// 獲取本地音頻和視頻流
navigator.mediaDevices.getUserMedia({
                "audio": false,
                "video"true
}).then( (stream)={
//顯示自己的輸出流,掛到頁面Video元素上
    document.getElementById("myVido").srcObject=stream
})

(捕獲本地視頻媒體流的顯示結果截圖)

 // stun和turn服務器  const iceServer = {
    "iceServers"[{
        urls:"stun:stun.l.google.com:19302"
    }]
};
//爲點到點的連接創建RTCPeerConnection
const peerRTCConn=new RTCPeerConnection(iceServer);

1.2 網絡協商

交互式連通性建立(Interactive Connectivity Establishment — ICE)是一個允許實時對等端發現對方並且彼此連接的框架。此技術允許對等方發現有關彼此拓撲的足夠信息,從而有可能在彼此之間找到一條或多條通信路徑。ICE 代理負責:收集本地 IP,端口元組候選、在同級之間執行連接檢查和發送連接保持活動

 // 發送ICE候選到其他客戶端 peerRTCConn.onicecandidate = function(event){
    if (event.candidate) {
        //向信令服務器轉發收集到的ICE候選          socket.send(JSON.stringify({
            "event""relayICECandidate",
            "data"{
                'iceCandidate'{
                    'sdpMLineIndex': event.candidate.sdpMLineIndex,
                    'candidate': event.candidate.candidate
                }
            },
            "fromID":signalMsg['data']['peerId']
        }));
    }
}
//有媒體流介入就掛載dom peerRTCConn.ontrack=function(event){
    let v=document.createElement("video")
    v.autoplay=true
    v.style="width:200px"
    
    document.getElementById("peer").appendChild(v)
    v.srcObject=event.streams[0]
}

1.3 媒體協商

 //新加入節點發起offer  if(canOffer){
    peerRTCConn.createOffer(
        function (localDescription) { 
             peerRTCConn.setLocalDescription(localDescription,
                function() { 
                    //發送描述信息給信令服務器                         socket.send(JSON.stringify({
                        "event":"relaySessionDescription",
                        "data":localDescription,
                        "fromID":peerId
                    }))
                 },
                function() { alert("offer failed"); }
            );
        },
        function (error) {
            console.log("error sending offer: ", error);
        }
    )
}
//創建Answer會話
peer.createAnswer(
function(_remoteDescription) {
     peer.setLocalDescription(_remoteDescription,
        function() { 
               //發送描述信息給信令服務器                  socket.send(JSON.stringify({
                    "event":"relaySessionDescription",
                    "data":_remoteDescription,
                    "callerID":signalMsg['fromId'],
                    "fromID":signalMsg['fromId']
                }))        },
        function() { alert("answer failed"); }
    );
},
function(error) {
    console.log("error creating answer: ", error);
});
 //對應的RTCPeerConnection
const peer = peers[signalMsg["fromID"]];
//ICE候選添加到遠程對等點描述
peer.addIceCandidate(new RTCIceCandidate(signalMsg["data"].iceCandidate));

(多人視頻結果截圖 <本地模擬效果>)

1.4 信令中轉

wss.on('connection'function (ws) { 
    ws.on('message'function (message) { 
        let meeageObj=JSON.parse(message)
        //交換ICE候選         if (meeageObj['event'] =='relayICECandidate') {             wss.clients.forEach(function (client) {
                console.log("send iceCandidate")
                    client.send(JSON.stringify({
                        "event""iceCandidate",
                        "data": meeageObj['data'],
                        "fromID": meeageObj['fromID']
                    }));          
            });
        }
        //交換SDP         if (meeageObj['event'] =='relaySessionDescription') {
            console.log(meeageObj["fromID"],meeageObj["data"].type) 
            wss.clients.forEach(function (client) {
                if (client!=ws) {
                    client.send(JSON.stringify({
                        "event""sessionDescription",
                        "fromId":meeageObj["fromID"],
                        "data": meeageObj["data"],
                    }));
                }
            });
        }
    })
})

八、應用場景

WebRTC 在當下和未來具有豐富的應用場景,此文檔不再贅述,可見下面 URL 的內容

https://webrtcforthecurious.com/zh/docs/08-applied-webrtc/

九、重要意義

WebRTC 的出現、發展和被業內標準(如 W3C)等普遍認可,對於當下和未來大前端技術發展具有重要的意義

  1. 降低在 web 端的音視頻交互開發門檻

    1. 以往的音視頻交互開發對於 Web 開發者而言具有一定技術門檻,

    2. 現在藉助於 WebRTC,Web 開發者通過調用 JS 接口,可快速的實現音視頻交互應用。

  2. 避免依賴、插件造成的次生問題

    1. 以往的音視頻交互應用構建依賴於各種插件、軟件和服務器等

    2. 現在藉助於主流瀏覽器即可形成端到端的音視頻交互

  3. 統一化和標準化對傳統音視頻交互環境差異性的規避

    1. 以往音視頻交互需要面對不同的 NAT 、防火牆對媒體 P2P 的建立帶來了很大的挑戰

    2. 現在 WebRTC 中有 P2P 打洞的開源項目 libjingle , 支持 STUN,TURN 等協議

  4. 更高效優化的算法、技術對於音視頻交互性能的提升

    1. WebRTC 通過 NACK、FEC 技術,避免了經過服務端路由中轉,減少了延遲和帶寬消耗。還有 TCC + SVC + PACER + JitterBuffer 等技術對於音視頻流暢性進行了優化

十、參考

本文檔相關內容參考自下面的衆多文章、項目 Markdown 和代碼等內容,在此一一列出

  1. https://github.com/Tinywan/WebRTC-tutorial

  2. https://www.bookstack.cn/read/webrtc-book-cn/spilt.6.05_putting_it_all_together.md

  3. https://www.html5rocks.com/en/tutorials/webrtc/basics/

  4. https://zh.wikipedia.org/wiki/WebRTC

  5. https://zhuanlan.zhihu.com/p/93107411

  6. https://github.com/muaz-khan/WebRTC-Experiment

  7. https://xie.infoq.cn/article/ddceaa09b2c3ec4b357bf0d26

  8. https://juejin.cn/post/6969030139120189477

  9. https://www.jianshu.com/p/24363820b3b2

  10. https://zhuanlan.zhihu.com/p/79489847

  11. https://www.researchandmarkets.com/reports/5116130/global-web-real-time-communication-webrtc

十一、QA

參考資料

[1] 網頁瀏覽器: https://zh.wikipedia.org/wiki/%E7%B6%B2%E9%A0%81%E7%80%8F%E8%A6%BD%E5%99%A8

[2] Global : https://zh.wikipedia.org/wiki/Global_IP_Solutions

[3] IP: https://zh.wikipedia.org/wiki/Global_IP_Solutions

[4] Solutions: https://zh.wikipedia.org/wiki/Global_IP_Solutions

[5] Mozilla Firefox: https://zh.wikipedia.org/wiki/Mozilla_Firefox

[6] WebRTC 1.0: Real-Time Communication Between Browsers: https://www.w3.org/TR/2021/REC-webrtc-20210126/

[7] 2021.10 版: https://www.w3.org/2021/10/w3c-highlights/zh.Overview.html

[8] getUserMedia(): https://webrtc.github.io/samples/src/content/getusermedia/gum/

[9] RTCPeerConnection: https://webrtc.github.io/samples/src/content/peerconnection/pc1/

[10] RTCDataChannel: https://webrtc.github.io/samples/src/content/datachannel/basic/

歡迎關注公衆號 ELab 團隊 收貨大廠一手好文章~

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cviG0xFTTpmXeNO8nJaIIg