WebRTC Gateway Janus入門:從配置到編寫插件

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

做者: 張鵬,資深音視頻工程師html

janus介紹

janus是Meetecho開發的一個WebRTC網關,janus的主要做用就是它能夠和你的內網設備和瀏覽器同時創建鏈接,並將瀏覽器發來的音視頻數據包如rtp/rtcp包,經過自定義插件轉發給你的內網設備,也能夠將你發給janus的音視頻數據包,加密後轉發給瀏覽器。前端

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

janus爲咱們完成了與瀏覽器創建會話的複雜邏輯,而且提供給咱們簡單的插件機制來處理音視頻數據。python

對於PeerConnection鏈接的創建過程,涉及到複雜的NAT穿透的ICE協議的實現,SDP的交換,DTLS-SRTP的握手和數據包加密發送,數據包接收後解密的複雜邏輯。 janus將咱們從與瀏覽器交互的PeerConnection創建的過程當中解脫出來,更專一於音視頻業務邏輯。git

janus的設計思想

janus基於插件思想,經過實現基礎架構,完成了與瀏覽器連接的創建過程。github

janus的插件主要完成一些必須的函數實現,如RTP/RTCP數據的接收。web

咱們經過實現本身的插件,來完成在將瀏覽器RTP數據轉發到內網服務器的業務邏輯。json

janus的用途

janus通常用於拓展已有視頻會議系統,提供對瀏覽器客戶端的支持。ubuntu

##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的使用有基本的認識。具體的細節能夠經過閱讀源碼的方式繼續深刻了解。

相關文章
相關標籤/搜索