前言:

大家週末好,今天給

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的官網看看,不過現在國內一般訪問不了:

https://webrtc.org

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協議的具體解析,大家可以看官網手冊:

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

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

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

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

https://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打造音視訊直播系統

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