首頁>技術>

0.引言

本篇文章主要講解webrtc框架,基本原理,關鍵介面等,如果對webrtc不熟,可以透過本篇文章建立一個認識。

1.簡述Webrtc

WebRTC(Web Real­Time Communication)是 Google於2010以6829萬美元從 Global IP Solutions 公司購買,並於2011年將其開源,旨在建立一個網際網路瀏覽器間的實時通訊的平臺,讓 WebRTC技術成為 H5標準之一。目前很多公司都基於WebRTC定製了音影片通話的SDK和解決方案。從官網上的描述我們可以知道,WebRTC是一個免費的開放專案,它透過簡單的API為瀏覽器和移動應用程式提供實時通訊(RTC)功能。

官網連結:

https://webrtc.org

官網截圖和原始碼編譯介紹,如下:

注意:國內是很難訪問webrtc官網,除非翻牆,但是要下載下來估計也要費很大力氣。這裡推薦一個國內可以訪問的,就是聲網提供的webrtc映象(與谷歌官網同步),連結如下:

https://webrtc.org.cn/mirror/

預覽介面如下:

在這裡也感謝聲網能夠給予支援,不然搭建環境就會更加麻煩!

2.WebRTC框架

webrtc底層是使用c++寫的。紫色部分就是瀏覽器廠商對使用者提供的API,淺綠色部分就是WebRTC的標準介面。對與普通應用開發者(如前端)就是關注最上面的那層就好了。WebRTC框架主要分為音訊(編解碼,降噪,回聲消除等),影片(編解碼,快取等),傳輸(P2P、SRTP等)等3大模組。WebRTC框架的虛線部分主要是第支援三方的擴充套件模組,如音影片的採集,音訊渲染,網路IO等。可以由自己去實現或瀏覽器廠商自定義實現。下圖中的PeerConnection為Web開發人員提供了一個抽象,從複雜的內部結構中抽象出來,只需要關注PeerConnection這個物件就可以開發音影片通話應用。

WebRTC框架主件介紹,如下:

(1)Your Web App:Web開發者開發的程式,Web開發者可以基於整合WebRTC的瀏覽器提供的web API開發基於影片、音訊的實時通訊應用。

(2)Web API:面向第三方開發者的WebRTC標準API(Javascript),如,瀏覽器使用該集成於瀏覽器內,開發者才能直接使用其頂層。使開發者能夠容易地開發出類似於網路影片聊天的web應用,最新的標準化程序可以檢視這裡。當前,重要API包括:MediaStream:媒體流,內部裝載VideoTrack與AudioTrack,即影片流與音訊流,其中AudioTrack可直接作為音訊源或音訊輸出,因為對於即時通訊的來說,音訊源只有可能為話筒。而作為影片源時不可以直接使用,還需要確定,包括攝像頭源,或是螢幕源,或是視窗源

(3)WebRTC Native C++ API:本地C++ API層,使瀏覽器廠商容易實現WebRTC標準的Web API,抽象地對數字訊號過程進行處理。

(4)Transport / Session:傳輸/會話層,會話層元件採用了libjingle庫的部分元件實現,無須使用xmpp/jingle協議。在WebRTC C++ API的下一層為會話層,採用libjingle庫對的具體功能進行管理。其具體功能包括voice engine音訊的管理,video engine影片的管理,以及transport傳輸的管理。

(5)VoiceEngine:音訊引擎是包含一系列音訊多媒體處理的框架。VoiceEngine是WebRTC極具價值的技術之一,是Google收購GIPS公司後開源的。在VoIP上,技術業界領先。Opus:支援從6 kbit/s到510 kbit/s的恆定和可變位元率編碼,幀大小從2.5 ms到60 ms,各種取樣率從8 kHz(4 kHz頻寬)到48 kHz(20 kHz頻寬,可複製人類聽覺系統的整個聽力範圍)。這個Opus音訊編碼,在前面的文章也分析過,音質好,位元速率低。音訊引擎中包括了眾多音訊處理技術,如isac(Internet Speech Audio Codec)WebRTC的預設編解碼器,適用環境為寬頻大,而頻寬小時,就使用ILBC(Internet Low Bitrate Codec)。使其能夠快速且高解析度地適應不斷變化的網路環境,確保音質優美且緩衝延遲最小。除此之外,還有不可或缺的回聲消除器(Acoustic Echo Canceler : AEC)用以實時消除麥克風在錄製聲音時產生的迴音。還有減噪器(Noise Reduction: NR),能夠自動檢測規則或類規則性的噪聲,比如風扇的轉動,馬路的喧囂等。

