WebRTC Gateway Janus入門:從配置到編寫外掛

WebRTC中文網發表於2018-04-26

本文首發於WebRTC中文網,轉載請註明出處

作者: 張鵬,資深音視訊工程師

janus介紹

janus是Meetecho開發的一個WebRTC閘道器,janus的主要作用就是它可以和你的內網裝置和瀏覽器同時建立連線,並將瀏覽器發來的音視訊資料包如rtp/rtcp包,通過自定義外掛轉發給你的內網裝置,也可以將你發給janus的音視訊資料包,加密後轉發給瀏覽器。

這樣就完成了內網音視訊伺服器和外網瀏覽器的互通。

janus為我們完成了與瀏覽器建立會話的複雜邏輯,並且提供給我們簡單的外掛機制來處理音視訊資料。

對於PeerConnection連線的建立過程,涉及到複雜的NAT穿透的ICE協議的實現,SDP的交換,DTLS-SRTP的握手和資料包加密傳送,資料包接收後解密的複雜邏輯。 janus將我們從與瀏覽器互動的PeerConnection建立的過程中解脫出來,更專注於音視訊業務邏輯。

janus的設計思想

janus基於外掛思想,通過實現基礎架構,完成了與瀏覽器連結的建立過程。

janus的外掛主要完成一些必須的函式實現,如RTP/RTCP資料的接收。

我們通過實現自己的外掛,來完成在將瀏覽器RTP資料轉發到內網伺服器的業務邏輯。

janus的用途

janus一般用於擴充已有視訊會議系統,提供對瀏覽器客戶端的支援。

##janus的安裝

官網安裝步驟

按照官網的安裝步驟可以順利的完成安裝。

本文在ubuntu16.04系統下測試。

首先安裝全新虛擬機器ubuntu16.04

下載原始碼,需要先安裝git

    git clone git@github.com:meetecho/janus-gateway.git
複製程式碼

然後安裝janus依賴庫

  sudo apt-get install aptitute
      sudo aptitude install libmicrohttpd-dev libjansson-dev libnice-dev \
    	libssl-dev libsrtp-dev libsofia-sip-ua-dev libglib2.0-dev \
    	libopus-dev libogg-dev libcurl4-openssl-dev liblua5.3-dev \
    	pkg-config gengetopt libtool automake
複製程式碼

安裝libsrtp 2.0

    wget https://github.com/cisco/libsrtp/archive/v2.0.0.tar.gz
    tar xfv v2.0.0.tar.gz
    cd libsrtp-2.0.0
    ./configure --prefix=/usr --enable-openssl
    make shared_library && sudo make install
複製程式碼

編譯安裝janus

    git clone https://github.com/meetecho/janus-gateway.git
    cd janus-gateway
    sh autogen.sh
    ./configure --prefix=/opt/janus
    make
    sudo make install
複製程式碼

到此為止,janus安裝到了/opt/janus目錄

##janus的配置檔案

janus的執行需要進行一些配置

使用命令生成一些預設配置檔案

    cd janus-gateway
    make configs
複製程式碼

對於最基本的演示用途,配置到此就結束了。

詳細的配置可以開啟檔案/opt/janus/etc/janus/janus.cfg按照註釋進行配置。

執行janus伺服器

直接啟動janus的可執行程式即可前臺執行janus

    cd /opt/janus/bin
    ./janus
複製程式碼

執行janus http server

我們需要研究janus提供的demo,比如EchoTest。我們需要在瀏覽器中開啟測試網頁才可以進行測試。所以,我們需要一個http server

    cd /opt/janus/share/janus/demos
    python -m SimpleHTTPServer
    命令列輸出:Serving HTTP on 0.0.0.0 port 8000 ...
複製程式碼

這樣就搭建了簡單的http server,監聽埠為8000 使用瀏覽器開啟地址,假設ubuntu 16.04的ip為10.1.32.146

    http://10.1.32.146:8000/
複製程式碼

即可看到janus的官網執行起來了。

執行狀態

執行echotest

  • 首先確保你有攝像頭和麥克風

  • 選擇Demos->Echo Test

  • 點選start就能夠正常執行演示程式。

  • Echo Test完成了將瀏覽器發來的音視訊資料,發回給瀏覽器。

  • 演示了會話建立,外掛編寫等基本功能。

  • Echo Test對應的外掛原始碼為janus-gateway/plugins/janus_echotest.c 通過閱讀janus-gateway/plugins/plugin.h中的註釋,可以基本瞭解外掛編寫的規則。

