-
在線教育、音視頻會議這類直播屬於實時互動直播,主要考慮傳輸的實時性,因此一般使用 UDP 作爲底層傳輸協議而娛樂直播對實時性要求不高,更多關注的是畫面的質量、音視頻是否卡頓等問題,所以一般採用 TCP 作爲傳輸協議
- 我們稱前者爲實時互動直播,後者爲傳統直播
-
編碼幀
- I 幀:關鍵幀
- 壓縮率低,可以單獨解碼成一幅完整的圖像。
- P 幀:參考幀
- 壓縮率較高,解碼時依賴於前面已解碼的數據。
- B 幀:前後參考幀
- 壓縮率最高,解碼時不光依賴前面已經解碼的幀,而且還依賴它後面的 P 幀。換句話說就是,B 幀後面的 P 幀要優先於它進行解碼,然後才能將 B 幀解碼
- I 幀:關鍵幀
-
共享桌面原理
- 對於共享者,每秒鐘抓取多次屏幕(可以是 3 次、5 次等),每次抓取的屏幕都與上一次抓取的屏幕做比較,取它們的差值,然後對差值進行壓縮。再將壓縮後的數據通過傳輸模塊傳送到觀看端;數據到達觀看端後,再進行解碼,這樣即可還原出整幅圖片並顯示出來
- 對於遠程控制端,當用戶通過鼠標點擊共享桌面的某個位置時,會首先計算出鼠標實際點擊的位置,然後將其作爲參數,通過信令發送給共享端。共享端收到信令後,會模擬本地鼠標,即調用相關的 API,完成最終的操作
實時通信架構
協議
(S)RTP/(S)RTCP協議
-
實時互動直播系統的時候必須使用UDP 協議
- 因爲如果網絡不好,TCP的重傳算法是指數回退的,極端情況下會導致1分鐘以上的傳輸延遲,這對於實時通信系統是無法接受的
-
在實時互動直播系統傳輸音視頻數據流時,我們並不直接將音視頻數據流交給 UDP 傳輸,而是先給音視頻數據加個 RTP 頭,然後再交給 UDP 進行傳輸
- 因爲音視頻幀的大小遠大於UDP的最大傳輸單元(1.5KB左右),需要對分幀的包進行標記
- 例如I幀一般會有幾十KB,這樣就需要傳輸幾十的UDP包到終點並重新組裝成I幀並解碼
- 一般來說需要序號,起始和結束標記這幾個字段
- 因爲音視頻幀的大小遠大於UDP的最大傳輸單元(1.5KB左右),需要對分幀的包進行標記
-
RTP包頭字段
- sequence number:序號,用於記錄包的順序
- timestamp:時間戳,同一個幀的不同分片的時間戳是相同的
- 這樣就省去了前面所講的起始標記和結束標記,因爲不同幀的時間戳肯定是不一樣的
- PT:Payload Type,數據的負載類型
- 音頻流的 PT 值與視頻的 PT 值是不同的,通過它就可以知道這個包存放的是什麼類型的數據
- RTCP協議用於確定網絡鏈路質量
- RTCP 有兩個重要的報文:**RR(Reciever Report)**和 SR(Sender Report)
- 通過這兩個報文的交換,各端就知道自己的網絡質量到底如何了
- RTP/RTCP 協議並沒有對它的負載數據進行加密
- 因此,如果你通過抓包工具,如 Wireshark,將音視頻數據抓取到後,通過該工具就可以直接將音視頻流播放出來
- 爲了防止這類事情發生,沒有直接使用 RTP/RTCP 協議,而是使用了 SRTP/SRTCP 協議 ,即安全的 RTP/RTCP 協議
SDP協議
-
SDP就是用文本描述的各端(PC 端、Mac 端、Android 端、iOS 端等)的能力,用來進行媒體協商
- 這裏的能力指的是各端所支持的音頻編解碼器是什麼,這些編解碼器設定的參數是什麼,使用的傳輸協議是什麼,以及包括的音視頻媒體是什麼等等
- 通信雙方可以根據各自的能力進行協商,協商出大家認可的音視頻編解碼器、編解碼器相關的參數(如音頻通道數,採樣率等)、傳輸協議等信息
-
SDP信息的交換是通過信令服務器完成的
- 通信雙方都要先與信令服務器建立websocket連接,之後通過服務器轉發
-
通信中斷重連時要重新進行媒體協商
-
多方通信時,新用戶加入時,可以獲得先前加入用戶的音視頻流,但是老用戶無法獲取新用戶的流
- 因爲老用戶在進行媒體協商時,新用戶還不存在
- 所以每當有新的用戶進來之後,就通過 update 信令通知已經在房間內的所有用戶,讓它們重新與服務器進行媒體協商
- 重新協商後,所有老用戶就可以收到了新用戶的視頻流了
-
對於 1 對 1 通信的雙方來說,我們稱首先發送媒體協商消息的一方爲呼叫方,而另一方則爲被呼叫方
- 呼叫方發送的 SDP 消息稱爲 Offer,被呼叫方發送的 SDP 消息稱爲 Answer
-
SDP協議的片段
- SDP的格式非常簡單,由多個行組成,每個行都是
<type>=<value>
的格式 - SDP 是由一個會話層和多個媒體層組成的;而對於每個媒體層,WebRTC 又將其細劃爲四部分,即媒體流、網絡描述、安全描述和服務質量描述
- 下面的例子中有兩個媒體層——音頻媒體層和視頻媒體層
- SDP的格式非常簡單,由多個行組成,每個行都是
//=============會話描述====================
v=0
o=- 7017624586836067756 2 IN IP4 127.0.0.1
s=-
t=0 0
...
//================媒體描述=================
//================音頻媒體=================
/*
* 音頻使用端口1024收發數據
* UDP/TLS/RTP/SAVPF 表示使用 dtls/srtp 協議對數據加密傳輸
* 111、103 ... 表示本會話音頻數據的 Payload Type
*/
m=audio 1024 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126
//==============網絡描述==================
//指明接收或者發送音頻使用的IP地址,由於WebRTC使用ICE傳輸,這個被忽略。
c=IN IP4 0.0.0.0
//用來設置rtcp地址和端口,WebRTC不使用
a=rtcp:9 IN IP4 0.0.0.0
...
//==============音頻安全描述================
//ICE協商過程中的安全驗證信息
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
...
//==============音頻流媒體描述================
a=rtpmap:111 opus/48000/2
//minptime代表最小打包時長是10ms,useinbandfec=1代表使用opus編碼內置fec特性
a=fmtp:111 minptime=10;useinbandfec=1
...
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
...
//=================視頻媒體=================
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98
...
//=================網絡描述=================
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
...
//=================視頻安全描述=================
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
...
//================視頻流描述===============
a=mid:video
...
a=rtpmap:100 VP8/90000
//================服務質量描述===============
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack //支持丟包重傳,參考rfc4585
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb //支持使用rtcp包來控制發送方的碼流
a=rtcp-fb:100 transport-cc
...
STUN/TURN協議
-
webrtc在建連過程中,如果同時存在多個有效連接時,它會進行連通性測試,首先選擇傳輸質量最好的線路
- 例如能用內網連通就不用公網,如果嘗試了很多線路都連通不了,那麼它還會使用服務端中繼的方式讓雙方連通
- 連通性檢測時的超時設置比較重要,設置短了,會把可以連通的判斷爲不能連通,設置長了,就會在不能連通的配對上浪費時間
- 在中國,P2P 成功率很低,尤其是移動互聯網
-
如果想在服務器保留音視頻通話記錄,P2P的連接方式就不能用了
-
通信場景
- 如果雙方都在同一內網中,則優先走內網通信而不是公網
- 難點在於如何判定雙方位於同一網段
- 通過公網通信時,優先使用P2P方式直接連接
- 如果P2P不通,則通過服務器中繼轉發
- 如果雙方都在同一內網中,則優先走內網通信而不是公網
-
**ICE Candidate (ICE 候選者)**表示 WebRTC 與遠端通信時使用的協議、IP 地址和端口
- 一般由本地IP和端口,候選類型,優先級,傳輸協議等字段組成
- 候選類型包括host(本機或內網),srflx(內網經NAT映射的外網IP和端口)和relay(中繼候選者)
- relay候選者的連通率是所有候選者中連通率最高的
- WebRTC 會對候選者進行排序,然後按優先級從高到低的順序進行連通性測試
- 一般由本地IP和端口,候選類型,優先級,傳輸協議等字段組成
-
STUN 協議用於獲取自己映射的外網IP和端口
- 首先在外網搭建一個 STUN 服務器
- 從內網主機發送一個 binding request 的 STUN 消息到 STUN 服務器
- STUN 服務器收到該請求後,會將請求的 IP 地址和端口填充到 binding response 消息中,然後順原路將該消息返回給內網主機
- 收到 binding response 消息的內網主機就可以解析 binding response 消息了,並可以從中得到自己的外網 IP 和端口
-
TURN協議用於獲取 relay 服務器(即 TURN 服務器)的 Candidate
- 通過向 TURN 服務器發送 Allocation 指令,relay 服務就會在服務器端分配一個新的 relay 端口,用於中轉 UDP 數據報
-
ICE 就是上面所講的獲取各種類型 Candidate 的過程,或者說就是包括了 STUN、TURN 協議的一套框架
-
在本機收集所有的 host 類型的 Candidate,通過 STUN 協議收集 srflx 類型的 Candidate,使用 TURN 協議收集 relay 類型的 Candidate
NAT打洞
- 所謂的“打洞”就是在 NAT 上建立一個內外網的映射表
- UDP 是無連接協議,它沒有連接狀態的判斷,也就是說只要你發送數據給它,它就能收到。而 TCP 協議必須建立連接後,才能收發數據,因此大多數人都選用 UDP 作爲打洞協議
- 通過藉助 STUN/TURN 服務器完成 NAT 穿越
完全錐型
- 完全錐型 NAT 的特點是,當 host 主機通過 NAT 訪問外網的 B 主機時,就會在 NAT 上打個“洞”,所有知道這個“洞”的主機都可以通過它與內網主機上的偵聽程序通信
- 如果 host 主機與 B 主機“打洞”成功,且 A 與 C 從 B 主機那裏獲得了 host 主機的外網 IP 及端口,那麼 A 與 C 就可以向該 IP 和端口發數據
IP限制型
-
IP 限制錐型要比完全錐型 NAT 嚴格得多,它主要的特點是,host 主機在 NAT 上“打洞”後,NAT 會對穿越洞口的 IP 地址做限制
- 只有登記的 IP 地址纔可以通過,也就是說,只有 host 主機訪問過的外網主機才能穿越 NAT
- 而其他主機即使知道“洞”的位置,也不能與 host 主機通信,因爲在通過 NAT 時,NAT 會檢查 IP 地址,如果發現發來數據的 IP 地址沒有登記,則直接將該數據包丟棄
-
IP 限制型 NAT 只限制 IP 地址,如果是同一主機的不同端口穿越 NAT 是沒有任何問題的
端口限制型
- 端口限制錐型比 IP 限制錐型 NAT 更加嚴格,它主要的特點是,不光在 NAT 上對打洞的 IP 地址做了限制,而且還對具體的端口做了限制
對稱型
-
對稱型 NAT 是所有 NAT 類型中最嚴格的一種類型
- 對稱型 NAT 對每個連接都使用不同的端口,甚至更換 IP 地址,而端口限制型 NAT 的多個連接則使用同一個端口,這對稱型 NAT 與端口限制型 NAT 最大的不同
-
這種特性爲 NAT 穿越造成了很多麻煩,尤其是對稱型 NAT 碰到對稱型 NAT,或對稱型 NAT 遇到端口限制型 NAT 時,基本上雙方是無法穿越成功的
NAT類型檢測步驟
服務質量
-
物理鏈路質量
- 影響因素:丟包,延遲,抖動
- 延遲最好小於200ms
- 抖動指的是數據一會兒快、一會兒慢,很不穩定。如果不加處理的話,你看到的視頻效果就是一會兒快播了、一會兒又慢動作
- WebRTC通過內部的 JitterBuffer(可以簡單地理解爲一塊緩衝區)來解決該問題
-
帶寬大小
- 指的是每秒鐘可以傳輸多少bit,比如 1M 帶寬,它表達的是每秒鐘可以傳輸 1M 個 bit 位
- 換算成字節就是 1Mbps/8 = 128KBps,也就是說 1M 帶寬實際每秒鐘只能傳輸 128K 個 Byte
- 延遲是因爲你的網終帶寬與音視頻流大小不匹配
-
幀率
- 通過減少幀率來控制碼率的效果可能並不明顯
- 因爲在傳輸數據之前是要將原始音視頻數據進行壓縮的,在同一個 GOP(Group Of Picture)中,除了 I/IDR 幀外,B 幀和 P 幀的數據量是非常小的
- 因此幀率與延遲的關係不是特別大,實際上分辨率纔是影響最大的
通信安全
- TLS 底層是基於 TCP 協議的,而 WebRTC 音視頻數據的傳輸主要基於 UDP 協議,因此 WebRTC 對數據的保護無法直接使用 TLS 協議
- DTLS 就是運行在 UDP 協議之上的簡化版本的 TLS,它使用的安全機制與 TLS 幾乎一模一樣
- webRTC通過使用 SDP、STUN、DTLS、SRTP 等幾個協議的結合來達到數據安全的
- 首先通過信令服務器交換 SDP,SDP 信息中包括了對方的 ice-ufrag、ice-pwd 和 fingerprint 信息,有了這些信息後,就可驗證對方是否是一個合法用戶了
- ice-ufrag 和 ice-pwd 是用戶名和密碼
- 當 A 與 B 建立連接時,A 要帶着它的用戶名和密碼過來,此時 B 端就可以通過驗證 A 帶來的用戶名和密碼與 SDP 中的用戶名和密碼是否一致的,來判斷 A 是否是一個合法用戶了
- fingerprint 是存放公鑰證書的指紋(或叫信息摘要)
- 在通過 ice-ufrag 和 ice-pwd 驗證用戶的合法性之餘,還要對它發送的證書做驗證,看看證書在傳輸的過程中是否被竄改了
- 緊接着通過 STUN 協議利用前面的信息進行身份認證
- 如果 STUN 消息中的用戶名和密碼與交換的 SDP 中的用戶名和密碼一致,則說明是合法用戶
- 確認對端合法後,則發送 DTLS 消息與服務端進行 DTLS “握手”
- 在“握手”過程中要交換雙方的安全證書和公鑰等相關信息,確認其沒有在傳輸中被竄改
- 使用協商後的密碼信息和公鑰對數據進行加密,開始傳輸音視頻數據
- 首先通過信令服務器交換 SDP,SDP 信息中包括了對方的 ice-ufrag、ice-pwd 和 fingerprint 信息,有了這些信息後,就可驗證對方是否是一個合法用戶了
多方通信方案
mesh方案
-
多個終端之間兩兩進行連接,同時還分別與 STUN/TURN 服務器進行連接,形成一個網狀結構
-
當某個瀏覽器想要共享它的音視頻流時,它會將共享的媒體流分別發送給其他 3 個瀏覽器,這樣就實現了多人通
-
優點
- 不需要服務器中轉數據,STUN/TUTN 只是負責 NAT 穿越,這樣利用現有 WebRTC 通信模型就可以實現,而不需要開發媒體服務器
- 充分利用了客戶端的帶寬資源
- 節省了服務器資源,由於服務器帶寬往往是專線,價格昂貴,這種方案可以很好地控制成本
-
缺點
- 這種方案對各終端的上行帶寬佔用很大,同時也會大量佔用 CPU、Memory 等資源
- 導致多人通信的規模非常有限
- 通過實踐來看,這種方案在超過 4 個人時,就會有非常大的問題
- 如果有部分人不能實現 NAT 穿越,但還想讓這些人與其他人互通,就顯得很麻煩
MCU方案
-
該方案由一個服務器和多個終端組成一個星形結構
-
各終端將自己要共享的音視頻流發送給服務器,服務器端會將在同一個房間中的所有終端的音視頻流進行混合,最終生成一個混合後的音視頻流再發給各個終端
- 以上圖爲例,若B1 與 B2 同時共享音視頻流,它們首先將流推送給 MCU 服務器,MCU 服務器收到兩路流後,分別將兩路流進行解碼,之後將解碼後的兩路流進行混流,然後再編碼,編碼後的流數據再分發給 B3 和 B4
-
優點
- 通過解碼、再編碼可以屏蔽不同編解碼設備的差異化,滿足更多客戶的集成需求
-
缺點
- 重新解碼、編碼、混流,需要大量的運算,對服務器 CPU 資源的消耗很大,且會帶來延遲
- 由於機器資源耗費很大,所以 MCU 所提供的容量有限,一般十幾路視頻就是上限了
SFU方案
- SFU 是三種架構方案中優勢最明顯而劣勢又相對較少的一種架構方案
- WebRTC 普及以後,支持 WebRTC 多方通信的媒體服務器基本都是 SFU 結構
- 該方案也是由一個服務器和多個終端組成,但與 MCU 不同的是,SFU 不對音視頻進行混流
- SFU服務器收到某個終端共享的音視頻流後,就直接將該音視頻流轉發給房間內的其他終端
-
優點
- 由於是數據包直接轉發,不需要編碼、解碼,對 CPU 資源消耗很小,同時降低了延遲,提高了實時性
- 可以根據終端下行網絡狀況做一些流控,可以根據當前帶寬情況、網絡延時情況,選擇性地丟棄一些媒體數據,保證通信的連續性
-
缺點
- 由於是數據包直接轉發,參與人觀看多路視頻的時候可能會出現不同步
- 相同的視頻流,不同的參與人看到的畫面也可能不一致
-
simulcast模式
- 指視頻的共享者可以同時向 SFU 發送多路不同分辨率的視頻流(一般爲三路,如 1080P、720P、360P)
- 而 SFU 可以將接收到的三路流根據各終端的情況而選擇其中某一路發送出去
- 例如,由於 PC 端網絡特別好,給 PC 端發送 1080P 分辨率的視頻;而移動網絡較差,就給 Phone 發送 360P 分辨率的視頻
- 可以靈活而又智能地適應不同的網絡環境
- SVC模式
- 在視頻編碼時將視頻分成多層——核心層、中間層和擴展層
- 上層依賴於底層,而且越上層越清晰,越底層越模糊。在帶寬不好的情況下,可以只傳輸底層,即核心層,在帶寬充足的情況下,可以將三層全部傳輸過去
- 通過錄制桌面,可以把多路音視頻流錄製下來以進行回放
- 利用一個虛擬客戶端接入 SFU 服務器,僅拉流,不上傳流