史上最全的WebRTC服務器技術選型分析

想學更多的WebRTC知識,請關注WebRTC中文社區

下面就來探討下常見的SFU開源解決方案,固然,你也能夠本身實現 SFU 流媒體服務器,但自已實現流媒體服務器困難仍是蠻多的,它裏面至少要涉及到 DTLS 協議、ICE 協議、SRTP/SRTCP 協議等,光理解這些協議就要花很多的時間,更況且要實現它了。html

前言

因此最多見的辦法就是使用開源的實現。可是這裏我也想給你們說必定,用了開源的解決方案,能快速的搭建起業務,可是無疑也欠下了技術債,由於開源的解決方案確定沒有本身實現的要熟悉,由於不熟悉不少時候出現了問題,並不能立刻解決,甚至解決不了,致使業務受到影響。並且熟悉開源解決方案都是須要一個時間和過程的,而通常領導會不會給你這個時間就兩說了。java

但若是你要快速的搭建起音視頻系統的話,無疑使用開源技術解決方案是最快,最能節省人力成本的。下面咱們就來分析下常見的SFU開源解決方案的優缺點,以便你選擇合適的開源解決方案。android

Licode

Licode 既能夠用做 SFU 類型的流媒體服務器,也能夠用做 MCU 類型的流媒體服務器。通常狀況下,它都被用於 SFU 類型的流媒體服務器。ios

Licode 不只僅是一個流媒體通訊服務器,並且仍是一個包括了媒體通訊層、業務層、用戶管理等功能的完整系統,而且該系統還支持分佈式部署。c++

Licode 是由 C++ 和 Node.js 語言實現。其中,媒體通訊部分由 C++ 語言實現,而信令控制、用戶管理、房間管理用 Node.js 實現。它的源碼地址爲:https://github.com/lynckia/licode 。下面這張圖是 Licode 的總體架構圖:git

avatar 經過這張圖你能夠看出,Licode 從功能層面來說分紅三部分,即 Nuve 、ErizoController 和 ErizoAgent 三部分,它們之間經過消息隊列進行通訊。github

  • Nuve 是一個 Web 服務,用於管理用戶、房間、產生 token 以及房間的均衡負載等相關工做。它使用 MangoDB 存儲房間和 token 信息,但不存儲用戶信息。
  • ErizoController,用於管理控制,信令和非音視頻數據都經過它接收。它經過消息隊列與 Nuve 進行通訊,也就是說 Nuve 能夠經過消息隊列對 ErizoController 進行控制。
  • ErizoAgent,用於音視頻流媒體數據的傳輸,能夠分佈式佈署。ErizoAgent 與 ErizoController 的通訊也是經過消息隊列,信令消息經過 ErizoController 接收到後,再經過消息隊列發給 ErizoAgent,從而實現對 ErizoAgent 進行控制。

Licode 不只僅是一個 SFU 流媒體服務器,它還包括了與流媒體相關的業務管理系統、信令系統、流媒體服務器以及客戶端 SDK 等等,能夠說它是一個比較完善的產品。web

若是你使用 Licode 做爲流媒體服務器,基本上不須要作二次開發了,因此這樣一套系統對於沒有音視頻積累的公司和我的具備很是大的誘惑力。目前 Intel CS 項目就是在 Licode 基礎上研發出來的,已經爲很多公司提供了服務。瀏覽器

官網提供學習demo,和文檔。服務器

但 Licode 也有如下一些缺點:

  • github star 2.4k issue和pr至關活躍,社區採用的是傳統提問,及時溝通相對較差
  • 在 Linux 下目前只支持 Ubuntu 14.04 版本,在其餘版本上很難編譯經過。
  • Licode 不只包括了 SFU,並且包括了 MCU,因此它的代碼結構比較重,學習和掌握它要花很多的時間。
  • Licode 的性能通常, 若是你把流媒體服務器的性能排在第一位的話,那麼 Licode 就不是特別理想的 SFU 流媒體服務器了。
  • 官方沒有看到android和ios的SDK,有其餘人實現,可是早已經不更新,若是你要考慮安卓和ios的話,可能本身會下功夫。

