當前位置:
首頁 > 最新 > webRTC——瀏覽器里的音視頻通話

webRTC——瀏覽器里的音視頻通話

背景

webRTC 是 Google 在 2010 年收購 GIP 公司之後獲得的一項技術。如下圖所示,它提供了音視頻的採集、處理 (降噪,回聲消除等)、編解碼、傳輸等技術。

webRTC 的目標是實現無需安裝任何插件就可以通過瀏覽器進行 P2P 的實時音視頻通話及文件傳輸,來看看 Google 的 demo,是不是很酷?本文將帶你分析 webRTC 的原理,並逐步編寫一個簡單的 demo。

原理

如圖,瀏覽器之間媒體流的傳輸是 P2P 的,但是這並不意味著 webRTC 不需要伺服器支持。建立 P2P 視頻連接需要的信息,如用來初始化通信的 session 信息,雙方的 ip、埠,視頻解析度,編解碼格式等等,還是需要通過伺服器來傳輸的。webRTC 沒有規定這些信息傳輸的機制,XHR、webSocket、Socket.io 等都是可以的,因為 Socket.io 自帶了房間的概念,便於雙向視頻的撮合,所以我在 demo 里選擇了 Socket.io。

當然,連接建立的過程不會這麼簡單。首先,提到 P2P 就繞不開 NAT(Network Address Translation),webRTC 使用 ICE(Interactive Connectivity Establishment) 框架,ICE 是一種綜合性的 NAT 穿越技術,它整合了 STUN、TURN。當穿越網路時,ICE 會先嘗試 STUN,查出自己位於哪種類型的 NAT 之後以及 NAT 為某一個本地埠所綁定的 Internet 端埠從而建立 UDP 連接,如果失敗了 ICE 就會再嘗試 TCP(先嘗試 HTTP,再嘗試 HTTPS),如果仍然失敗就使用中繼的 TURN 伺服器。

再來看看建立連接過程中的具體步驟:

調用 getUserMedia 獲取本地的 MediaStreams;

從 STUN 獲取自己的外網 IP 及埠,通過 Signaling Server 向對方發送 Offer(SDP 協議),並收到 Answer;

同時 webRTC 會生成一些包含自己的內網、外網 IP 等信息的 candidate,同樣通過 Signaling Server 相互傳輸;

建立 P2P 連接,傳輸媒體信息。

API

getUserMedia: 獲取本地視頻、音頻,可以傳入 constraints 調整解析度、幀率,返回一個 promise;

RTCPeerConnection: 生成一個 RTCPeerConnection 實例,傳輸視頻、音頻流;

createOffer: 會話發起方生成 SDP Offer,包含了本地媒體流信息;

setLocalDescription:在此方法被調用之前 oncandidate 事件不會被觸發;

setRemoteDescription: 接收到 offer 或者 answer 之後調用;

addIceCandidate: 接收到 icecandidate 之後調用;

Steps

獲取媒體流

getUserMedia 存在兼容性問題,需要在項目中引用 webRTC 官方給出的 adapter.js。constraints 還可以配置 video 的解析度、幀率、對移動端還可以選擇前後攝像頭:

定義 RTCPeerConnection

由 STUN、TURN 配置生成對應的 RTCPeerConnection 實例,再定義相關的事件處理函數,如 onicecandidate、onaddstream、onremovestream 等。

創建連接

必須先 getUserMedia 後才能生成 sessionDescription,並且只有在 setLocalDescription 後 onicecandidate 事件才會觸發。上面代碼中的只是為了說明大致流程,實際項目中結合 socket.io 的事件更容易實現。

中斷會話

關於 socket.io 有關的代碼本文沒有貼出,詳情可參考 socket.io 的用法。

可行性

按照上面的步驟可以成功地搭建 webRTC 的小 demo,但是能否將 webRTC 運用到實際項目中去呢?下面從瀏覽器兼容性和 webRTC 本身的性能兩個方面去分析。

兼容性

IOS: 只有最新的 ios11 支持 webRTC,且僅限 safari 瀏覽器,微信內置瀏覽器尚不支持 getUserMedia, 不支持 DataChannel,視頻編解碼格式為 H.264;

Android: 安卓 4.4 以上 (不含 4.4),經測試各大手機廠商自帶瀏覽器均不支持 getUserMedia,但微信內置瀏覽器可以正常運行,另外 61 版本以上的 Chrome for Android 也都支持;

PC: Chrome49 以上,Firefox55 以上,Edge 支持,Safari 只有 11 支持,IE 不支持。

性能

誠然 webRTC 在回聲消除,圖像編解碼等方面已經做得十分出色,但它在性能上的問題還是不可忽視的:

由於需要進行視頻編解碼,所以 CPU 佔用率非常高,尤其是在移動設備上;

在移動設備上獲取的視頻解析度有限,最高只能達到 640 * 480;

帶寬有限時,音視頻質量較差,延時明顯;

綜上所述,雖然 webRTC 具有不需安裝插件或者客戶端,開源免費,強大的網路穿透能力,出色的音視頻處理技術等等優點,但由於兼容性及性能上的問題,要投入到生產中還需要時間,主要是 IOS11 的普及以及 CPU 佔用率和延時的問題。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 JavaScript 的精彩文章:

和 Firebug 說再見 Firefox 宣布 Firebug 的壽命即將終止
前端小白到30K月薪的路徑有哪些
vscode 將在下個穩定版本換回藍色 logo!
希望今天沒有 bug
【Node.js系列】Express 介紹

TAG:JavaScript |