webrtc原理及相關api使用邏輯

#簡單剖析webrtc,並結合easyrtc與coturn(stun,turn)服務實現音視頻聊天html

  • webRTC全稱爲Web Real-Time Communications,即web實時通信前端

  • 音視頻聊天實現前提,跟直播不同哦~api類型繁多,有的也過期了,見到有不一樣的就翻翻MDN,換個方案吧,谷歌須要https或者localhost才能開啓媒體權限,火狐則不須要,但作兼容很費工夫。localhost下就本身開兩個網頁測吧,後面會講easyrtcnode

    • 理解websocket鏈接/websocket算是node.js最繁華的領域了,socket.io簡單粗暴https://github.com/socketio/socket.io.git
    • 理解webrtc的工做流程 juejin.im/post/5b3f50…
      • stun服務器做用,獲取雙方ip協助創建鏈接
      • turn服務器做用,轉發音視頻
      • 信令服務器做用,利用socket.io實現,主要就是轉發音視頻聊天雙方的軟硬件信息ip,設備信息,協助直連或者視頻轉發
  • 簡化文章內容介紹,webrtc流程,如下在內網中能夠運行git

    • 1.獲取用戶音視頻媒體,完成這步,便可看到本身的攝像頭影像
    navigator.mediaDevices.getUserMedia({
        audio: true,
        video: true,
      }).then((stream) => {
        let video = document.querySelector('#video')
        video.srcObject = stream  // mediaDevices.getUserMedia獲取到的音視頻流捆綁在video標籤上
        video.onloadedmetadata = () => video.play() // 讀取數據時進行播放
      })
    複製代碼
    • 2.進行peertopeer點對點鏈接,
      • 2-1.房主createOffer回調中能取到房主的信息desc,音視頻結構軟硬件信息,儲存本地,而且發送到信令服務器,協助轉發
      let peer = new RTCPeerConnection(servers)
        pc.createOffer(sendOffer, function (error) {
          console.log('發送 offer 失敗')
        })
        function sendOffer (desc) {
          console.log('sendOffer')
          pc.setLocalDescription(desc);
          socket.emit('offer', JSON.stringify({
          data: {sdp: desc}
            })
          )
        }
      複製代碼
      • 2-2.房主createOffer時會觸發自身鏈接的onicecandidate事件,獲取candidate,用戶地址等
      pc.onicecandidate = function(event) {
          if (event.candidate !== null) {
              socket.emit("_ice_candidate",JSON.stringify({
                type: '_candidate',
                data: {
                  candidate: event.candidate
                }
              })
            )
          }
        };
      複製代碼
      • 2-3.對方在socket中收到offer時,將其設置爲遠端描述,offer對應的爲answer,建立時會觸發該用戶的onicecandidate事件,能得到到其用戶地址信息,此時將描述發給房主
      socket.on('offer', function(e) {
          getUserMedia(function (stream) {
          let vid1 = document.getElementById('vid1')
          vid1.srcObject = stream
          vid1.onloadedmetadata = function(e) {
            vid1.play();
          };
          pc.addStream(stream)
          var json = JSON.parse(e) 
          pc.setRemoteDescription(new RTCSessionDescription(json.data.sdp));
          pc.createAnswer(sendAnswer, function (error) {
            console.log('建立answer失敗')
          })
          }, function (error) {
            console.log('攝像頭獲取失敗', '接聽視頻失敗');
          })
        })
        function sendAnswer(desc) {
          pc.setLocalDescription(desc);
          socket.emit('answer', JSON.stringify({
            type: '_answer',
            data: {
              sdp: desc
            }
          }))
        }
      複製代碼
      • 2-4.房主在接收answer的socket事件中將其設置爲遠端描述
      socket.on('answer', async function(e) {
          let data = e.message
          await peer.setRemoteDescription(data)
        })
      複製代碼
  • 外網實現點對點音視頻聊天 ICE(結合stun,turn進行穿透獲取音視頻雙方地址)github

    • STUN解析
      • 但現實中咱們的視頻通話,不可能侷限在內網,可能會在防火牆,NAT以後,點對點鏈接以前,咱們須要檢測是否能進行,該技術稱爲NAT穿透,一般基於UDP協議,如RFC3489。在新的RFC5389中支持了TCP穿透
    • TURN解析
      • TURN使用中繼穿透NAT:STUN的擴展,跟STUN同樣都是經過修改應用層中的私網地址達到NAT穿透的效果,異同點是TURN是經過兩方通信的「中間人」方式實現穿透。就有點像服務器轉發音視頻流的意思,在STUN失敗時會走TURN
    • NAT做用是啥
      • 爲了緩解全球ip不足,NAT能夠將內網的私有地址轉爲外網的共有地址,從而能夠進行internet訪問
      • 防止外部主機攻擊內部主機
    • 固然前端開發是不熟悉這些的,閱讀多篇RTC博客得知谷歌開源了stun,coturn相關的服務,只須要將依賴安裝,帳號密碼加密設置便可使用參考文獻https://www.cnblogs.com/idignew/p/7440048.html
    • 配置完畢coturn後測試地址,返回有relay屬性爲服務器地址證實成功https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

  • easyRTCweb

    • 通過屢次測試,本身的RTCdemo兼容性差,目前測試階段就不手寫了。採用了easyRTC,除了safari和古董ie不行,其餘方面仍是ok的。github.com/priologic/e…json

  • 注意採用beta分支,爲最新的項目
相關文章
相關標籤/搜索