janus.js的作用

在echo test的例子中,前端部分使用了janus.js。janus.js是和janus伺服器進行通訊的javascript庫,通過使用janus.js簡化了webrtc api的使用,以及前端與janus伺服器建立連線,交換sdp等功能。如果你不依賴於janus.js你可以自行實現這些邏輯,不過會比較複雜。

janus伺服器和瀏覽器建立會話的過程

整個會話建立的過程符合標準的webrtc peerconnection連線建立的過程。這裡的janus伺服器就像另一個瀏覽器端一樣。兩端分別通過stun server拿到自己的外網地址,以及內網地址。推薦看一下ICE協議文件,深入瞭解下NAT穿透的過程。

然後交換sdp方面。在生成sdp的過程中,我們可以通過設定需要使用的音視訊編解碼引數,來要求瀏覽器使用我們希望使用的音視訊編碼。

sdp交換後,雙方進行連通性測試,即UDP打洞過程。由於echo test中我們並沒有配置stun server,所以無法獲取到外網IP。所以最終打洞成功的只有本地區域網地址。

janus的外掛機制介紹

janus的關鍵概念是它的外掛機制。janus底層完成了連線建立的通用部分,而把具體業務部分作為外掛來提供。對於會話的整個生命週期,都會有對應的外掛回撥產生。外掛在自己的實現中,完成了需要的業務邏輯。如echo test就在它的業務邏輯中給瀏覽器原樣返回了RTP資料。而我們公司的業務就是將資料轉發到媒體伺服器的某個會議中。

janus如何編寫外掛

janus plugin需要實現的介面

在plugins.h標頭檔案中,定義了外掛結構體struct janus_plugin。我們只需要按照struct janus_plugin中定義的函式,逐個實現,就可以完成外掛的編寫。

需要實現的介面有:

    struct janus_plugin {
    	int (* const init)(janus_callbacks *callback, const char *config_path);
    	void (* const destroy)(void);
    	int (* const get_version)(void);
    	const char *(* const get_package)(void);
    	void (* const create_session)(janus_plugin_session *handle, int *error);
    	struct janus_plugin_result * (* const handle_message)(janus_plugin_session *handle, char *transaction, json_t *message, json_t *jsep);
    	void (* const setup_media)(janus_plugin_session *handle);
    	void (* const incoming_rtp)(janus_plugin_session *handle, int video, char *buf, int len);
    	void (* const incoming_rtcp)(janus_plugin_session *handle, int video, char *buf, int len);
    	void (* const incoming_data)(janus_plugin_session *handle, char *buf, int len);
    	void (* const destroy_session)(janus_plugin_session *handle, int *error);
    	...
    };
複製程式碼

這些介面體現了整個會話的生命週期。對於incoming_rtp,incoming_rtcp,incoming_data來說,分別代表收到的瀏覽器發來的rtp,rtcp,自定義資料。這是我們媒體處理的重點。你可以根據業務需求去實現自己的邏輯。

使用janus_callbacks轉發資料給瀏覽器

當我們希望janus幫助我們把資料發給對方時,我們需要使用janus暴露給我們的callback:

    struct janus_callbacks {
    	void (* const relay_rtp)(janus_plugin_session *handle, int video, char *buf, int len);
    	void (* const relay_rtcp)(janus_plugin_session *handle, int video, char *buf, int len);
    	void (* const relay_data)(janus_plugin_session *handle, char *buf, int len);
    	void (* const close_pc)(janus_plugin_session *handle);
    	void (* const end_session)(janus_plugin_session *handle);
    	...
    };
複製程式碼

其中relay_rtp,relay_rtcp,relay_data分別是用來傳送rtp,rtcp,自定義資料的。 janus的外掛都有唯一的識別符號,如echo test外掛的識別符號為:

    #define JANUS_ECHOTEST_PACKAGE			"janus.plugin.echotest"
複製程式碼

在前端js中需要指定需要與哪個外掛建立會話,在呼叫janus.js的janus.attach介面時指定:

    janus.attach({
    				plugin: "janus.plugin.echotest",
    				...
    			})
複製程式碼

總結

本文介紹了janus的環境搭建,janus的設計思想,和外掛的編寫方法。閱讀本文後,你能夠對janus的使用有基本的認識。具體的細節可以通過閱讀原始碼的方式繼續深入瞭解。

相關文章