Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          本文由ELab技術團隊分享,原題“淺談WebRTC技術原理與應用”,有修訂和改動。

          1、基本介紹

          WebRTC(全稱 Web Real-Time Communication),即網頁即時通信。 是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術方案。從前端技術開發的視角來看,是一組可調用的API標準。

           

          在WebRTC發布之前,開發實時音視頻交互應用的成本是非常昂貴,需要考慮的技術問題很多,如音視頻的編解碼問題,數據傳輸問題,延時、丟包、抖動、回音的處理和消除等,如果要兼容瀏覽器端的實時音視頻通信,還需要額外安裝插件。

          2010年5月:Google以6820萬美元收購VoIP軟件開發商Global IP Solutions的GIPS引擎,并改為名為“WebRTC”(見《了不起的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》)。

          本文已同步發布于:http://www.52im.net/thread-3804-1-1.html

          2、重要意義

          WebRTC的出現、發展和被業內標準組織(如W3C)等普遍認可,對于當下和未來大前端技術發展具有重要的意義。

          降低在web端的音視頻交互開發門檻:

          • 1)以往的音視頻交互開發對于Web開發者而言具有一定技術門檻;
          • 2)現在借助于WebRTC,Web開發者通過調用JS接口,可快速的實現音視頻交互應用。

          避免依賴、插件造成的次生問題:

          • 1)以往的音視頻交互應用構建依賴于各種插件、軟件和服務器等;
          • 2)現在借助于主流瀏覽器即可形成端到端的音視頻交互。

          統一化和標準化對傳統音視頻交互環境差異性的規避:

          • 1)以往音視頻交互需要面對不同的 NAT 、防火墻對媒體 P2P 的建立帶來了很大的挑戰;
          • 2)現在WebRTC 中有P2P 打洞的開源項目 libjingle ,支持 STUN,TURN 等協議。

          更高效優化的算法、技術對于音視頻交互性能的提升:

          • 1)WebRTC 通過NACK、FEC技術,避免了經過服務端路由中轉,減少了延遲和帶寬消耗;
          • 2)還有 TCC + SVC + PACER + JitterBuffer 等技術對于音視頻流暢性進行了優化。

          3、技術特征

          WebRTC內容豐富,主要的技術特征包含以下幾點。

          1)實時通訊:

          WebRTC是一項實時通訊技術,允許網絡應用或者站點,在不借助中間媒介的情況下,建立瀏覽器之間點對點(Peer-to-Peer)的連接,實現視頻流和(或)音頻流或者其他任意數據的傳輸。

          2)無依賴/插件:

          WebRTC包含的這些標準使用戶在無需安裝任何插件或者第三方的軟件的情況下,創建點對點(Peer-to-Peer)的數據分享和電話會議成為可能。

          3)協議棧 眾多:

          WebRTC并不是單一的協議,包含了媒體、加密、傳輸層等在內的多個協議標準以及一套基于 JavaScript的 API,它包括了音視頻的采集、編解碼、網絡傳輸、顯示等功能。通過簡單易用的 JavaScript API ,在不安裝任何插件的情況下,讓瀏覽器擁有了 P2P音視頻和數據分享的能力。

          WebRTC依賴眾多協議棧圖:

           

           

          同時WebRTC 并不是一個孤立的協議,它擁有靈活的信令,可以便捷的對接現有的SIP 和電話網絡的系統。

          4、兼容覆蓋

          目前大部分主流瀏覽器都正常兼容WebRTC:

          更詳細的瀏覽器及版本兼容情況,可以看看下圖:

          ▲ 上圖引用自《https://caniuse.com/rtcpeerconnection

          主流瀏覽器都支持 WebRTC 標準 API ,因此也讓瀏覽器之間無插件化的音視頻互通成為可能, 大大降低了音視頻開發的門檻,開發者只需要調用 WebRTC API 即可快速構建出音視頻應用。

          5、技術框架

          如下圖所示:的技術框架描述了WebRTC的核心內容和面向不同開發者的API設計。

          WebRTC技術框架圖:

          從圖中可看到,WebRTC主要面向三類開發者的API設計:

          • 1)對于Web開發者的API:框架包含了基于JavaScript 、 經過W3C認證了的一套API標準,使得web開發者可以基于這套API開發基于WebRTC的即時通訊應用;
          • 2)對于瀏覽器廠商的API:框架同樣包含了基于C++的底層WebRTC接口,對于瀏覽器廠商底層的接入十分友好;
          • 3)瀏覽器廠商可自定義的部分:框架中還包含瀏覽器廠商可自定義的音視頻截取等擴展部分。

          6、技術核心

          從上節框架中可以看到,WebRTC主要有音頻、視頻引擎和傳輸三部分組成,其中又包含眾多的協議和方法等。

          1)Voice Engine(音頻引擎):

          • a、Voice Engine包含iSAC/iLBC Codec(音頻編解碼器,前者是針對寬帶和超寬帶,后者是針對窄帶);
          • b、NetEQ for voice(處理網絡抖動和語音包丟失);
          • c、Echo Canceler(回聲消除器)/ Noise Reduction(噪聲抑制)。

          2)Video Engine(視頻引擎):

          • a、VP8 Codec(視頻圖像編解碼器);
          • b、Video jitter buffer(視頻抖動緩沖器,處理視頻抖動和視頻信息包丟失);
          • c、Image enhancements(圖像質量增強)。

          3)Transport。

          7、技術原理

          7.1 基本情況

          WebRTC主要的技術特征:

          • 1)SRTP:安全的實時傳輸協議,用于音視頻流傳輸;
          • 2)Multiplexing:多路復用;
          • 3)P2P:STUN+TURN+ICE,用于NAT網絡和防火墻穿越;
          • 4)DTLS:安全傳輸可能還會用到DTLS(數據報安全傳輸),用于加密傳輸和密鑰協商;
          • 5)UDP:整個WebRTC通信是基于UDP的。

          限于篇幅,本文以下章節將不細致介紹音視頻采集、編碼和處理等內容,僅介紹實時通訊的建立過程原理的核心內容。

          7.2 公網IP映射:明確網絡定位信息

          WebRTC是基于瀏覽器端到端的連接(P2P)實現的.

          由于不需要服務器中轉,所以獲取連接對象的網絡地址的方式,是借助于ICE、STUN、TURN等輔助內網穿透技術(NAT)得到對應主機的公網網絡地址和端口等網絡定位信息。

          明確網絡定位是建立端與端直接通訊的基礎。

          NAT穿透原理圖:

          STUN服務器用于輔助內網穿透得到對應主機的公網網絡地址和端口信息圖:

          7.3 信令服務器:網絡協商與信息交換

          信令服務器的作用是基于雙工通信來中轉信息。

          中轉信息包括公網IP映射后的網絡定位信息,比如:公網IP、端口和媒體數據流等。

          概念圖:

          信令服務器信息交互過程圖:

          7.4 會話描述協議SDP:統一的媒體協商方式

          SDP的作用:

          • 1)不同端/瀏覽器對于媒體流數據的編碼格式各異,如VP8、VP9等,參與會話的各個成員的能力不對等、用戶環境與配置不一致等;
          • 2)WebRTC通訊還需要確定和交換本地和遠程音頻和視頻媒體信息,例如分辨率和編解碼器功能。交換媒體配置信息的信令通過使用會話描述協議 (SDP) 交換Offer和Anwser來進行;
          • 3)SDP的交換一定是先于音視頻流交換的。其內容包括會話基本信息、媒體信息描述等。

          //SDP的結構體

          Session description(會話級別描述)

                   v=  (protocol version)

                   o=  (originator and session identifier)

                   s=  (session name)

                   c=* (connection information -- not required ifincluded inall media)

                   One or moreTime descriptions ("t="and "r="lines; see below)

                   a=* (zero or moresession attribute lines)

                   Zero or moreMedia descriptions

           

          Time description

                   t=  (timethe session is active)

           

          Media description(媒體級別描述), ifpresent

                   m=  (media name and transport address)

                   c=* (connection information -- optional ifincluded at session level)

                   a=* (zero or moremedia 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/SAVPF103 104 0 8 106 105 13 126 //...

          a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh81

          7.5 一對一連接建立過程

          以建立一對一的Web RTC連接過程為例來簡要講解。

          一對一過程圖:

          簡要過程圖:

          如上圖所示,解釋一下:

          • 1)交換SDP,獲取各自媒體配置信息;
          • 2)STUN服務器交換網絡地址和端口等網絡信息;
          • 3)Turn中轉音視頻媒體流數據。

          工作流程圖:

          如上圖所示,解釋一下:

          • 1)A和B雙方先調用 getUserMedia 打開本地攝像頭,作為本地待輸出媒體流;
          • 2)向信令服務器發送加入房間請求;
          • 3)Peer B 接收到 Peer A 發送的 offer SDP 對象,并通過PeerConnection的SetLocalDescription方法保存 Answer SDP 對象并將它通過信令服務器發送給 Peer A;
          • 4)在 SDP 信息的 offer/answer 流程中,Peer A 和 Peer B 已經根據 SDP 信息創建好相應的音頻 Channel 和視頻 Channel,并開啟Candidate 數據的收集,Candidate數據(本地IP地址、公網IP地址、Relay服務端分配的地址);
          • 5)當 Peer A 收集到 Candidate 信息后通過信令服務器發送給 Peer B。同樣的過程 Peer B 對 Peer A 也會再發送一次。

          7.6 多對多的建立

          多對多建立點到點連接概念圖,以三個用戶點對點的連接為例:

          7.7 WebRTC的主要JavaScrip接口

          getUserMedia()訪問數據流,例如來自用戶的相機和麥克風

          //請求媒體類型

          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通過加密和帶寬管理工具啟用音頻或視頻通話

          // 允許 RTC 服務器配置。

          const server = {

              "iceServers":

                      [{ "urls": "stun:stun.stunprotocol.org"}]

          };

           

          // 創建本地連接

          const localPeerConnection = newRTCPeerConnection(servers);

           

          // 收集Candidate 數據

          localPeerConnection.onicecandidate=function(event){

              ...

          }

          // 監聽到媒體流接入時的操作

          localPeerConnection.ontack=function(event){

              ...

          }

          RTCDataChannel支持通用數據的點對點通信,常用于數據點到點的傳輸

          const pc = newRTCPeerConnection();

          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");

          };

          8、應用案例

          這里以WebRTC的多人視頻案例為實踐來大致演示一下。

          8.1 設計框架

          多人視頻基本框架圖:

          8.2 關鍵代碼

          8.2.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=newRTCPeerConnection(iceServer);

          8.2.2)網絡協商:

          主要任務就是:創建對等連接,收集ICE候選,等待媒體流接入時掛載到dom。

          交互式連通性建立(Interactive Connectivity Establishment — ICE)是一個允許實時對等端發現對方并且彼此連接的框架。此技術允許對等方發現有關彼此拓撲的足夠信息,從而有可能在彼此之間找到一條或多條通信路徑。ICE 代理負責:收集本地IP,端口元組候選、在同級之間執行連接檢查和發送連接保持活動。(關于ICE的介紹,見《P2P技術之STUN、TURN、ICE詳解

          // 發送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]

          }

          8.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(newRTCIceCandidate(signalMsg["data"].iceCandidate));

          多人視頻結果截圖<本地模擬效果>:

          8.2.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"],

                              }));

                          }

                      });

                  }

              })

          })

          9、小結一下

          WebRTC的優點主要是:

          1)方便:對于用戶來說,在WebRTC出現之前想要進行實時通信就需要安裝插件和客戶端,但是對于很多用戶來說,插件的下載、軟件的安裝和更新這些操作是復雜而且容易出現問題的,現在WebRTC技術內置于瀏覽器中,用戶不需要使用任何插件或者軟件就能通過瀏覽器來實現實時通信。對于開發者來說,在Google將WebRTC開源之前,瀏覽器之間實現通信的技術是掌握在大企業手中,這項技術的開發是一個很困難的任務,現在開發者使用簡單的HTML標簽和JavaScript API就能夠實現Web音/視頻通信的功能。

          2)免費:雖然WebRTC技術已經較為成熟,其集成了最佳的音/視頻引擎,十分先進的codec,但是Google對于這些技術不收取任何費用。

          3)強大的打洞能力:WebRTC技術包含了使用STUN、ICE、TURN、RTP-over-TCP的關鍵NAT和防火墻穿透技術,并支持代理。

          WebRTC的缺點主要是:

          1)缺乏服務器方案的設計和部署。

          2)傳輸質量難以保證。WebRTC的傳輸設計基于P2P,難以保障傳輸質量,優化手段也有限,只能做一些端到端的優化,難以應對復雜的互聯網環境。比如對跨地區、跨運營商、低帶寬、高丟包等場景下的傳輸質量基本是靠天吃飯,而這恰恰是國內互聯網應用的典型場景。

          3)WebRTC比較適合一對一的單聊,雖然功能上可以擴展實現群聊,但是沒有針對群聊,特別是超大群聊進行任何優化。

          4)設備端適配,如回聲、錄音失敗等問題層出不窮。這一點在安卓設備上尤為突出。由于安卓設備廠商眾多,每個廠商都會在標準的安卓框架上進行定制化,導致很多可用性問題(訪問麥克風失敗)和質量問題(如回聲、嘯叫)。

          5)對Native開發支持不夠。WebRTC顧名思義,主要面向Web應用,雖然也可以用于Native開發,但是由于涉及到的領域知識(音視頻采集、處理、編解碼、實時傳輸等)較多,整個框架設計比較復雜,API粒度也比較細,導致連工程項目的編譯都不是一件容易的事。

          10、參考資料

          [1] 開源實時音視頻技術WebRTC的現狀

          [2] 簡述開源實時音視頻技術WebRTC的優缺點

          [3] 訪談WebRTC標準之父:WebRTC的過去、現在和未來

          [4] 良心分享:WebRTC 零基礎開發者教程(中文)[附件下載]

          [5] WebRTC實時音視頻技術的整體架構介紹

          [6] 新手入門:到底什么是WebRTC服務器,以及它是如何聯接通話的?

          [7] WebRTC實時音視頻技術基礎:基本架構和協議棧

          [8] 淺談開發實時視頻直播平臺的技術要點

          [9] 基于開源WebRTC開發實時音視頻靠譜嗎?第3方SDK有哪些?

          [10] 開源實時音視頻技術WebRTC在Windows下的簡明編譯教程

          [11] 網頁端實時音視頻技術WebRTC:看起來很美,但離生產應用還有多少坑要填?

          [12] 了不起的WebRTC:生態日趨完善,或將實時音視頻技術白菜化

          [13] 零基礎入門:基于開源WebRTC,從0到1實現實時音視頻聊天功能

          [14] P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介

          [15] P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解(基本原理篇)

          本文已同步發布于:http://www.52im.net/thread-3804-1-1.html



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 邯郸市| 定州市| 蕲春县| 桐城市| 丰原市| 关岭| 夹江县| 浙江省| 云龙县| 无锡市| 黔东| 泰来县| 日照市| 太康县| 新乡县| 芒康县| 文化| 丽江市| 洛隆县| 舞阳县| 中方县| 兰考县| 武穴市| 五台县| 西和县| 宾阳县| 九台市| 陕西省| 阳春市| 桦甸市| 合水县| 松溪县| 馆陶县| 民权县| 通州区| 安义县| 桂林市| 凤冈县| 嘉义县| 大兴区| 同江市|