webrtc之TURE、STUN、攝像頭打開實戰

前言:

大家周末好,今天給

webrtc之TURE、STUN、攝像頭打開實戰

大家分享的是webrtc第一篇文章,在之前的音視頻文章裏面沒有分享過關於webrtc的內容;在上個周末分享了一篇關於播放器的文章,那篇文章整體上介紹了播放器的設計結構;我個人的學習路線,主要分為兩大方向:ffmpeg和webrtc,然後會具體到各種協議。

關於播放器實戰學習第二篇,我會在下周分享自己的學習筆記和感悟;今天呢,主要是分享一些webrtc的通話原理:STUN 和TURN ,其中會涉及到NAT穿透原理,以及我會用實戰來舉例在google瀏覽器上打開自帶的電腦攝像頭。

好了,具體內容如下:

一、webrtc的通話原理:

1、什麼是webrtc?

在介紹什麼是webrtc之前呢,我先分析一下當前的一個背景:不知道大家平時有沒有注意,短視頻越來越火,你比如微信的視頻號、抖音、頭條、微視頻、快手等,就連知乎裏面在今年也開始玩起了視頻,更別說特別流行的直播帶貨呢,這些產品都離不開音視頻技術的支持,特別是當下5G時代,極大的解決了帶寬問題,會讓這項技術得到更大的發展和應用;作為學習者和開發人員,我們要認真學習,掌握裏面的技術,才能讓我們在職場上有更多的競爭優勢!

好了,說了點廢話,主要就是讓大家知道,這些平時生活當中我們經常玩的的產品,都涉及到音視頻技術的支持;那麼,下面我們來看看webrtc到底是什麼?

webrtc英文名為: Web Real-Time Communication ,web端實時通信,它是google公司在2011年開源的一個項目,主要是面向瀏覽器之間的通信,它的出現真的解決了很多問題,在後期的分享當中大家就可以看到它的強大之處了,更多詳細介紹,大家可以去webrtc的官網看看,不過現在國內一般訪問不了:

//webrtc.org

webrtc官網關於webrtc簡單介紹webrtc官網關於webrtc簡單介紹

2、webrtc的通話原理:

首先在介紹這個原理之前呢,我們先來考慮一個問題:就是在不同的網絡環境下的瀏覽器,要實現點對點(也就是一對一)的實時音視頻對話,那他們是如何通信的呢?

媒體協商媒體協商

如上圖所示,我們先考慮下兩個問題:

  • 瀏覽器Peer-A視頻採用VP8(視頻圖像編解碼器,是WebRTC視頻引擎的默認的編解碼器,它適合實時通信應用場景,因為它主要是針對低延時而設計的編解碼器)做編碼,然後發給瀏覽器Peer-B,那麼它該如何去解碼呢?

  • 瀏覽器Peer-B採用VP9做編碼,那瀏覽器Peer-A該如何去解碼呢

看到這裡,你是不是發現了,這中間少了點啥東西,因為雙方不能進行通信啊,你發給我的信息,用不了,我發給你的東西,你用不了;沒錯,少了媒體協商SDP(session description protcol),所以利用SDP規定,雙方都用h264做為共同的編解碼器,這樣雙方都能正確的編解碼了!

上面解決了瀏覽器雙方協商的一個大問題,但是還有一個問題,就是網絡問題,比如說,兩個瀏覽器不在同一個局域網內,一端可能在深圳,另外一端可能在北京,這個時候呢,就會用到NAT(Net Address Transiation,網絡地址轉換),這裡NAT可能會涉及到它的類型,這裡不是文章的重點,不過簡單說一下,分為四種類型:

  • 完全錐型NAT

  • IP限制錐型NAT

  • 端口限制錐型NAT

  • 對稱型NAT

具體大家可以去網上找資料了解一下他們的區別和使用原理,也可以去看之前我推薦的李老師的課程:從0打造一個直播系統

說白了NAT就是網絡地址進行一個映射,也就是轉換,為啥要轉換,這個應該好理解吧,你兩個瀏覽器都不在一個局域網內,那肯定是不能直接進行通信的啊,是吧!

這裡還需要STUN(Session Traversal utilities for NAT,NAT會話穿越應用程序),它主要是為終端提供公網IP地址和端口是什麼,這裡也就是為什麼要用它的原因了,只有地址轉換也沒用,必須能夠訪問到外網;關於STUN協議的具體解析,大家可以看官網手冊:

//datatracker.ietf.org/doc/html/rfc5389

但是有時候呢,STUN不可能每次都可以成功的為需要NAT的通話設備分配IP地址的,所以這個時候問題就來了,我們該如何解決呢?

沒錯,我們還需要TURN(Traversal Using Relays around NAT,在NAT周圍使用中繼遍歷) ,它是STUN的一個擴展,添加了Relayd功能;有了它,就可以解決上面的這個問題了

在STUN分配公網IP失敗後,可以通過TURN服務器請求公網IP地址作為中繼地址。關於TURN的詳細介紹,大家可以看官網手冊:

//datatracker.ietf.org/doc/html/rfc5766

這裡關於網絡的轉換,換句專業的語句來講就是網絡協商了:Candidate

最終要實現瀏覽器之間交換信息,我們還需要信令服務器(Signal Server)轉發彼此的媒體信息和網絡信息。關於信令服務器的介紹就沒啥好介紹的了,它就是起着交換瀏覽器兩端的媒體協商和網絡協商信息。當然信令服務器還有創建房間和離開房間的作用。

二、利用vscode實戰舉例:

1、安裝Live Server插件

利用vscode安裝Live Server插件,他可以在本地開發環境中,實時重新加載(reload)頁面:

這裡可能會涉及到一些前端和js的知識,有c和c++的基礎,很快就可以上手,大家也不用專門花時間去學習,可以看菜鳥教程就行。

2、在google瀏覽器上打開攝像頭

代碼構思流程:

  • 初始化button、video控件

  • 綁定「打開攝像頭」響應事件onOpenCamera

  • 如果要打開攝像頭則點擊 「打開攝像頭」按鈕,以觸發onOpenCamera事件的調用

    • 當觸發onOpenCamera調用時

    • 設置約束條件,即是getUserMedia函數的入參

    • getUserMedia有兩種情況,一種是正常打開攝像頭,使用handleSuccess處理;一種是打開攝像頭失敗,使 用handleError處理

    • 當正常打開攝像頭時,則將getUserMedia返回的stream對象賦值給video控件的srcObject即可將視頻顯示出 來

下面是完整代碼:

<!DOCTYPE html>
<html>
    <body>
        <video id="local‐video" autoplay playsinline></video>
        <button id="showVideo" >打開攝像頭</button> 
         <p>通過getUserMedia()獲取視頻</p>
    </body>
    <script >
            const constraints = {
                audio: false,
                video: true

            };
            //處理打開攝像頭成功
            function handleSuccess(stream) {
                const video = document.querySelector("#local‐video");
                video.srcObject = stream;
            }
            // 異常處理
            function handleError(error) {
                console.error("getUserMedia error: " + error);
            }

            function onOpenCamera(e) {
                navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
            }
            document.querySelector("#showVideo").addEventListener("click", onOpenCamera);

    </script>
</html>

最終結果如下:

暫時這只是一部分,添加音頻進去,以及去燥等,後面會進行優化!

三、總結:

好了今天的分享就到這裡了,我們下期見!

相關文章參考:

從0打造音視頻直播系統

//ke.qq.com/webcourse/index.html#cid=468797&term_id=100561187&taid=4217056589719357&vid=5285890796286162335