實時音影片WebRTC介紹

  • 2019 年 10 月 7 日
  • 筆記

什麼是 WebRTC

WebRTC (Web Real-Time Communications) 是一項實時通訊技術,它允許網路應用或者站點,在不藉助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現影片流和(或)音頻流或者其他任意數據的傳輸。WebRTC包含的這些標準使用戶在無需安裝任何插件或者第三方的軟體的情況下,創建點對點(Peer-to-Peer)的數據分享和電話會議成為可能。

簡而言之,WebRTC就是W3C定的一個Web標準,用來做二進位數據傳輸用的,各瀏覽器只要支援WebRTC,就可以不通過插件,直接在Web端實現諸如音頻、影片、文件等二進位數據的傳輸。方便之處在於:不需要再使用Flash、Silverlight之類的插件了。but!理想很豐滿,現實往往很殘酷,WebRTC從誕生之初到現在仍然還有很多地方布滿了坑。

step1. 開通雲服務

小程式跟 WebRTC 的互通是基於實時音影片(TRTC)服務實現的,需要開通該服務。

註冊帳號之前點先領取騰訊雲2860元代金券,用於購買騰訊雲CVM雲伺服器、雲資料庫產品時可以用來抵用,節約財務成本。

WebRTC使用要求

1. 支援WebRTC的Web運行環境

越簡單越容易忽略,必須要強調說明,並不是所有的Web運行環境都支援WebRTC,支援WebRTC的Web運行環境也不一定會支援所有的API及特性,因此,先要確定Web運行環境是否能支援,可以通過檢測頁面看一下(需要翻牆,覆蓋了WebRTC幾乎所有API方法)或騰訊雲WebRTCAPI.js的檢查。

2. HTTPS

出於安全考慮,WebRTC只允許在HTTPS環境下使用,否則瀏覽器將不允許頁面獲取音頻或影片設備,調試時請使用HTTPS或localhost。

3. 數據對象

數據對象指的是瀏覽器能夠管理的輸入/輸出設備,因為 WebRTC 的設備管理方式是瀏覽器先將輸入/輸出設備抽象為 MediaStream 對象,再通過 API 將 MediaStream 對象提供給 Web 頁面使用,如果瀏覽器無法識別到設備,那麼 Web 頁面必然是獲取不到數據的。

WebRTC 流程

WebRTC 的工作流程,如下圖。詳見WebRTC通訊流程

看上去比較複雜,可以花時間理解一下交互過程。簡單來說分兩部分:

  • 信令通道 什麼叫信令?比如說發起通話、結束通話、響鈴、佔線、掛斷、成員新增、成員減少等等通話相關的資訊同步,這些就是信令。 WebRTC 標準並沒有強制規定如何傳遞信令,只是建議使用 SIP 和 SDP 協議,SIP 和 SDP 具體是什麼這裡先不多作介紹,先知道它們可以做通話信令就行。通常,WebRTC 服務商使用的是 websocket 來做信令通道。
  • 數據通道 數據通道就是用於傳輸 MediaStream 對象的通道,MediaStream 對象可以是音頻、影片、文件、消息等等二進位數據。數據通道方面 WebRTC 標準規定了使用 RTCPeerConnection 來實現,即通過 P2P 直連的方式進行數據傳輸。 P2P 直連過程,打洞是肯定要做的事情,一般打洞的方式都是使用ICE。

這裡以騰訊雲當前提供的 WebRTC SDK 即 WebRTCAPI.js 為例 ,簡述一下其工作過程如下:

1、 SDK 封裝的 getLocalStream 是通過瀏覽器的 MediaDevice 和 getUserMedia 標準方法來得到設備的數據( MediaStream 對象),通過 getLocalStream 拿到 MediaStream 對象後將其賦值給頁面的 <video> 標籤元素的 srcObject 屬性即可顯示播放,在本地進行預覽;

2、SDK 與服務端通過 websocket 方式建立信令通道,SDK 封裝的方法為 enterRoom;

3、wss 連接建立後,SDK 會與服務端進行 SDP 協商,交換雙方的音影片支援能力及相關參數;

4、 SDP 協商成功後,SDK 與服務端節點建立 RTCPeerConnection,這個過程會有 P2P 打洞(ICE),為了提高打洞成功率,服務端提供了 STUN 伺服器,SDK 會與伺服器 P2P 直連後進行數據收發,SDK 封裝的的方法是 startRTC ;

5、每個加入房間的用戶,都會先按照 1-4 步,與服務端建立 wss 連接傳遞信令,同時通過 RTCPeerConnection 將數據發送到服務端。新進入用戶後,已經在房間里的用戶(包括新加入成功的用戶)將會通過 wss 接收到其他用戶進入房間的通知;

