淺談 WebRTC 技術原理與應用
一、技術背景
自 2010 年至今,WebRTC 的出現和發展簡要背景
- 根據 Cisco 預測指數顯示,到 2022 年,視頻將佔所有 IP 流量的 82%,高於目前的 75%。在疫情背景下,線上實時音視頻交互已經是當下和未來重要的交互途徑之一了,比如在線視頻會議。
(線上實時音視頻交互)
- WebRTC(Web Real-Time Communication),即網頁即時通信。 是一個支持網頁瀏覽器 [1] 進行實時語音對話或視頻對話的技術方案。從前端技術開發的視角來看,是一組可調用的 API 標準。
-
在 WebRTC 發佈之前,開發實時音視頻交互應用的成本是非常昂貴,需要考慮的技術問題很多,如音視頻的編解碼問題,數據傳輸問題,延時、丟包、抖動、迴音的處理和消除等,如果要兼容瀏覽器端的實時音視頻通信,還需要額外安裝插件。
-
2010 年 5 月,Google 以 6820 萬美元收購 VoIP 軟件開發商 Global [2]IP[3] Solutions[4] 的 GIPS 引擎,並改爲名爲 “WebRTC”。旨在建立一個互聯網瀏覽器間的實時通信的平臺,讓 WebRTC 技術成爲 H5 標準之一。
-
2012 年 1 月,谷歌已經把這款軟件集成到 Chrome 瀏覽器中,Opera 初步集成 WebRTC。
-
2013 年 6 月,Mozilla Firefox[5] 發佈 22.0 版本正式集成及支持 WebRTC。
-
2017 年 11 月 ,W3C WebRTC 1.0 草案正式定稿。
-
2021 年 1 月,WebRTC 被 W3C 和 IETF 發佈爲正式標準(WebRTC 1.0: Real-Time Communication Between Browsers[6]
(圖引用自 W3C 重點報告,2021.10 版 [7])
- 根據全球領先的技術研究和諮詢公司——Technavio 的關於 “全球網絡實時通信(webrtc)市場” 的研究報顯示,自 2017-2021 年期間,全球網絡實時通信(webrtc)市場,將以 34.37% 的年均複合增長率增長,可謂十分的迅速。
二、簡要特徵
WebRTC 內容豐富,主要的技術特徵包含以下幾點:
1. 實時通訊
是一項實時通訊技術,允許網絡應用或者站點,在不借助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現視頻流和(或)音頻流或者其他任意數據的傳輸。
2. 無依賴 / 插件
WebRTC 包含的這些標準使用戶在無需安裝任何插件或者第三方的軟件的情況下,創建點對點(Peer-to-Peer)的數據分享和電話會議成爲可能。
3. 協議棧 衆多
它並不是單一的協議,包含了媒體、加密、傳輸層等在內的多個協議標準以及一套基於 JavaScript 的 API,它包括了音視頻的採集、編解碼、網絡傳輸、顯示等功能。通過簡單易用的 JavaScript API ,在不安裝任何插件的情況下,讓瀏覽器擁有了 P2P 音視頻和數據分享的能力。
(WebRTC 依賴衆多協議棧圖)
同時 WebRTC 並不是一個孤立的協議,它擁有靈活的信令,可以便捷的對接現有的 SIP 和電話網絡的系統。
三、兼容覆蓋
主流瀏覽器的兼容情況
- 目前大部分主流瀏覽器都正常兼容,如下圖
(瀏覽器兼容性覆蓋圖)
- 主流瀏覽器都支持 WebRTC 標準 API ,因此也讓瀏覽器之間無插件化的音視頻互通成爲可能, 大大降低了音視頻開發的門檻,開發者只需要調用 WebRTC API 即可快速構建出音視頻應用。
四、技術框架
結合技術框架圖來認知和理解官方技術框架的基本內容
如下圖的技術框架描述了 WebRTC 的核心內容和麪向不同開發者的 API 設計。
(技術框架圖)
-
從圖中可看到主要面向三類開發者的 API 設計,包括:
a. 對於 Web 開發者的 API
框架包含了基於 ****JavaScript 、 經過 W3C 認證了的一套 API 標準,使得 web 開發者可以基於這套 API 開發基於 WebRTC 的即時通訊應用。
b. 對於瀏覽器廠商的 API
框架同樣包含了基於 C++ 的底層 WebRTC 接口,對於瀏覽器廠商底層的接入十分友好。
c. 瀏覽器廠商可自定義的部分
框架中還包含瀏覽器廠商可自定義的音視頻截取等擴展部分。
五、核心內容
從上述框架中看到,主要有音頻、視頻引擎和傳輸三部分主要內容,其中又包含衆多的協議和方法等
- WebRTC 主要組成:
-
Voice Engine(音頻引擎)
-
Voice Engine 包含 iSAC/iLBC Codec(音頻編解碼器,前者是針對寬帶和超寬帶,後者是針對窄帶)
-
NetEQ for voice(處理網絡抖動和語音包丟失)
-
Echo Canceler(回聲消除器)/ Noise Reduction(噪聲抑制)
-
Video Engine(視頻引擎)
-
VP8 Codec(視頻圖像編解碼器)
-
Video jitter buffer(視頻抖動緩衝器,處理視頻抖動和視頻信息包丟失)
-
Image enhancements(圖像質量增強)
-
Transport
六、實現原理
-
SRTP(安全的實時傳輸協議,用於音視頻流傳輸)
-
Multiplexing(多路複用)
-
P2P,STUN+TURN+ICE(用於 NAT 網絡和防火牆穿越的)
-
除此之外,安全傳輸可能還會用到 DTLS(數據報安全傳輸),用於加密傳輸和密鑰協商
-
整個 WebRTC 通信是基於 UDP 的
不細緻介紹音視頻採集、編碼和處理等內容,僅介紹實時通訊的建立過程原理的核心內容
1. 公網 IP 映射:明確網絡定位信息
-
WebRTC 是建立瀏覽器端到端的連接(P2P),由於不需要服務器中轉,所以獲取連接對象的網絡地址的方式,是藉助於 ICE、STUN、TURN 等輔助內網穿透技術(NAT)得到對應主機的公網網絡地址和端口等網絡定位信息。明確網絡定位是建立端與端直接通訊的基礎。
(NAT 原理圖)
(STUN 服務器用於輔助內網穿透得到對應主機的公網網絡地址和端口信息圖)
2. 信令服務器:網絡協商與信息交換
- 信令服務器的作用是基於雙工通信來中轉信息。中轉信息包括公網 IP 映射後的網絡定位信息(公網 IP、端口和媒體數據流等。
(概念圖)
(信令服務器信息交互過程圖)
3. 會話描述協議 SDP:統一的媒體協商方式
-
不同端 / 瀏覽器對於媒體流數據的編碼格式各異,如 VP8、VP9 等,參與會話的各個成員的能力不對等、用戶環境與配置不一致等。
-
WebRTC 通訊還需要確定和交換本地和遠程音頻和視頻媒體信息,例如分辨率和編解碼器功能。交換媒體配置信息的信令通過使用會話描述協議 (SDP) 交換 Offer 和 Anwser 來進行。
-
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)
- 一個 SDP 例子如下
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 連接過程爲
(一對一過程圖)
- 簡要過程
(簡要過程圖)
-
交換 SDP,獲取各自媒體配置信息
-
STUN 服務器交換網絡地址和端口等網絡信息
-
Turn 中轉音視頻媒體流數據
-
工作流
(工作流程圖)
-
A 和 B 雙方先調用 getUserMedia 打開本地攝像頭,作爲本地待輸出媒體流;
-
向信令服務器發送加入房間請求;
-
Peer B 接收到 Peer A 發送的 offer SDP 對象,並通過 PeerConnection 的 SetLocalDescription 方法保存 Answer SDP 對象並將它通過信令服務器發送給 Peer A。
-
在 SDP 信息的 offer/answer 流程中,Peer A 和 Peer B 已經根據 SDP 信息創建好相應的音頻 Channel 和視頻 Channel,並開啓 Candidate 數據的收集,Candidate 數據(本地 IP 地址、公網 IP 地址、Relay 服務端分配的地址)。
-
當 Peer A 收集到 Candidate 信息後通過信令服務器發送給 Peer B。同樣的過程 Peer B 對 Peer A 也會再發送一次。
6. 多對多的建立
(多對多建立點到點連接概念圖,以三個用戶點對點的連接爲例)
7. JavaScript 主要接口
- getUserMedia()[8]:訪問數據流,例如來自用戶的相機和麥克風
//請求媒體類型
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);
- RTCPeerConnection[9]:通過加密和帶寬管理工具啓用音頻或視頻通話
// 允許 RTC 服務器配置。
const server = {
"iceServers":
[{ "urls": "stun:stun.stunprotocol.org"}]
};
// 創建本地連接
const localPeerConnection = new RTCPeerConnection(servers);
// 收集Candidate 數據
localPeerConnection.onicecandidate=function(event){
...
}
// 監聽到媒體流接入時的操作
localPeerConnection.ontack=function(event){
...
}
- RTCDataChannel[10]:支持通用數據的點對點通信,常用於數據點到點的傳輸
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 媒體捕獲
- 獲取瀏覽器視頻權限,捕獲本地視頻媒體流,在 Video 元素中附加媒體流,顯示本地視頻結果。
//攝像頭兼容性處理
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
})
(捕獲本地視頻媒體流的顯示結果截圖)
- 爲每個新的客戶端連接創建 RTCPeerConnection 對象
// stun和turn服務器 const iceServer = {
"iceServers": [{
urls:"stun:stun.l.google.com:19302"
}]
};
//爲點到點的連接創建RTCPeerConnection
const peerRTCConn=new RTCPeerConnection(iceServer);
1.2 網絡協商
- 創建對等連接,收集 ICE 候選,等待媒體流接入時掛載到 dom
交互式連通性建立(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。peer 利用 setLocalDescription 方法將會話信息加到 RTCPeerConnection(),並由信令服務器中轉。其他 Peer 會返回相應的 Answer。SDP 過程。
//新加入節點發起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。會話描述包括音視頻信息等內容,當發起者向響應者發出 offer 類型的描述後,響應者會返回 answer 類型的描述
//創建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);
});
- 當收到 ICE 候選共享後,會把 ICE 候選添加到遠程對等點描述中
//對應的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)等普遍認可,對於當下和未來大前端技術發展具有重要的意義
-
降低在 web 端的音視頻交互開發門檻
-
以往的音視頻交互開發對於 Web 開發者而言具有一定技術門檻,
-
現在藉助於 WebRTC,Web 開發者通過調用 JS 接口,可快速的實現音視頻交互應用。
-
-
避免依賴、插件造成的次生問題
-
以往的音視頻交互應用構建依賴於各種插件、軟件和服務器等
-
現在藉助於主流瀏覽器即可形成端到端的音視頻交互
-
-
統一化和標準化對傳統音視頻交互環境差異性的規避
-
以往音視頻交互需要面對不同的 NAT 、防火牆對媒體 P2P 的建立帶來了很大的挑戰
-
現在 WebRTC 中有 P2P 打洞的開源項目 libjingle , 支持 STUN,TURN 等協議
-
-
更高效優化的算法、技術對於音視頻交互性能的提升
- WebRTC 通過 NACK、FEC 技術,避免了經過服務端路由中轉,減少了延遲和帶寬消耗。還有 TCC + SVC + PACER + JitterBuffer 等技術對於音視頻流暢性進行了優化
十、參考
本文檔相關內容參考自下面的衆多文章、項目 Markdown 和代碼等內容,在此一一列出
-
https://github.com/Tinywan/WebRTC-tutorial
-
https://www.bookstack.cn/read/webrtc-book-cn/spilt.6.05_putting_it_all_together.md
-
https://www.html5rocks.com/en/tutorials/webrtc/basics/
-
https://zh.wikipedia.org/wiki/WebRTC
-
https://zhuanlan.zhihu.com/p/93107411
-
https://github.com/muaz-khan/WebRTC-Experiment
-
https://xie.infoq.cn/article/ddceaa09b2c3ec4b357bf0d26
-
https://juejin.cn/post/6969030139120189477
-
https://www.jianshu.com/p/24363820b3b2
-
https://zhuanlan.zhihu.com/p/79489847
-
https://www.researchandmarkets.com/reports/5116130/global-web-real-time-communication-webrtc
十一、QA
-
Q:是否有連接限制?
-
A:有看到在 chrome 會有限制 256 爲最多連接,但更多取決於帶寬等
-
https://stackoverflow.com/questions/16015304/webrtc-peer-connections-limit
-
Q:商業應用現狀?商業應用時的安全性、數據傳輸的解決方案?
-
A:不太瞭解,目前成熟的商業應用比較少,我猜想成熟的商業應用會進步一進行包裝,以滿足商業應用中的安全性、數據傳輸等要求
-
A:WebRTC 對於一對一單聊比較適用,但對於超多人聊天還是有優化空間 https://toutiao.io/posts/489762/app_preview
-
Q:安卓應用兼容性不好
-
A:這個我沒有經驗,但現階段的確有兼容性問題,該技術還有待進一步兼容性優化和成熟應用,我也去再瞭解瞭解。
參考資料
[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