Janus-gateway

Janus 是一個很是有名的 WebRTC 流媒體服務器,它是以 Linux 風格編寫的服務程序,採用 C 語言實現,支持 Linux/MacOS 下編譯、部署,但不支持 Windows 環境。

它是一個開源項目,其源碼的編譯、安裝很是簡單,只要按 GitHub 上的說明操做便可。源碼及編譯手冊的地址爲:https://github.com/meetecho/janus-gateway

Janus 的部署也十分簡單,具體步驟詳見文檔,地址爲:https://janus.conf.meetecho.com/docs/deploy.html

avatar 從上面的架構圖中,你能夠看出 Janus 分爲兩層,即應用層和傳輸層。

插件層又稱爲應用層,每一個應用都是一個插件,能夠根據用戶的須要動態地加載或卸載掉某個應用。插件式架構方案是很是棒的一種設計方案,靈活、易擴展、容錯性強,尤爲適用於業務比較複雜的業務,但缺點是實現複雜,成本比較高。

在 Janus 中默認支持的插件包括如下幾個。

  • SIP:這個插件使得 Janus 成了 SIP 用戶的代理,從而容許 WebRTC 終端在 SIP 服務器(如 Asterisk)上註冊,並向 SIP 服務器發送或接收音視頻流。
  • TextRoom:該插件使用 DataChannel 實現了一個文本聊天室應用。
  • Streaming:它容許 WebRTC 終端觀看 / 收聽由其餘工具生成的預先錄製的文件或媒體。
  • VideoRoom:它實現了視頻會議的 SFU 服務,實際就是一個音 / 視頻路由器。
  • VideoCall:這是一個簡單的視頻呼叫的應用,容許兩個 WebRTC 終端相互通訊,它與 WebRTC 官網的例子類似(https://apprtc.appspot.com),不一樣點是這個插件要通過服務端進行音視頻流中轉,而 WebRTC 官網的例子走的是 P2P 直連。
  • RecordPlay:該插件有兩個功能,一是將發送給 WebRTC 的數據錄製下來,二是能夠經過 WebRTC 進行回放。

傳輸層包括媒體數據傳輸和信令傳輸。媒體數據傳輸層主要實現了 WebRTC 中須要有流媒體協議及其相關協議,如 DTLS 協議、ICE 協議、SDP 協議、RTP 協議、SRTP 協議、SCTP 協議等。

信令傳輸層用於處理 Janus 的各類信令,它支持的傳輸協議包括 HTTP/HTTPS、WebSocket/WebSockets、NanoMsg、MQTT、PfUnix、RabbitMQ。不過須要注意的是,有些協議是能夠經過編譯選項來控制是否安裝的,也就是說這些協議並非默認所有安裝的。另外,Janus 全部信令的格式都是採用 Json 格式。

Janus 總體架構採用了插件的方案,這種架構方案很是優秀,用戶能夠根據本身的須要很是方便地在上面編寫本身的應用程序。

並且它目前支持的功能很是多,好比支持 SIP、 RTSP、音視頻文件播放、錄製等等,因此在與其餘系統的融合性上有很是大的優點。

另外,它底層的代碼是由 C 語言編寫的,性能也很是強勁。Janus 的開發、部署手冊也很是完善,所以它是一個很是棒的開源項目。

github star4.1k,而且處理issue和pr相對較快。

官方提供安卓和ios的sdk。

缺點:

  • 架構太複雜,不適合初學者,公司採用的話人力成本和事件成本會比較高
  • janus 底層沒有使用 epoll 這類異步I/O事件處理機制,這應該說是它的一大缺陷
  • Janus還使用 glib 庫,因爲 glib 庫對於國內的不少開發同窗來講用的比較少,因此會有必定的學習成本

Mediasoup

Mediasoup 是推出時間不長的 WebRTC 流媒體服務器開源庫,其地址爲:https://github.com/versatica/mediasoup/

Mediasoup 由應用層和數據處理層組成。應用層是經過 Node.js 實現的;數據處理層由 C++ 語言實現,包括 DTLS 協議實現、ICE 協議實現、SRTP/SRTCP 協議實現、路由轉發等。

avatar Mediasoup 把每一個實例稱爲一個 Worker,在 Worker 內部有多個 Router,每一個 Router 至關於一個房間。在每一個房間裏能夠有多個用戶或稱爲參與人,每一個參與人在 Mediasoup 中由一個 Transport 代理。換句話說,對於房間(Router)來講,Transport 就至關於一個用戶。

Transport 有三種類型,即 WebRtcTransport、PlainRtpTransport 和 PipeTransport。

  • WebRtcTransport 用於與 WebRTC 類型的客戶端進行鏈接,如瀏覽器。
  • PlainRtpTransport 用於與傳統的 RTP 類型的客戶端鏈接,經過該 Transport 能夠播放多媒體文件、FFmpeg 的推流等。
  • PipeTransport 用於 Router 之間的鏈接,也就是一個房間中的音視頻流經過 PipeTransport 傳到另外一個房間。

在每一個 Transport 中能夠包括多個 Producer 和 Consumer。

  • Producer 表示媒體流的共享者,它又分爲兩種類型,即音頻的共享者和視頻的共享者。
  • Consumer 表示媒體流的消費者,它也分爲兩種類型,即音頻的消費者和視頻的消費者。

Mediasoup 的實現邏輯很是清晰,它不關心上層應用該如何作,只關心底層數據的傳輸,並將它作到極致。

Mediasoup 底層使用 C++ 開發,使用 libuv 做爲其異步 IO 事件處理庫,因此保證了其性能的高效性。同時它支持了幾乎全部 WebRTC 爲了實時傳輸作的各類優化,因此說它是一個特別優秀的 WebRTC SFU 流媒體服務器。

它與 Janus 相比,它更聚焦於數據傳輸的實時性、高效性、簡潔性,而 Janus 相比 Mediasoup 作的事兒更多,架構和邏輯也更加複雜。

對於開發能力比較強的公司來講,根據本身的業務須要在 Mediasoup 上作二次開發也是很是值得推薦的技術方案。

手機端的話須要本身實現安卓和ios的SDK

Medooze

Medooze 是一款綜合流媒體服務器,它不只支持 WebRTC 協議棧,還支持不少其餘協議,如 RTP、RTMP 等。其源碼地址爲:https://github.com/medooze/media-server

avatar 從大的方面來說,Medooze 支持 RTP/RTCP、SRTP/SRCP 等相關協議,從而能夠實現與 WebRTC 終端進行互聯。除此以外,Medooze 還能夠接入 RTP 流、RTMP 流等,所以你可使用 GStreamer/FFmpeg 向 Medooze 推流,這樣進入到同一個房間的其餘 WebRTC 終端就能夠看到 / 聽到由 GStream/FFmpeg 推送上來的音視頻流了。另外,Medooze 還支持錄製功能,即上圖中的 Recorder 模塊的做用,能夠經過它將房間內的音視頻流錄製下來,以便後期回放。

Medooze 的控制邏輯層是經過 Node.js 實現的,Medooze 經過 Node.js 對外提供了完整的控制邏輯操做相關的 API,經過這些 API 你能夠很容易的控制 Medooze 的行爲了。

Medooze 與 Mediasoup 相比,二者在覈心層實現的功能都差很少,但 Medooze 的功能更強大,包括了錄製、推 RTMP 流、播放 FLV 文件等相關的操做,而 Mediasoup 則沒有這些功能。

Medooze 也有一些缺點,儘管 Medooze 也是 C++ 開發的流媒體服務務器,使用了異步 IO 事件處理機制,但它使用的異步 IO 事件處理的 API 是 poll,poll 在處理異步 IO 事件時,與 Linux 下最強勁的異步 IO 事件 API epoll 相比要遜色很多,這致使它在接收 / 發送音視頻包時性能比 Mediasoup 要稍差一些。

jitsi

使用Java構建的服務端,底層也是使用c/c++,使用Java語言因此性能上沒有使用c/c++的表現好。

主要模塊及實現語言:

  1. Jitsi Video-Bridge (Software video-bridge 實現語言java)
  2. Jitsi Jicofo (Component mandatory for jitsi conference 實現語言java)
  3. Prosody ( XMPP Server 實現語言lua)
  4. Nginx (Web Server)
  5. Jitsi Meet (Web application – to which the end user will interact. 實現語言js)

優勢:

  • github star12.3k,issue和pr處理快
  • 文檔齊全
  • 官方提供安卓和ios SDK,也能夠自行編譯SDK,使用的是React Native
  • 官方提供web端的SDK,並提供使用electron進行桌面端打包(端很齊全)
  • 社區採用論壇方式溝通,活躍較高
  • 社區提供分佈式解決方案,可是文檔偏少。
  • 每週一維護團隊在jitsi上進行視頻會議,回答開發者的提問,溝通使用英文,國內時間好像是晚上。
  • 社區版本更新迭代較快

Kurento

Kurento和jitsi是同樣,持續維護了不少年,通過了時間的檢驗。不一樣的是他是使用c++開發,有豐富的文檔和示例褲,對於開發者來講很是友好。

pion/webrtc

WebRTC API的Pure Go實現,github上star4.7k,目前用的人較少,不建議使用生成環境,能夠學習參考使用,建議長期關注。

總結:

對流媒體服務器的選擇,沒有最好,只有最合適。每一個開源實現都有其各自的特色,均可以應用到實際產品中,只不過做爲開發人員都有本身獨特的技術背景,你須要根據自身特色以及項目特色選一個最合適的。接下來,我就介紹一下我是如何對這些開源項目進行評判和選擇的。

  1. 團隊 在一個團隊中確定會選擇一種你們都比較熟悉的語言做爲項目開發的語言,因此咱們在選擇開源項目時,就要選擇使用這種語言開發的開源項目。 好比阿里系基本都用 Java 語言進行開發,因此它們在選擇開源項目時,基本都會選擇 Java 開發的開源項目; 而作音視頻流媒體服務的開發人員,爲了追求性能,因此通常都選擇 C/C++ 語言開發的開源項目。 團隊人手若是不充裕的狀況下,儘可能就不要選擇特別複雜的,和文檔比較少的開源技術。

  2. 適合業務 要充分考慮到你的業務的用戶量和用戶羣體,若是你的業務量很大,須要作分佈式,那麼你選擇的開源技術必定要先去了解下他是否支持分佈式部署,分佈式部署採用那種方式。單機支持多少併發,最好本身用服務器實際測試下,官方數據會和實際測試數據多少都有出入。 項目功能也須要考慮,好比業務須要錄製回放,開源技術並無這樣的功能,須要本身開發,時間成本很高,但選擇已經作好錄製回放功能的開源技術又不同了。

  3. 二次開發 Licode 是一個完整的系統,支持分佈式集羣部署,因此係統相對複雜,學習週期要長一些。它能夠直接佈署在生產環境,可是二次開發的靈活性不夠。 Janus-gateway 是一個獨立的服務,支持的信令協議很豐富,並且支持插件開發,易擴展,對於 Linux/C 背景的開發者是很不錯的選擇。 Medooze 和 Mediasoup 都是流媒體服務器庫,對於須要將流媒體服務器集成到本身產品中的開發者來講,應該選擇它們。

  4. 時間成本 公司對於項目的時間計劃和成本也要考量,由於使用開源技術或多或少都會遇到坑,有可能一個坑會卡好久,因此使用文檔全,社區活躍的開源技術比較好。

不管選擇哪一種開源技術,前期必定要作好調研,並實際本身搭建使用過在作決定,選擇好後,爲了彌補技術債,須要去深刻開源技術的代碼,否則還債的時候很疼苦。

在這裏插入圖片描述

相關文章
相關標籤/搜索