6、然後每個用戶會與服務端協商 SDP 資訊,協商成功後,服務端會將遠端的用戶數據通過 RTCPeerConnection.onTrack 傳輸給每個在房間的用戶,SDK 將其封裝在 onRemoteStreamUpdate 事件;用戶通過 onRemoteStreamUpdate 獲取到遠端的 MediaStream 對象,然後將其賦值給頁面的 <video> 標籤元素,展示遠端用戶的畫面;

7、上面的 1-6 步即從開始到通話的過程,在通話過程中間,如果有人員退出,SDK 會通過 wss 收到服務端的通知,並通過 onRemoteStreamRemove 得知變化,在本地移除  <video> 標籤,直至最終所有人停止推流(stopRTC)退出(quit)。

WebRTC 坑點

  1. 不是所有瀏覽器都支援WebRTC
  2. 不是所有支援WebRTC的瀏覽器都支援全部的標準方法
  3. 同一款瀏覽器的桌面版與行動版對WebRTC支援不同
  4. 同一款、同一端的瀏覽器不同版本號對WebRTC支援不同
  5. 不能被瀏覽器識別的輸入設備Web頁面必然拿不到
  6. 不能被瀏覽器支援的編解格式必然顯示不了,瀏覽器支援的格式影片有H.264/VP8/VP9,音頻有Opus/iSAC(理解一下,現在的WebRTC不適合做直播的原因之一)
  7. WebRTC必然要打洞,不支援P2P直連的網路不支援。我們後面會做免打洞方案,雖然本質上也是P2P,不過不是直連
  8. WebRTC標準帶了安全校驗,必須走https,調試可以走localhost
  9. 畫面不顯示,有可能是沒有拿到數據,也可能是  <video> 標籤沒有處理好
  10. 常見問題看 騰訊文檔

排查手段

設備拿不到

  1. 根據原理,直接在頁面打開控制台,輸入 navigator.mediaDevices.enumerateDevices() 看看能不能獲取到設備列表,拿不到說明瀏覽器都沒有識別到設備,檢查瀏覽器或檢查設備;
  2. 能拿到設備列表的情況下,輸入 navigator.mediaDevices.getUserMedia({"audio":true,"video":true}) 看能不能正常返回 MediaStream 對象,不能正常返回說明瀏覽器沒有拿到數據,檢查一下瀏覽器的配置。

畫面顯示不了

  1. 先確認的確有拿到數據
  2. 根據原理,檢查  <video> 元素的 srcObject 屬性是否正常賦值了正確的 mediastream 對象,不對的話肯定顯示不了;
  3. 有部分情況是瀏覽器的問題,檢查一下瀏覽器是不是編解碼器掛了,一般重啟瀏覽器,或重啟系統(設備被其他進程佔用時就不能用),chrome如果硬體編解碼不行的時候,可以在 chrome://flags 裡面把 #enable-webrtc-h264-with-openh264-ffmpeg 這個標記設置為 enable ,強制軟體編解碼,不過看標記名字也知道,使用的是ffmpeg調用openh264庫,性能消耗會有點大。

回聲

  1. 同一房間收發的人隔得太近的時候,請離遠一點;
  2. 有可能是把自己的聲音播放出來了,檢查本地音頻,靜音muted。
  3. 某些設備上有回聲,沒辦法,編解碼是瀏覽器控制的,SDK沒辦法控制,需要等瀏覽器廠商來解決。

網路

  1. 網路連接不上的,先檢查防火牆。有些P2P直連不成功的網路(對稱型NAT的),這種建議先換網路;
  2. 網路抗抖動能力覺得不好的,WebRTC 的網路傳輸是瀏覽器控制,其自帶的QoS是NetEQ,這個東西已經上了年紀,而且演算法簡單粗暴,能夠抵抗一定程度的網路抖動,但抗抖動能力有限,稍微多一點就不行了,加上瀏覽器的 <video>在渲染和顯示機制上有點坑,所以最終畫面顯示效果受很容易受網路影響,因此在當前WebRTC標準還不是特別完善的情況下,網路一定要好一點。

畫面模糊

設備採集、編解碼、網路都在瀏覽器手裡攥著,SDK沒辦法控制,所以,盡量保持設備好、瀏覽器好、網路好。

小程式跟 WebRTC 的互通是基於實時音影片(TRTC)服務實現的,需要開通該服務。

註冊帳號之前點先領取騰訊雲2860元代金券,用於購買騰訊雲CVM雲伺服器、雲資料庫產品時可以用來抵用,節約財務成本。

1、騰訊雲產品3折特惠,熱門雲產品3折起,服務更穩,速度更快,價格更優

2、騰訊雲伺服器鉅惠,助力中小微企業發展

step7. Chrome 對接

了解騰訊雲官網的 webrtc 服務,可以對接 Chrome 端的 H5 影片通話,因為不是本文檔的重點,此處不做贅述。

Tags: