架構設計:基於Webrtc、Kurento的一種低延遲架構實現
前言
在音視訊領域,低延遲互動一直是一個非常重要的需求。
而直播大多基於RTMP協議,其存在1到3秒左右的延遲,基本無法勝任低延遲互動的需求;另外在遊戲領域、語音聊天、教育領域,低延遲也是一個非常重要的議題。
下面以直播的連麥架構的設計來簡單介紹下整個架構設計的演進流程。
最樸素的連麥架構(基於RTMP)
架構設計

基於RTMP的連麥設計.png
架構解析
- 連麥端A/B存在多平臺特性,例如Android、iOS、PC(Web)等,其利用RTMP協議將音視訊推送到RTMP伺服器。
- 連麥端A在推送RTMP的同時,拉取連麥端B的RTMP流資料用於播放。
- RTMP服務端通過CDN海量分發,將兩路音視訊資料推送到觀眾端。
存在問題:
由於RTMP天然存在延遲的特性,業界統計大概在1~3秒之間。
如果我們以一個連麥端點在推流和播流之間的延遲以一個 delay_time (延遲時間)來表示。
也就是說A端看到B端的音視訊流是一個 delay_time 之前的資料,如果A端做出迴應,那麼B端在整個迴應需要浪費兩個 delay_time 時間(A到B的延遲+B迴應A的延遲)。

迴應延遲示例.png
理論上延遲需要控制在500毫秒以內才能保證流暢的交流,上述設計明顯是不可接受的,自然架構需要升級。
引入實時通訊的開源框架Webrtc
什麼是webrtc
WebRTC 全稱 Web Real-Time Communication。 包含了媒體、加密、傳輸層等在內的多個協議,極大的降低了音視訊實時通訊技術的門檻。
- Andorid/iOS端音視訊資料採集。
- 靈活的信令控制設計。
- 迴音消除模組、加密模組。
- 低延遲的音視訊流傳輸協議
webrtc的官網地址: ofollow,noindex">https://webrtc.org
webrtc編譯可以參考: Webrtc 研究: Android編譯
架構設計

引入webrtc的連麥設計.png
架構解析
關注紅框部分,這裡將連麥端A/B的互動由RTMP改為webrtc實現,由於webrtc是一個低延遲的框架,保證了雙端互動的實時性。
存在問題
這個框架其實還有一個問題,就是雖然連麥雙端利用webrtc進行交流,但是其分發到CDN的流資料都是獨立傳送的,也就是沒有一個同步機制可以控制多路流的時基一致性。
通俗點講,假設一個問問題的場景,並且此時候A端到觀眾端有3秒延遲,B端到觀眾端有1秒延遲,那麼會出現這麼奇怪的場景:B端先回答了問題,然後A端由於延遲才提問問題。

獨立推流同步控制.png
引入本地多路流同步機制
解決思路
如果在RTMP獨立推流的情況,一旦出現網路抖動;容易出現各個直播流到觀眾端的延遲不可控,而出現了答非所問的尷尬場景。
架構設計

本地合流設計.png
架構解析
連麥端點A通過提取webrtc的實時音視訊流資料,與本地採集到的音視訊流資料進行混流;並且將混流完畢後所得的流資料通過RTMP推送到CDN。以此代替兩端獨立推流的設計,並且可以在A端(混流端)可以進行同步控制。
存在問題
- 多點連麥存在webrtc流網路複雜的問題。
由於webrtc是點對點通訊,並不支援廣播,所以一旦終端節點增多,其實時互動網路複雜度將會迅速提升。
簡單列舉下:
2個端點需要建立2條webrtc通道。
3個端點需要建立6條webrtc通道。
n個端點需要建立n*(n-1)條webrtc通道。

組網示意圖.png
- 混流端機器效能要求高、壓力比較大。
這個設計將混流推流壓力集中在其中一個端點,例如3連麥端點組網的話,混流端點需要實現如下工作:
1.傳送2路webrtc流
2.接收2路webrtc流
3.採集1路音視訊流
4.解碼2路webrtc流
5.合併3路音視訊
6.編碼1路rtmp流
7.傳送1路rtmp流
一般來說,移動裝置的效能並不能完全hold住這些io、計算密集型的任務,所以隨著連麥節點的增加,混流端點的壓力也會加倍增長。
- 連麥端到端音視訊流資料不可控。
由於webrtc的基於p2p的特性,一旦通過服務端完成信令互動後。服務端在後續的音視訊資料傳輸並不需要也不能進行監控處理,也就是說對於一些視訊備份、關鍵幀鑑別等功能是無法實現的。
媒體伺服器Kurento的使用
簡單說下kurento
Kurento 是一個 WebRTC 流媒體伺服器以及一些客戶端API,有了它,開發WWW及智慧手機平臺的高階視訊應用就變得更加容易。
- 群組通訊(group communications)。
- 媒體流的轉碼、錄製、廣播、路由。
- 高階媒體處理特性,包括:機器視覺、視訊索引、增強現實、語音分析。
官網地址: http://www.kurento.org
架構設計

媒體伺服器設計.png
架構解析
引入了Kurento這個媒體伺服器來替換上面的混流端點。
- 由於媒體伺服器也是一個webrtc端點,其完美支援與終端的實時音視訊流通訊;
- 同時Kurento還支援對音視訊進行預處理,例如影象增強、轉發RTP、本地快取等功能;
- 而且建立在伺服器資源上的視訊資料處理也能更好的解決多端點連麥帶來的效能瓶頸。
最後通過Kurento媒體伺服器將處理完畢資料轉發到RTMP伺服器,並通過CDN分發推送到海量觀眾端。
Kurento的進一步設計
當然Kurento僅僅只是一個媒體伺服器,我們同時也需要一個跟媒體伺服器核心打交道的業務模組,其實Kurento已經把我們把生態建立好了。
有以下幾個開源庫提供我們二次開發:
信令服務架構設計

信令伺服器.png
架構解析
連麥終端(Android/iOS/Web)在Kurento-room建立房間以及使用者等角色,並且根據特定業務需求,聊天伺服器充當連麥終端與媒體伺服器的交流媒介,並通過業務需求觸發媒體伺服器構建業務管道(例如建立轉發管道、視訊幀預處理管道等),等信令互動完畢後,連麥終端直接與媒體伺服器建立webrtc資料傳輸通道。
Kurento的缺陷
由於Kurento並沒有提供RTMP的轉發模組,所以除非實現自定義Kurento模組,否則無法實現媒體伺服器直接推送RTMP流資料,但是Kurento已經提供了RTP的轉發模組,所以我們可以藉助RTP轉發模組間接實現RTMP的轉發推流。
Kurento轉發端點設計

轉發實現.png
筆者發現以下兩種轉發的實現方案:
gstreamer轉發模組
筆者實現的一個轉發管道,主要流程是:
RTP解包 —— 音視訊轉換 —— FLV封包 —— RTMP推流
具體元件如下:

Gstreamer管道設計.png
結語
這篇文章簡單介紹了基於Webrtc和Kurento為基礎實現的低延遲架構的設計,由於立足於架構介紹,所以沒有對單獨各個點深入講解,後續會針對各個部分講解實現細節。
End!