wvp-pro对讲版本部署
前言
wvp-pro对讲版本是在wvp-pro项目上增加了国标28181对讲功能,wvp-pro对讲版本的部署,除了需要开启https功能,本质上和部署wvp-pro的部署没有任何区别。
我的本意是让大家参考wvp和zlmediakit的部署文档去部署wvp-pro-talk,奈何大部分人在部署的过程中还是会出现各种问题,故出此文档。
在和大家的接触过程中,发现每个公司的部署环境和部署思路不一样,我这里列出两种常用的部署方案,并且亲自验证过的方案如下:
- wvp + nginx(前后端分离) + docker部署zlmediakit
- wvp(前后端不分离) + 手动编译zlmediakit
1. 作者服务器环境
服务器:腾讯云 centos 7.6_1810
wvp-pro-talk运行环境(关于以下软件的版本自己把握就可以,不一定非得和我一样)
- redis 6.2.6
- mysql 5.7
- jdk(作者使用的jdk 1.8_212 建议使用最新的1.8版本,因为老的1.8版本在开启https后和tomcat有兼容问题,这个我遇到过,升级jdk后解决)
- maven 3.6(选装 一般都是开发环境打jar包后上传到部署环境,所以部署环境没必要安装maven)
- nodejs v10.24.1(选装 原因同上)
zlmediakit手动编译依赖环境(作者使用的版本)
- gcc 4.8.5
- cmake 3.21.0-rc3
- openssl 1.1.1k
- libsrtp >= 2.3.0
- ffmpeg 4.2.3 (选装)
2. 两个必要条件
2.1 https
浏览器安全机制,调用设备麦克风,本站必须得是https,非https没办法调用麦克风,两个方案:
- 自签名证书
自签名证书第一次访问会有浏览器告警,需要手动点击继续前往
zlmediakit目录下有个default.pem,我们如果不指定证书默认会加载这个证书
如果使用自签名证书,zlmediakit的ssl端口也需要在浏览器访问下,要不然视频出不来,因为wvp前端会有判断,如果本站是https那么取的视频播放地址也是安全的播放地址,但是zlmediakit的证书也是自签名,浏览器会拦截,所以需要我们在浏览器地址栏访问下zlmediakit的ssl端口,访问后出现告警画面,点击继续前往,再去播放视频,视频画面就会正常出现,如下错误示范(视频出不来就是没有信任zlmediakit的证书):
-
公网证书
我使用的是阿里云证书:
2.2 zlmediakit webrtc
语音数据流是通过zlmediakit的webrtc进行录制的,所以zlmediakit的webrtc功能必须开启才能保证国标对讲功能的可用,关于zlmediakit如何开启webrtc详见[ZlmediaKit部署](#3. ZlmediaKit部署),zlmediakit开启webrtc后会产生webrtc文件夹,如下:
3. ZlmediaKit部署
**注意:**手动编译zlmeidakit需要开启webrtc功能,开启webrtc功能需要安装openssl和libsrtp,docker部署zlmediakit默认开启了webrtc功能不用做特殊配置
3.1 手动编译zlmediakit
- 安装gcc
# 首先查看是否已经安装gcc,如果安装且版本>=4.8跳过此步骤
$ gcc -version
# 安装gcc
$ yum isntall gcc
$ yum -y install gcc-c++
- 安装cmake
$ yum -y install cmake
# 查看cmake 版本
$ cmake -version
- 安装openssl
# 服务器安装好后一版自带openssl,但是自带的openssl可能版本和zlmediakit所需的版本不匹配,此处推荐安装openssl 1.1.1K
#查看openssl版本
$ openssl version -a
# 安装openssl
$ wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
$ tar -xvzf openssl-1.1.1k.tar.gz
$ yum install -y zlib zlib-devel perl-CPAN
$ ./config shared --openssldir=/usr/local/openssl --prefix=/usr/local/openssl
$ make && make install
$ echo "/usr/local/lib64/" >> /etc/ld.so.conf
$ echo "/usr/local/openssl/lib" >> /etc/ld.so.conf
$ ldconfig
$ ln -s /usr/local/openssl/bin/openssl /usr/local/bin/openssl # 替换系统openssl,非必须
$ openssl version -a
- 安装libsrtp
$ wget https://codeload.github.com/cisco/libsrtp/tar.gz/refs/tags/v2.3.0
$ tar -xvzf libsrtp-2.3.0.tar.gz
$ cd libsrtp-2.3.0
$ ./configure --enable-openssl --with-openssl-dir=/usr/local/openssl
$ make -j8 && make install
#对于一些比较新的编译环境(如GCC 10+),编译 libsrtp-2.3.0 可能会存在问题,可以考虑切换到 2.5.0 版本,即
$ wget https://github.com/cisco/libsrtp/archive/refs/tags/v2.5.0.tar.gz
$ tar -xvzf libsrtp-2.5.0.tar.gz
$ cd libsrtp-2.5.0
$ ./configure --enable-openssl --with-openssl-dir=/usr/local/openssl
$ make -j8 && make install
- 下载zlm源码
git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit
cd ZLMediaKit
千万不要忘记执行这句命令
git submodule update --init
- 编译zlmediakit
$ mkdir build
$ cd build
# -DENABLE_WEBRTC=true 开启webrtc,必须开启
$ cmake .. -DENABLE_WEBRTC=true -DOPENSSL_ROOT_DIR=/usr/local/openssl -DOPENSSL_LIBRARIES=/usr/local/openssl/lib
$ cmake --build . --target MediaServer
# 最终输出
[ 96%] Built target test_rtcp_fci
[ 96%] Building CXX object tests/CMakeFiles/test_rtp.dir/test_rtp.cpp.o
[ 97%] Linking CXX executable ../../release/linux/Debug/test_rtp
[ 97%] Built target test_rtp
[ 97%] Building CXX object tests/CMakeFiles/test_wsServer.dir/test_wsServer.cpp.o
[ 97%] Linking CXX executable ../../release/linux/Debug/test_wsServer
[ 97%] Built target test_wsServer
[ 97%] Building CXX object tests/CMakeFiles/test_server.dir/test_server.cpp.o
[ 97%] Linking CXX executable ../../release/linux/Debug/test_server
[ 97%] Built target test_server
[ 98%] Built target jsoncpp
[ 98%] Linking CXX executable ../../release/linux/Debug/MediaServer
[100%] Built target MediaServer
- 运行zlmediakit
# -s 参数指定加载的ssl证书
./MediaServer -s xx.pem
3.2 docker部署zlmediakit
- 下载zlmediakit docker镜像
$ docker pull zlmediakit/zlmediakit:master
- 查看镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zlmediakit/zlmediakit master e461953e6ef1 3 days ago 597MB
nginx latest eb4a57159180 2 weeks ago 187MB
- 运行镜像(端口映射和目录挂载视自己情况而定)
docker run -d -p 1935:1935 -p 80:80 -p 554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp -p 446:446 -p 30000-30050:30000-30050 -p 30000-30050:30000-30050/udp --name zlmediakit --restart=always --env MODE=standalone -e TZ="Asia/Shanghai" -v /usr/local/docker/zlmediakit/media/bin:/opt/media/bin -v /usr/local/docker/zlmediakit/media/conf:/opt/media/conf zlmediakit/zlmediakit:master
-
docker部署可能出现的问题
docker做范围端口映射,如果端口范围太大可能会出现吃内存的情况,我一开始映射 的端口范围是30000-30500发现服务器内存撑不住,随后改成30000-30050,视硬件情况而定,但是如果开启多端口收流,最少需要开启的端口不能少于26个。
docker部署zlmediakit加载公网证书,因为我没有在启动容器命令上找到设置参数的地方,我是把我的证书名称改成default.pem,让zlmediakit自动加载,因为zlmediakit默认加载default.pem。
3.3 部署完成后zlmediakit config.ini必要的两点配置
-
修改语音数据第一推送格式
大多数设备接收的语音格式是g711a,这一步视设备侧支持的格式而定,zlmediakit默认是PCMU为第一格式,如果设备侧支持的是G711A格式,需要把PCMA调整到第一位,如果格式和设备侧不对应会出现杂音问题。
-
公网部署需要修改rtc 的externIP为公网ip,默认是置空的。
3.wvp-pro对讲版本部署
3.1 非前后端分离部署
关于 wvp运行环境依赖 redis mysql 以及数据库的初始化我就不再赘述,请自行安装操作
- 拉取代码
- 前端打包
# 1.进入web_src文件夹
npm install
npm run build
#打包后生成的文件会自动放到后端的resource/static目录下
- 后端配置(非前后端分离需要在配置文件中开启https,这是我的公网配置请参考)
spring:
# [可选]上传文件大小限制
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
# REDIS数据库配置
redis:
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
host: 127.0.0.1
# [必须修改] 端口号
port: 60001
# [可选] 数据库 DB
database: 0
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
password:
# [可选] 超时时间
timeout: 10000
# mysql数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:60002/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password:
druid:
initialSize: 10 # 连接池初始化连接数
maxActive: 200 # 连接池最大连接数
minIdle: 5 # 连接池最小空闲连接数
maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小
timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒
filters: stat,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j
useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000
#stat-view-servlet.url-pattern: /admin/druid/*
#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
server:
port: 18080
ssl:
# [可选] 是否开启HTTPS访问
enabled: true
# [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名
key-store: classpath:gbslink.top.pfx
# [可选] 证书密码
key-store-password: g0jr52ef
# [可选] 证书类型, 默认为jks,根据实际修改
key-store-type: PKCS12
# 作为28181服务器的配置
sip:
# [必须修改] 本机的IP
ip: 10.0.4.4
# [可选] 没有任何业务需求,仅仅是在前端展示的时候用
show-ip: 124.220.191.166
# [可选] 28181服务监听的端口
port: 15060
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
# 后两位为行业编码,定义参照附录D.3
# 3701020049标识山东济南历下区 信息行业接入
# [可选]
domain: 3402000000
# [可选]
id: 34020000002000000001
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
password: 12345678
#zlm 默认服务器配置
media:
id: your_server_id
# [必须修改] zlm服务器的内网IP
ip: 10.0.4.4
# 视频播放地址,如果有域名可以使用域名,没有域名使用ip
stream-ip: gbslink.top
# [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip
sdp-ip: 124.220.191.166
# [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip
hook-ip: 124.220.191.166
# [必须修改] zlm服务器的http.port
http-port: 80
# [可选] zlm服务器的hook.admin_params=secret
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
rtp:
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
enable: true
# [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
port-range: 30000,30500 # 端口范围
# [可选] 国标级联在此范围内选择端口发送媒体流,
send-port-range: 30000,30500 # 端口范围
# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
record-assist-port: 0
# [可选] 日志配置, 一般不需要改
logging:
config: classpath:logback-spring-local.xml
- 后端打包
mvn package
- 启动
上传至服务器
java -jar wvp-pro.jar
3.2 前后端分离部署使用nginx做代理
-
前端打包把生成的文件上传至nginx的html目录下
-
nginx配置
server { # 服务器端口使用443,开启ssl, 这里ssl就是上面安装的ssl模块 listen 443 ssl; # 域名,多个以空格分开 server_name gbslink.top www.gbslink.top; # ssl证书地址 ssl_certificate /etc/nginx/ssl/gbslink.top.pem; # pem文件的路径 ssl_certificate_key /etc/nginx/ssl/gbslink.top.key; # key文件的路径 # ssl验证相关配置 ssl_session_timeout 5m; #缓存有效期 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #加密算法 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #安全链接可选的加密协议 ssl_prefer_server_ciphers on; #使用服务器端的首选算法 location / { root /usr/share/nginx/html; index index.html index.htm; } location /api/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; add_header Access-Control-Allow-Methods *; add_header Access-Control-Allow-Origin $http_origin; proxy_pass http://124.220.191.166:18080; #公网地址,需要防火墙打开端口 } } # http请求重定向到https server { listen 80; #填写绑定证书的域名 server_name gbslink.top www.gbslink.top; #强制将http的URL重写成https rewrite ^(.*) https://$server_name$1 permanent; }
nginx中配置了https wvp后端中就不用启用https了,直接走nginx代理就可以
-
nginx重启
./nginx -s reload
-
后端打包
mvn package
-
启动
上传至服务器
java -jar xxx.jar
4. 防火墙需要打开的端口
wvp(以下端口视自己部署的服务情况而定)
前端 nginx 443 80
后端 18080
zlmediakit(以下端口是zl默认端口,自己如果修改了按照自己的来)
rtmp 1935/udp
rtsp 554/udp
收流端口默认:30000-30500/udp 30000-30500/tcp
webrtc 8000/udp 8000/tcp
http 80/tcp (和nginx冲突)
https 443/tcp (和nginx冲突)
5. 对讲入口
6. 联系作者
wx:17686791164
项目演示地址:https://www.gbslink.top