做者:潘嘉明
野狗科技嵌入式工程師,曾在TP-Link從事相關工做,在嵌入式研究上經驗豐富。git
一直以來,由於涉及音視頻編解碼、P2P穿越等許多複雜的技術,同時還須要客戶端以及瀏覽器插件的支持,實時視頻通訊的開發成本很高,只有大公司纔會去作。github
WebRTC(http://webrtc.org/) 是 google主推的一個項目,旨在使得瀏覽器能爲實時通訊(RTC)提供簡單的JavaScript接口。有了它,直接經過瀏覽器的 Web 頁面就能夠實現音視頻聊天功能,無需任何插件。web
從著名的瀏覽器兼容性查詢網站caniuse.com能夠查詢到各瀏覽器對WebRTC的支持狀況。其中,Edge瀏覽器支持相似WebRTC的ORTC。能夠說,從市場佔有率來看,大部分場景下都可以使用WebRTC進行通訊。chrome
下面咱們從webrtc的基本原理開始介紹。後端
上圖是一個簡單的 WebRTC 三角關係圖。圖中,兩臺電腦A和B想要創建實時音視頻聊天。因爲它們在不一樣的內網,所以沒法直接創建音視頻管道。它們首先鏈接到一個服務器,WebRTC 稱之爲信令服務器(signal server)。經過信令服務器,兩者交換創建管道的一些必要信息(信令,採用SDP協議編碼),如音視頻格式、幀率,兩者的 ip 地址等。瀏覽器
收到對方信令後,它們分別將其交給 WebRTC 底層,由底層實現兩者間管道的創建。管道創建完成後,數據直接經過管道交互,無需再通過信令服務器。服務器
它們之間交互的流程如上圖:微信
電腦A獲知本身的外網ip和端口,並經過信令服務器向電腦B發送請求(offer 信令)。數據結構
電腦B收到A的請求後,處理A的offer信令,並將結果(answer信令)經過信令服務器返回給A。函數
在此過程當中,WebRTC 底層同時會生成不少 candidate(候選項)信息,candidate信息包括電腦的內網 IP,外網 IP 等。電腦A和B將生成的candidate 也經過信令服務器傳遞給對方。
WebRTC 底層根據這些信息,創建管道。
能夠看出,A和B之間的信令交換須要一個公網服務器來作中轉。然而大部分技術愛好者自行搭建信令交換服務仍是比較複雜的。
咱們注意到,A 和 B 的信令交換實質上就是兩者數據同步的過程, Wilddog的數據通訊服務能夠很好的解決數據同步的問題,那麼經過 Wilddog 就能夠輕鬆實現 A 和 B 的信令交換,很是簡單快捷,還不須要服務器。
關於野狗實時後端雲的使用,這裏就不展開介紹了,有興趣的朋友自行到www.wilddog.com去了解就好。爲了方便處理,咱們在野狗雲端設計下圖的數據結構:
其中的value字段只是示意。真實的value字段是較長的,採用SDP協議編碼的。roomname 爲房間名稱,每一個用戶進入房間後,在房間下面根據本身的userId建立子節點,若是有向其餘用戶通訊的需求,則向其餘用戶的mailbox發送信件。
同時,用戶會監聽自身的mailbox,能夠實時的發現mailbox中來了新的信件,則處理這封信件,須要回覆的話則向對方的mailbox回信。
咱們將offer、answer、candidate這幾種信令都抽象成信件,經過Wilddog的實時同步,將信件同步給對方。總體流程圖以下:
讓咱們以電腦A和B來舉例:
A和B打開瀏覽器後都調用getUserMedia獲取本地視頻流,並在瀏覽器上播放;
B先進入房間,此時房間中沒有其餘用戶,B在房間下創建屬於本身的節點,且監聽本身的信箱;
A進入房間,發現B已存在,此時A調用createOffer生成offer信令,並使用setLocalDescription存儲到本地,而後向B的節點下面的信箱發送offer,同時,A也監聽本身的信箱;
B發現信箱下有信件,查知此信爲A的offer,B調用setRemoteDescription將其存儲到本地,而後使用createAnswer生成answer信令,使用setLocalDescription存儲到本地,而後向A的信箱發送answer;
A發現信箱下有信件,查知此信爲B的answer,A調用setRemoteDescription將其存儲到本地;
與此同時,A和B均可能觸發onicecandidate事件,WebRTC底層會將收集的candidate信令報告給上層,這種信令也須要向對方的信箱發送,對方收到這類信件後,調用addCandidate將之保存到本地;
在收集足夠多的信令後,WebRTC底層會將A和B之間的管道打通,A和B會觸發onaddstream事件,事件的回調函數中,會收到對方的stream流,能夠用來在瀏覽器端播放。
上文描述的基於webrtc的音視頻聊天室的實現源碼在github上供你們參考:https://github.com/itolfh/demo-webrtc-onepeer。這段源碼只實現了一對一視頻聊天。要實現相似視頻會議的多人聊天也很容易,在此基礎上的改動也不會太大。
須要注意的是,在chrome瀏覽器上調用getUserMedia接口,要求頁面必須使用https服務,不能使用http或者本地打開。而使用firefox瀏覽器則無此限制,所以若是採用firefox,能夠將網頁傳給好友並本地打開,兩邊輸入相同房間號,便可以進行實時音視頻聊天。而使用chrome則須要搭建https服務。
使用Wilddog,咱們輕鬆解決了信令服務器的問題,無需服務器,也可以搭建本地視頻聊天室了。然而你們可能會好奇,兩個在不一樣內網的電腦,是如何可以創建管道的?candidate中的ip信息,包括什麼?又是從哪獲取的呢?這些疑問也就是本文開篇時提到的穿越(有的文章中也叫作穿透)的問題了,咱們將在後續的文章中解答你們的疑惑。
關注野狗官方微信,獲取更多技術乾貨