(6)NetEQ模組是Webrtc語音引擎中的核心模組 ,一種動態抖動緩衝和錯誤隱藏演算法,用於隱藏網路抖動和資料包丟失的負面影響。保持儘可能低的延遲,同時保持最高的語音質量

(7)VideoEngine:WebRTC影片處理引擎,VideoEngine是包含一系列影片處理的整體框架,從攝像頭採集影片到影片資訊網路傳輸再到影片顯示整個完整過程的解決方案。VP8 影片影象編解碼器,是WebRTC影片引擎的預設的編解碼器,VP8適合實時通訊應用場景,因為它主要是針對低延時而設計的編解碼器。影片引擎中還包含針對移動裝置最佳化的影片抖動緩衝器Video Jitter Buffer,用以降低由於影片裝置在影片進行時移動而對影片造成的影響。影片引擎中的影象改善器Image enhancements包含影象的顏色增強,顏色降噪等提升畫面質量的功能。

(8)傳輸模組主要由RTP/SRTP實時傳輸協議棧、STUN/TURN/ICE防火牆穿越方法等組成,共同實現Web應用的客戶端使用者之間的資料傳輸。Web應用開發者在運用和實現傳輸功能時需要結合具體的應用場景進行設計。

(9)在瀏覽器中還包含了會話控制及相關標準協議。目前會話控制有兩種實現方式:一種是直接使用瀏覽器現有整合協議棧,這種方式提高了瀏覽器應用程式的執行效率,但是降低了靈活度,並且不支援私有協議;另一種是基於JavaScript編寫協議棧,如基於JavaScript的SIP協議棧或者JSEP,其優勢在於使WebRTC具有更強的擴充套件能力,而且在協議邏輯並不複雜且系統輕載的情況下較容易實現,降低了開發難度,提升了系統的靈活性。

透過WebRTC框架該框架,我們將實時通訊所需的音影片和傳輸模組融合在瀏覽器中,並以介面的方式將能力提供給應用客戶端,從而實現瀏覽器對的支援。

以瀏覽器舉例,WebRTC的瀏覽器模型,如下圖:

WebRTC的瀏覽器模型中,要求其增加了處理RTC的功能模組,該模型預設瀏覽器並有包含所有音影片通訊所需要的功能單元,模型的目標是將Web應用程式所需的實時通訊功能函式,結合其後臺伺服器,共同實現實時通訊功能。這意味著需要規範兩個重要的介面,一是當沒有任何中間伺服器時,瀏覽器相互通訊的協議;另一個是讓javasript應用程式使用瀏覽器的功能的API介面。

瀏覽器模型中,應用伺服器透過Web socket或信令HTTP承載對應用客戶端進行會話控制等信令操作。客戶端應用JS程式透過呼叫WebRTC API獲取瀏覽器的實時通訊功能。透過這種瀏覽器模型,使用者可以透過任何部署了WebRTC協議的瀏覽器使用其提供WebRTC的應用,與其他在瀏覽器中使用該WebRTC應用的使用者進行實時通訊。

3.WebRTC發展前景

WebRTC雖然冠以“web”之名,但並不受限於傳統網際網路應用或瀏覽器的終端執行環境。實際上無論終端執行環境是瀏覽器,桌面應用,移動裝置(Android或ios),還是IOT裝置,只要IP連線可到達且符合WebRTC規範,就可以互通。這一點釋放了大量智慧終端(或執行在智慧終端上的app)的實時通訊能力,打開了許多對於實時互動性要求較高的應用場景的想象空間,譬如線上教育、影片會議、影片社交、遠端協助、遠端操控等等都是其合適的應用領域。

全球領先的技術研究和諮詢公司Technavio最近釋出了題為“全球網路實時通訊(WebRTC)市場,2017­2021”的報告。報告顯示,2017-­2021年期間,全球網路實時通訊(WebRTC)市場將以34.7%的年均複合增長率增長,增長十分迅速。增長主要來自北美、歐洲及亞太地區。

國內方案廠商

聲網、即構科技、環信、融雲等公司都在基於WebRTC二次開發自己的音影片通話方案。

聲網官網地址:

https://www.agora.io/cn/

即構科技地址:

https://www.zego.im/

4.WebRTC通話原理

A端影片採用VP8做編碼,然後傳送給B端,B端怎麼去解碼(B端使用的是VP9)?反過來也是一樣。所以就需要媒體協商資訊(彼此瞭解對方的媒體格式)。比如都支援H264或H265,那經過協商後,就可以使用H264和H265。使用SDP做媒體協商資訊。

