因为产品需要,选择Janus作为音视频通信服务器框架,在阿里云的ubuntu服务器上进行搭建测试。
1、环境
服务器:阿里云ECS
系统:ubuntu16.04.6 LTS,以root用户登录。
2、下载Janus源码
官网:git clone https://github.com/meetecho/janus-gateway.git
// 下载不下来,直接上网下载最新的TAG 0.11.1 版本,解压处理
// https://github.com/meetecho/janus-gateway/tags
查看readme文件:cat README.md (非常重要,不同的版本可能在配置和编译时有区别,一定要重点看所下载版本的readme文件)
我特别把这一个步骤放在第一,因为不同版本的janus,对依赖项的版本也不一样。
重点查看如下:
To install it, you'll need to satisfy the following dependencies:
* [Jansson](http://www.digip.org/jansson/)
* [libconfig](https://hyperrealm.github.io/libconfig/)
* [libnice](https://libnice.freedesktop.org/) (at least v0.1.16 suggested, master recommended)
* [OpenSSL](http://www.openssl.org/) (at least v1.0.1e)
* [libsrtp](https://github.com/cisco/libsrtp) (at least v2.x suggested)
* [usrsctp](https://github.com/sctplab/usrsctp) (only needed if you are interested in Data Channels)
* [libmicrohttpd](http://www.gnu.org/software/libmicrohttpd/) (at least v0.9.59; only needed if you are interested in REST support for the Janus API)
* [libwebsockets](https://libwebsockets.org/) (only needed if you are interested in WebSockets support for the Janus API)
* [cmake](http://www.cmake.org/) (only needed if you are interested in WebSockets and/or BoringSSL support, as they make use of it)
* [rabbitmq-c](https://github.com/alanxz/rabbitmq-c) (only needed if you are interested in RabbitMQ support for the Janus API or events)
* [paho.mqtt.c](https://eclipse.org/paho/clients/c) (only needed if you are interested in MQTT support for the Janus API or events)
* [nanomsg](https://nanomsg.org/) (only needed if you are interested in Nanomsg support for the Janus API)
* [libcurl](https://curl.haxx.se/libcurl/) (only needed if you are interested in the TURN REST API support)
以上特别注意查看版本要求。
3、安装依赖环境
下载最新的源代码需要git,若没有安装git可以使用下面命令进行安装:
sudo apt-get install git -y
安装lua库
sudo apt-get install liblua5.3-dev
编译运行 Janus Server 需要依赖较多的一些第三方库,而这些依赖库在 Ubuntu 下主要通过 aptitude 进行安装,首先通过安装 aptitude:
sudo apt-get install aptitude
还有一些编译的aptitude依赖库,相关安装命令如下:
sudo aptitude install libmicrohttpd-dev libjansson-dev libnice-dev
sudo aptitude install libssl-dev libsrtp-dev libsofia-sip-ua-dev libglib2.0-dev
sudo aptitude install libopus-dev libogg-dev libcurl4-openssl-dev pkg-config gengetopt libtool automake
大部分依赖是可以通过ubuntu默认的安装处理的,但有些版本不一致,需要重新安装。
libmicrohttpd-dev :在ubuntu16.04中默认为0.9.44,无法满足最低0.9.59的要求,如果不安装,将无法使用REST API支持。(http://www.gnu.org/software/libmicrohttpd/ 下载合适版本 https://ftp.gnu.org/gnu/libmicrohttpd/ ) 参考《ubunut下安装libmicrohttpd》
4、编译安装libsrtp
- 下载libsrtp
git clone https://github.com/cisco/libsrtp.git - ./configure && make && make install
- make runtest
如果在服务器上无法git clone下来,直接到github网站(https://github.com/cisco/libsrtp),download zip,然后传到服务器上编译。
测试通过后,可以看到提示:crypto test applications passed.
5、编译安装libwebsockets
依赖库安装:
sudo apt-get install cmake -y
sudo apt-get install openssl -y
sudo apt-get install libssl-dev -y
编译安装:
git clone https://github.com/warmcat/libwebsockets.git
// 下载下来编译有问题,下载tag中 libwebsockets-4.1.6.tar.gz 的版本,编译ok。
// https://github.com/warmcat/libwebsockets/tags 中包含。
cd libwebsockets
//这里注意下,这个build要在Ubuntu系统里,不能是windows共享目录,否则make会失败。
mkdir build && cd build
cmake ..
make
make install
//测试
cd bin
//服务端
./libwebsockets-test-server
netstat -ntlp
//客户端
./libwebsockets-test-client 127.0.0.1 --port=7681
测试ok。
6、编译安装usrsctp
官网:https://github.com/sctplab/usrsctp
git clone https://github.com/sctplab/usrsctp
cd usrsctp
./bootstrap
./configure --prefix=/usr --disable-programs --disable-inet --disable-inet6
make && sudo make install
装好以后,编译janus会默认启用data channel。
7、编译安装janus
生成配置文件
sh autogen.sh
./configure --prefix=/opt/janus
// /usr/lib/x86_64-linux-gnu/libgupnp-1.0.so.4: undefined reference to `uuid_unparse@UUID_1.0'
// error问题的解决参考:https://blog.csdn.net/u014734886/article/details/93029349
Compiler: gcc
libsrtp version: 2.x
SSL/crypto library: OpenSSL
DTLS set-timeout: not available
Mutex implementation: GMutex (native futex on Linux)
DataChannels support: no
Recordings post-processor: no
TURN REST API client: yes
Doxygen documentation: no
Transports:
REST (HTTP/HTTPS): yes
WebSockets: yes
RabbitMQ: no
MQTT: no
Unix Sockets: yes
Nanomsg: no
Plugins:
Echo Test: yes
Streaming: yes
Video Call: yes
SIP Gateway: yes
NoSIP (RTP Bridge): yes
Audio Bridge: yes
Video Room: yes
Voice Mail: yes
Record&Play: yes
Text Room: yes
Lua Interpreter: no
Duktape Interpreter: no
Event handlers:
Sample event handler: yes
WebSocket ev. handler: yes
RabbitMQ event handler:no
MQTT event handler: no
Nanomsg event handler: no
GELF event handler: yes
External loggers:
JSON file logger: no
JavaScript modules: no
第一次安装时发现:REST (HTTP/HTTPS): yes 为 no,使用enable-rest配置时出错,发现时libmicrohttpd的版本有问题。具体参见上面1的描述。
make
make install
拷贝配置文件
make configs
启动janus(暂还不带打洞功能)
/opt/janus/bin/janus --configs-folder=/opt/janus/etc/janus/
后台启动:
nohup /opt/janus/bin/janus --configs-folder=/opt/janus/etc/janus/ >> /var/log/janus.log 2>&1 &
查看进程:ps -ef|grep janus
查看相关端口:netstat -apn|grep janus
停止进程:直接kill即可:kill -9 xxx
启动 janus 后,可以用两种方法来验证,一个websocket,一个rest api。
其中8188是websocket,8088是http,8089是https。
运行demo
demo代码的位置:cd /opt/janus/share/janus/demos
在局域网内,可以将 echotest.js 中关于server地址的部分调整为:
server = "ws://192.168.xx.xxx:8188/janus";
这样就可以进行echotest测试,验证ok。
如果要使用rest方式,这也是janus的默认方式。
可以直接在本地用HBuilderX打开echotest.html,运行到浏览器,进行测试。
这样可以看到janus服务器端的日志输出。其他测试样例类似。
从测试的效果来看,局域网内websocket比rest方式效果要好一些。
如果要将代码用WEB服务器发布出来,则:
简单的方式:python -m SimpleHTTPServer 8080
访问时,出现错误: WebRTC error: getUserMedia not available
查找解决方案,发现新的浏览器版本(chrome,我测试firefox也是如此),都需要https的支持,才能响应音视频的请求。
在本地代码中直接访问阿里云上的janus http服务,报错:同源策略禁止读取位于 http://xxxx/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')
在 etc/apache2 目录下修改 apache2.conf:
<Directory /var/www/>
Options FollowSymLinks
AllowOverride None
Require all granted
Header set Access-Control-Allow-Origin *
</Directory>
重启apache,可能会出现报错:Invalid command 'Header'
需要在 apache2/mods-enabled 目录下:
ln -s ../mods-available/headers.load headers.load
然后重启apache,/usr/sbin/apachectl restart
CORS错误问题解决。
在继续用本地demo代码访问时,浏览器可以拉起摄像头,但远端echo的视频无法显示,查看服务器日志。
报错:ICE failed for component 1 in stream 1, but let's give it some time... (trickle pending, answer received, alert not set)
分析应该是STUN服务器的问题。后面处理。
8、搭建基于https的janus
生成ssl证书
cd ~
mkdir ssl
cd ssl
# Gen ssl certs:
openssl req -new -newkey rsa:4096 -nodes -keyout key.pem -out cert.csr
openssl x509 -req -sha256 -days 365 -in cert.csr -signkey key.pem -out cert.pem
chmod 600 cert.csr
chmod 600 cert.pem
chmod 600 key.pem
调整janus相关配置
主要修改 /opt/janus/etc/janus 目录下的三个配置文件。
janus.jcfg
janus.transport.http.jcfg
janus.transport.websockets.jcfg
在apache上调整配置
default-ssl.conf
调整完上述配置后,重启janus和apache,然后打开demo测试。
在局域网内,测试正常。
但部署到阿里云上后,用chrome和firefox浏览器来测试,发现问题。
HTTPS方式,报错:已拦截跨源请求:同源策略禁止读取位于 https://x.x.x.x:8089/janus 的远程资源。(原因:CORS 请求未能成功)
最终发现,必须要采用正式的SSL证书,并且采用域名,这样才可以。自签名的证书只能用于局域网。
测试链接:
https://xxx.xxxx.cn/janus_demos/echotest.html
9、STUN
目前启动janus会提示:
[WARN] Janus is deployed on a private address (172.31.166.26) but you didn't specify any STUN server!
Expect trouble if this is supposed to work over the internet and not just in a LAN...
这需要安装STUN Server。
采用coturn作为穿透服务器,具体可查看《coturn穿透服务器安装部署》
添加TURN Server后,Janus的相关配置如下:
nat: {
stun_server = "xxx.xxx.cn"
stun_port = 3478
nice_debug = false
nat_1_1_mapping = "47.xxx.xxx.xxx"
turn_server = "47.xxx.xxx.xxx"
turn_port = 3478
turn_type = "udp"
turn_user = "xxxx"
turn_pwd = "xxxx"
}
10、运维
1)启动、停止
启动:
# 直接启动
/opt/janus/bin/janus --configs-folder=/opt/janus/etc/janus/
# 后台启动
nohup /opt/janus/bin/janus --configs-folder=/opt/janus/etc/janus/ >> /var/log/janus.log 2>&1 &
查看进程和关闭:
# 进程
ps -ef|grep janus
# 端口
netstat -apn|grep janus
# 关闭
kill -9 (pid)
2)日志
如果后台启动,可以直接配置日志文件位置,然后使用 tail -f -n 100 xxxx 来进行实时展示。
3)测试链接
https://xxx.xxxx.cn/janus_demos/videocalltest.html
11、效果
使用官网样例中的echotest 完全没有问题,PC版浏览器和手机版浏览器都可以。
但使用videocall时,总是报错(在下文中有提到),但在上午早一点的时间,网速似乎好一些,测试又ok,PC端和手机浏览器端测试没问题。
PC端和Android端还没有进行测试,下一步处理。
12、存在的问题
1)[WARN] Data Channels support not compiled
已经安装了usrsctp,但在janus的启动运行时log提示没有编译。
检查 janus目录下的 config.log,发现 #define HAVE_SCTP 1 也是正常的。
通过 make clean,然后重新配置编译,问题解决。
2)VideoCall 测试时,提示错误
[janus.plugin.videocall-0x7f1e50003e30] WebRTC media is now available
[ERR] [dtls.c:janus_dtls_srtp_incoming_msg:923] [6228751724242325] Oops, error creating inbound SRTP session for component 1 in stream 1??
[ERR] [dtls.c:janus_dtls_srtp_incoming_msg:924] [6228751724242325] -- 1 (srtp_err_status_fail)
分析:
网上有建议可能需要采用2.2.0版本,我用的是2.4.0版本。
但编译完成2.2.0版本后,编译janus时报错:
/home/janus/janus-gateway-0.11.1/dtls.c:896: undefined reference to `srtp_crypto_policy_set_aes_gcm_256_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:897: undefined reference to `srtp_crypto_policy_set_aes_gcm_256_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:900: undefined reference to `srtp_crypto_policy_set_aes_gcm_128_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:901: undefined reference to `srtp_crypto_policy_set_aes_gcm_128_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:861: undefined reference to `srtp_crypto_policy_set_aes_gcm_256_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:862: undefined reference to `srtp_crypto_policy_set_aes_gcm_256_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:865: undefined reference to `srtp_crypto_policy_set_aes_gcm_128_16_auth'
/home/janus/janus-gateway-0.11.1/dtls.c:866: undefined reference to `srtp_crypto_policy_set_aes_gcm_128_16_auth'
/usr/local/lib/libsrtp2.so: undefined reference to `srtp_aes_expand_decryption_key'
/usr/local/lib/libsrtp2.so: undefined reference to `srtp_aes_decrypt'
collect2: error: ld returned 1 exit status
分析:
应该是系统中有两个版本的libsrtp,或者版本就是有问题。
后来通过 find -name libsrtp*.* 查找相关系统文件信息,完全删除后,重新用 2.4 版本编译,ok。
3)使用videocall时,经常报错:
ICE failed for component 1 in stream 1, but let's give it some time... (trickle pending, answer received, alert not set)
在PC端浏览器中也看到错误:
Got error on data channel: RTCErrorEvent {isTrusted: true, error: RTCError: Transport channel closed, type: "error", target: RTCDataChannel, currentTarget: RTCDataChannel, …}
目前还无法确认原有,因为有时候早上网速好一点时,测试又完全ok。
参考链接:
https://blog.csdn.net/newchenxf/article/details/110451532
https://blog.csdn.net/passionkk/article/details/97368352
https://blog.csdn.net/cgs1999/article/details/89881401
https://blog.csdn.net/cgs1999/article/details/89881733
HTTPS
https://blog.csdn.net/cgs1999/article/details/89881733
TURN
https://blog.csdn.net/cgs1999/article/details/89882164
janus网络穿透失败解决方案
https://blog.csdn.net/weixin_44259356/article/details/103594808