写在前面
首先,这篇文章会偏长,涉及到的音视频知识点会比较多,很多地方我解释的可能不是很详细,如果看到专有名词名称不懂的,可以到文末加群联系我们。目前就我所知国内还没有将openvidu改造为springcloud模式的文章,我应该是第一个分享出来的.当然我会尽我所能的解释清楚,有异议的地方还欢迎大家指正.
技术选型:为什么要选择openvidu
openvidu是基于java写的一个音视频服务器的信令服务器,框架使用的是springboot,对于熟悉java的程序员来说无疑是一种福音。毕竟我调研过jitsi/openvidu/starrtc等开源的音视频框架.经过一两个月的比较选型,在对openvidu做了对流媒体负载均衡(点我跳转到openvidu+kms负载均衡),修改源代码,将springboot的openvidu集成到现有的springcloud里面后。最终选择了openvidu。下面简单列一下我所了解的三个音视频框架优缺点:
- jitsi
优点:
1. 应用比较广泛的音视频框架,部署上手比较容易.
2. 部署成功后可以不用知道什么是打洞服务器!为什么要打洞等webrtc原理,框架封装的特别好.
3. jvb视频桥原理非常强大,适合大流量的音视频,支持p2p
缺点:
1. 原始jitsi没有传统意义上的http接口.
2. 后期二次改造比较复杂,需要了解xmpp协议,需要会写lua脚本,需要维护jicofo/jvb等java后端模块。
3. 不适合自定义一些列接口。
4. 官方文档贼少,大部分是告诉你怎么部署.原理解释的不多。
- starrtc
优点:
中国人写的开源框架,上手比较容易,支持p2p,有官方qq群.
缺点:
音频噪音实在太大,接受不了,官方还在解决中,并且这个问题已经存在很久了...
- openvidu
优点:
1. openvidu的流媒体服务器是基于kurento实现的。
2. 不论是kurento还是openvidu,文档都特别详细,从kurento开始了解,会知道为什么需要打洞,什么是coturn,怎么部署,为什么看不到远程头像等特别详细,介绍知识点如数家珍.这里还是情不自禁留意下[kurento官网地址](https://doc-kurento.readthedocs.io/en/6.14.0/)和[openvidu官网地址](https://docs.openvidu.io/en/2.15.0/)。
3. openvidu2.15.0使用springboot2。里面添加了相关kurento的jar包,并且基础的openvidu与kms调用都在接口里面写好了.非常方便.
4. 带有webhook。可以监视到音视频里面每个房间的具体信息.
缺点:
1. 目前不支持p2p,两个人通话也会走流媒体服务器中转.
2. openvidu将session信息存储在jvm里面(使用的hashmap存的),如果不改造,上生产的适合只能单点部署.
3. kms流媒体压力会比较大.原生的只能取第一个kms流媒体服务器(这点我已经改造源码负载好了,如果和我一样改造了,就不算缺点了)
怎么改造流媒体服务器(kms)负载均衡部署
怎么改造流媒体服务器原因,具体流程都在这篇文章里面了.如果要上生产,还是建议改造一下.点我跳转
为什么要将openvidu部署在springcloud上
- 那么我们为什么需要部署在springcloud上呢?这得了解如果使用源码的docker部署,openvidu是什么结构?怎么部署起来的?
答: a. 怎么部署:其实如果熟读openvidu的官方文档,我们会很清楚的知道在docker-compose目录下面,执行:./openvidu start 就好了(当然,假设你已经安装好docker-compose且版本大于1.24 且安装jdk 版本大于1.8 且安装maven,且版本为3.6.1 (特别说明,我之前使用mvn 3.6.3是不行的)).
b. openvidu部署结构是什么样子的:我截个图
图中我圈起来的地方就是docker-compose执行的起点.这与我们在官网部署流程的 openvidu文件功能相同,我们只用执行下列命令,就可以启动一个音视频的后端了(已安装上面说的软件了):
./openvidu start
这个时候,我们docker ps 可以看到下列列表:
如果需要查看日志,我们可以自爱openvidu所在目录下执行下列命令:
docker-compose logs -f kms
docker-compose logs -f nginx
docker-compose logs -f coturn
docker-compose logs -f redis
docker-compose logs -f app
或者一口气查看所有日志:
docker-compose logs -f
到此,我画了一个图,目前如果我们音视频,前后端的交互是这样的:
可以看到,其实前后端的连接总共有3种方式:
1.http : 在加入房间之前,会调用http 的 /api/sessions,/api/token等接口获取相关信息
2.websocket: 客户端的动作都是使用websocket发送,比如加入房间(joinroom),退出房间等动作
3.webrtc: 客户端与后端流媒体服务器相互传输视频的适合使用.当然,公网环境必须部署coturn服务器打洞(为什么需要打洞,我前面有文章介绍).
是的,如果是单独的音视频项目,直接使用官方网站推荐的部署方式,我就觉得很优雅,但是很多时候,我们都是在自有的一套项目上集成openvidu音视频会议,比如我们使用的是springcloud,就想着把openvidu集成为微服务下面的一个服务.这就是我为什么要把他改造的根本原因.
openvidu-server 改造的代码部分:
(将openvidu挂在springcloud的nacos下部分我就不介绍了)
改造后多了一层网关转发,我们需要修改websocket的地址,在application-local文件下添加配置文件:
GETAWAY_WS_URL=wss://192.168.53.116:9000/openvidu-api
然后在openviduConfig里将其配置进去(具体配置逻辑和之前配置KMS_WEIGHT一样)
添加变量:
启动时初始化变量
gatewayWSURL = initGatewayURL();
public String initGatewayURL(){
String property = "GETAWAY_WS_URL";
return getValue(property);
}
最重要的地方,就是在获取token的时候,将我们配置的url给进去
然后docker-compose方面,我们不需要官方使用nginx的方式来部署了:
version: '3.1'
services:
# openvidu-server:
# image: openvidu/openvidu-server:2.15.0
# restart: on-failure
# network_mode: host
# entrypoint: ['/bin/bash', '-c', 'export COTURN_IP=`/usr/local/bin/discover_my_public_ip.sh`; /usr/local/bin/entrypoint.sh']
# volumes:
# - /var/run/docker.sock:/var/run/docker.sock
# - ${OPENVIDU_RECORDING_PATH}:${OPENVIDU_RECORDING_PATH}
# - ${OPENVIDU_RECORDING_CUSTOM_LAYOUT}:${OPENVIDU_RECORDING_CUSTOM_LAYOUT}
# - ${OPENVIDU_CDR_PATH}:${OPENVIDU_CDR_PATH}
# env_file:
# - .env
# environment:
# - SERVER_SSL_ENABLED=false
# - SERVER_PORT=9001
# - KMS_URIS=["ws://localhost:8888/kurento"]
# - KMS_WEIGHT=[1]
# - GETAWAY_WS_URL=wss://vidudrilling.zhimeiwulian.com/openvidu-api
# - COTURN_REDIS_IP=127.0.0.1
# - COTURN_REDIS_PASSWORD=${OPENVIDU_SECRET}
kms:
image: ${KMS_IMAGE:-kurento/kurento-media-server:6.14.0}
restart: always
network_mode: host
ulimits:
core: -1
volumes:
- /opt/openvidu/kms-crashes:/opt/openvidu/kms-crashes
- ${OPENVIDU_RECORDING_PATH}:${OPENVIDU_RECORDING_PATH}
environment:
- KMS_MIN_PORT=40000
- KMS_MAX_PORT=57000
- GST_DEBUG=${KMS_DEBUG_LEVEL:-}
redis:
image: openvidu/openvidu-redis:1.0.0
restart: always
network_mode: host
environment:
- REDIS_PASSWORD=JD123
coturn:
image: openvidu/openvidu-coturn:1.0.0
restart: on-failure
network_mode: host
environment:
- REDIS_IP=127.0.0.1
- TURN_LISTEN_PORT=3478
- DB_NAME=0
- DB_PASSWORD=JD123
- MIN_PORT=57001
- MAX_PORT=65535
# nginx:
# image: openvidu/openvidu-proxy:3.0.0
# restart: on-failure
# network_mode: host
# volumes:
# - ./certificates:/etc/letsencrypt
# - ./owncert:/owncert
# - ${OPENVIDU_RECORDING_CUSTOM_LAYOUT}:/opt/openvidu/custom-layout
# environment:
# - DOMAIN_OR_PUBLIC_IP=${DOMAIN_OR_PUBLIC_IP}
# - CERTIFICATE_TYPE=${CERTIFICATE_TYPE}
# - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
# - PROXY_HTTP_PORT=${HTTP_PORT:-}
# - PROXY_HTTPS_PORT=${HTTPS_PORT:-}
# - ALLOWED_ACCESS_TO_DASHBOARD=${ALLOWED_ACCESS_TO_DASHBOARD:-}
# - ALLOWED_ACCESS_TO_RESTAPI=${ALLOWED_ACCESS_TO_RESTAPI:-}
# - PROXY_MODE=CE
# - WITH_APP=true
gateway转发部分:
server:
port: 9000
spring:
application:
name: CRAWLER-GETAWAY
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
namespace:
group: GETAWAY_GROUP
file-extension: yml
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: wb-api
uri: lb://CRAWLER-WB
predicates:
- Path=/wb/**
filters:
- SwaggerHeaderFilter
- StripPrefix=1
- id: openvidu-api
uri: lb://CRAWLER-OPENVIDU
predicates:
- Path=/openvidu-api/**
filters:
- SwaggerHeaderFilter
- StripPrefix=1
客户端修改部分(以安卓为例):
public class CustomWebSocket extends AsyncTask implements WebSocketListener {
...
private String getWebSocketAddress(String openviduUrl) {
try {
URL url = new URL(openviduUrl);
return "wss://192.168.53.116:9000/openvidu-api/openvidu";
}
}
...
}
到此,就将openvidu集成在springcloud上了 . 可能在公网上部署的时候,还会看不到远端的视频,这是因为openvidu没有连接上打洞服务器,这个时候在配置文件里面加一个下面配置就好了
COTURN_IP 一定要填,不填看不到远方视频.因为找不到我们部署的打洞服务器
COTURN_IP=127.0.0.1
最后,app上访问的路径和效果如下图:
最后欢迎加入我们:
qq群:
openvidu钉钉群:
21919158
openvidu中文学习码云:
http://openvidu_cn.gitee.io/openvidu_docs_cn/docs/home/