注意:有一個專門的協議 ,稱為Session Description Protocol (SDP),可用於描述上述這類資訊,在WebRTC中,參與影片通訊的雙方必須先交換SDP資訊,這樣雙方才能知根知底,而交換SDP的過程,也稱為"媒體協商"。

4.1 網路協商

最理想的情況就是每個瀏覽器的電腦都是私有公網IP,彼此直接訪問,能夠點對點連線。彼此要了解對方的網路情況,這樣才有可能找到一條相互通訊的鏈路,需要做到以下2點,那就是如下:

(1)獲取本端對應的外網IP地址對映。

(2)端與端之間,透過信令伺服器互動“網路資訊”。

理想的情況如下:

實際的情況如下:

實際是在端到端的網路環境中,都是在某個區域網,需要NAT(NetWork Address Translation,即網路地址轉換)。實際在解決這些問題的時候,就需要用STUN和TURN。

4.2 STUN

在遇到上述情況的時候,我們可以建立一個STUN伺服器,這個伺服器做什麼用的呢?主要是給無法在公網環境下的影片通話裝置分配公網IP用的。這樣兩臺電腦就可以在公網IP中進行通話。使用一句話說明STUN做的事情就是:告訴我對應的公網地址和埠是什麼。如果STUN轉換成功,就可以使用P2P傳輸

STUN(Session Traversal Utilities for NAT,NAT會話穿越應用程式)是一種網路協議,它允許位於NAT(或多重NAT)後的客戶端找出自己的公網地址,查出自己位於哪種型別的NAT之後以及NAT為某一個本地埠所繫結的Internet埠,這些資訊被用來在兩個同時處於NAT路由器之後的主機之間建立UDP通訊。該協議由RFC 5389定義。在遇到上述情況的時候,可以建立一個STUN伺服器,這個伺服器做什麼用的呢?主要是給無法在公網環境下的影片通話裝置分配公網IP用的。這樣兩臺電腦就可以在公網IP中進行通話。如下圖所示:

上面也可能會有一些問題,STUN並不是每次都能成功的分配IP地址,P2P在傳輸媒體流時,使用的本地頻寬,在多人影片通話的過程中,通話質量的好壞是需要根據使用者本地的頻寬確定。如果遇到這類問題,那就可以使用TURN來解決這個問題。

4.3 TURN

TURN的全稱為Traversal Using Relays around NAT,是STUN/RFC5389的一個拓展,主要添加了Relay功能,如果終端在NAT之後, 那麼在特定的情景下,有可能使得終端無法和其對等端(peer)進行直接通訊,這就需要公網的伺服器作為一個中繼,對來往的資料進行轉發。這個轉發的協議就被定義為TURN。TURN伺服器如下圖所示:

在STUN分配公網IP失敗後,可以透過TURN伺服器請求公網IP地址作為中繼地址。這種中繼的方式的頻寬就由伺服器端承擔,在多人影片聊天的時候,本地頻寬壓力較小,並且,根據Google的說明,TURN協議可在所有的環境中,一般單向通話,如果能夠保證音質較好,一般是設定在200Kbps。以上是WebRTC經常用到的2個協議,STUN和TURN伺服器使用的是coturn開源專案來搭建。

兩個區域網IP是不能直接連線!每臺電腦都有一個外網IP地址,如58.222.15.91。A端和B端都有一個外網IP。A和B端對映,就需要NAT轉換,做對映,看兩個外網對映的IP+埠,能否相通。如果能夠相通,就說明能夠實現A到B的點到點的通訊,這個就是打洞,是一種理想的情況。

建議使用relay模式,否則在部署到公網的時候,coturn伺服器很容易失敗。在區域網,即使coutrn不工作,也可以工作的。

注意:ICE跟STUN和TURN不一樣,ICE不是一種協議,而是一個框架(Framework),它整合了STUN和TURN。coturn開源專案集成了STUN和TURN的功能。

描述網路資訊的術語就叫做candidate。媒體協商使用SDP。網路協商使用candidate。那這些媒體資訊和網路資訊,怎麼去交換呢?那就需要一個信令伺服器(Signal server)轉發彼此的媒體資訊和網路資訊。原理如下:

如上圖,我們在基於WebRTC API開發應用(APP)時,可以將彼此的APP連線到信令伺服器(Signal Server,一般搭建在公網,或兩端都可以訪問到的區域網),藉助信令伺服器,就可以實現上面提到的SDP媒體資訊及Candidate網路資訊交換

注意:信令伺服器不只是互動媒體資訊SDP和網路資訊candidate,如,房間管理,人員進出房間等。

5.WebRTC APIs

(1)MediaStream — MediaStream用來表示一個媒體資料流(透過getUserMedia介面獲取),允許你訪問輸入裝置,如麥克風和 Web攝像機,該 API 允許從其中任意一個獲取媒體流。

(2)RTCPeerConnection— RTCPeerConnection 物件允許使用者在兩個瀏覽器之間直接通訊 ,你可以透過網路將捕獲的音訊和影片流實時傳送到另一個 WebRTC 端點。使用這些 Api,你可以在本地機器和遠端對等點之間建立連線。它提供了連線到遠端對等點、維護和監視連線以及在不再需要連線時關閉連線的方法。

信令伺服器不是一個標準,可以自定義,可以使用c++,go,NODE.js都可以使用。透過信令伺服器去交換SDP、candidate。如果信令伺服器是給外面的人用,一般是把信令伺服器搭建在公網。如果是在區域網,也可以搭建在區域網,一定要保證所有的訪問者,都能夠訪問到信令伺服器。信令伺服器還可以使用房間管理。

如多人通話時,為了區分不同的人群,那就需要一個"房間"的概念。這個“房間”就可以實現房間的管理和人員的進出。如a加入房間100,b加入房間100,此時需要通知a已經加入房間了。

注意:直播一般是RTMP互動的,一般不需要考慮超低延遲。音影片通話就需要考慮,需要極地的延時。直播RTMP都是單向傳播的。webrtc是雙向傳播。聲網影片群聊最大支援17人。

這個CreateOffer、AddStream、SetLocalDescription也是屬於這個PeerConnection。設定自己的SDP是SetlocalDescription,設定別人的是setRemoteDescription。

在一對一通話場景中,每個 Peer均建立有一個 PeerConnection 物件,由一方主動發 Offer SDP,另一方則應答AnswerSDP,最後雙方交換 ICE Candidate 從而完成通話鏈路的建立。但是在中國的網路環境中,據一些統計資料顯示,至少%50的網路是無法直接穿透打通,這種情況下只能藉助TURN伺服器中轉。關於P2P傳輸,以後可以用專門的文章來介紹,因為這個也是另外一個方向了。

6.WebRTC連線的建立

傳送端在準備好影片源(攝像頭或者螢幕分享或者視窗分享)以及音訊源(麥克風)之後放入videotrack與audiotrack中,再封裝成MediaStream,再將MediaStream放入用來建立連線的PeerConnection中。

接收端從建立的PeerConnection中取得MediaStream,再分別將MediaStream內的videotrack與audiotrack展示出來(OpenGL進行影片展示,喇叭播放音訊)。

在WebRTC的開源開發包中,無論是Web端還是Android端或是IOS端,使用者都只需要簡單的new peerconnection,就可以透過對方的ID與對方建立連線。這是WebRTC使用者的方便之處,但是對於WebRTC的開發者,必須更加深入地瞭解WebRTC,才能夠對其進行修改,完善其功能。需要強調在最高層程式碼中,對於音訊源,只需要new audiotrack即可,而對於WebRTC影片源,由於的影片源可有三個選擇,一是攝像頭獲取的影片輸入,二是獲取使用者的螢幕展示作為影片輸入,三是獲取使用者的某視窗展示作為影片輸入,所以對於videotrack,除了需要new videotrack之外,還需要給videotrack增加videosource,用於管理影片的來源,在videosource中需要新增videocapturer,用videocapturer從videosource中獲取待傳輸的影片畫面。也就是在WebRTC開發中,對WebRTC直接使用的最高層中,需要new peerconnection,new mediastream,new audiotrack、new videotrack、new videosource、new videocapturer。

傳送端

接收端

在WebRTC的傳送端的影片資料獲取過程,如下圖:

傳送端的影片資料獲取過程

在實際開發中,谷歌不僅僅只提供了WebRTC的底層開發包,還提供底層與高層的中間層,如android開發,谷歌提供了JNI,使得處於高層的android能夠在新建連線,媒體流,影片管道,音訊管道,影片源,影片影象獲取之後,透過呼叫JNI來達到最終底層方法的呼叫。

WebRTC底層為C++,對於影片源的獲取可以上面的圖瞭解到,在WebRTC底層,有WebRTCVideoCapturer,是高層的Videocapturer透過JNI控制的,在WebRTCVideoCapturer中,可以管理DeviceManager,當DeviceManager獲取到高層所需要的影片源後,呼叫影片源相關裝置,使其能夠獲取影片源。如在DeviceManager中已經存在的三種方法,如下:

GetVideoCapturerDevice:由此方法開啟攝像頭,並由攝像頭獲取影片源。

GetWindows:獲取使用者某視窗的連續截圖作為影片源。

GetDestops:獲取使用者螢幕作為影片源。

所有影片源將會放在記憶體中的memoryPool中,由FileVideoCapturer由記憶體池中獲取影片幀源資訊,再由DevcieManager的三個get方法中的對應一個方法。再由DeviceManager交到WebRTCVideoCapturer後由JIN交到android層videocapturer,經由videosource到videotrack後,再到mediastream後到達PeerConnection進行傳輸。接收端的影片資料獲取過程如下圖所示:

接收端的影片資料獲取過程

在Render中加入listener,每當一幀影片到達,Render就從Videotrack中獲取圖片資訊交給視影片源經由peerconnection到達後將傳送到mediastream中,經由videotrack中的Observer傳送給Render,影片到達後即可獲得儲存影片資訊的Buffer,該Buffer可選擇由不同的方式顯示,在Twinsee的android端選擇為OpenGL顯示。有特殊制定檔案VideoStreamView.java來配置OpenGL的顯示,例如影象的大小,影象的位置,本地影象與遠端影象如何分佈等。

7.WebRTC連線時序

媒體協商和網路協商的簡單過程如下圖:

RTCPeerConnection:連線物件,建立該連線物件,後以為資訊,連線兩個瀏覽器。

RTCIceCandidate:連線物件候選者資訊,如賬號等。

RTCIceServer:建立連線時用以讀取候選者資訊的伺服器。一般使用時,不同的瀏覽器中所使用的指令碼都有所不同,以下是相關對應的方法名稱,如下圖:

7.1 媒體協商

A端這裡是發起者,B端這裡是接收者。A端向B端發起。PeerConnection和RTCConnection是屬於同一個物件。A和B端都會AddStream,就是把本地媒體流(音訊+影片),發起者呼叫CreateOffer(從瀏覽器裡拿到的資訊,就可以設定到PeerConnection裡面去),有一個回撥,透過這個回撥函式,就可以拿到這個SDP,拿到SDP資訊後,首先發到信令伺服器上,透過信令伺服器,再轉發發到B端,這樣B端就會把A端的SDP資訊設定到B端的PeerConnection。B端也會呼叫CreateAnswer去回撥,產生一個屬於B端的SDP,再呼叫B端的SerLocalDescription,把SDP設定到本地,B端會繼續呼叫Send Answer SDP傳送給信令伺服器,信令伺服器透過Relay Answer SDP去傳送SDP資訊給A端。同樣,A端也會呼叫setRemoteDescription把B端的SDP資訊設定給A端的PeerConnection。做完上面的步驟,就完成了媒體協商。

7.2 網路協商

ICE是一種STUN和TURN服務整合,ICE=STUN+TURN,A端會使用ICE Request去STUN上請求公網資訊,伺服器會用onIceCandidate(這個是回撥函式,繫結到A端的PeerConnection)回發Candidate(網路協商資訊)給A端的PeerConnection。A端拿到Candidate資訊後,就透過Send ICE Candidate傳送給信令伺服器,信令伺服器就使用Relay ICE Candidate轉發給B端,B端也是自己PeerConnection的用回撥函式AddIceCabdidate新增信令伺服器轉發給B端的Candidate,然後B端也是使用ICE Request去公網伺服器去請求公網的網路資訊,同樣的,也是透過onIceCandidate去拿到這個資訊,同理,B端也是把這些網路資訊透過信令伺服器去做轉發給A端,也同樣使用Send ICE Candidate和Relay ICE Candidate發,同樣的A端也會把B端的Candidate,透過AddIceCandidate新增到本地A端的PeerConnection。一般A端和B端都各有多組Candidate,如Candidate0-Candidate6,它們之間就會相互做一個互動的嘗試,如果有相互連線成功的,那就會打洞成功(那就意味著,可以點對點傳輸,不用經過伺服器),這樣A端和B端的PeerConnection的回撥函式onAddStream就會收到對方的音影片。如果打洞不成功,就會使用中繼方式TURN去轉發資料。

8.總結

12
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 數字化轉型中更新改造遺留系統的七個方法