WVP+ZLMediaKit流媒体搭建并实现摄像头GB28181推流播放

一、介绍

概述

  • WVP-PRO基于GB/T 28181-2016标准实现的流媒体平台,依托优秀的开源流媒体服务ZLMediaKit,提供完善丰富的功能。
  • GB/T 28181-2016 中文标准名称是《公共安全视频监控联网系统信息传输、交换、控制技术要求》是监控领域的国家标准。大量应用于政府视频平台。
  • 通过28181协议你可以将IPC摄像头接入平台,可以观看也可以使用28181/rtsp/rtmp/flv等协议将视频流分发到其他平台。

特性

  • 实现标准的28181信令,兼容常见的品牌设备,比如海康、大华、宇视等品牌的IPC、NVR以及平台。
  • 支持将国标设备级联到其他国标平台,也支持将不支持国标的设备的图像或者直播推送到其他国标平台
  • 前端完善,自带完整前端页面,无需二次开发可直接部署使用。
  • 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。
  • 支持多流媒体节点负载均衡。

应用场景 :

  • 支持浏览器无插件播放摄像头视频。
  • 支持摄像机、平台、NVR等设备接入。
  • 支持国标级联。 支持rtsp/rtmp等视频流转发到国标平台。
  • 支持rtsp/rtmp等推流转发到国标平台。

二、所需服务

1 服务介绍

服务作用是否必须
WVP-PRO 实现国标28181的信令以及视频平台相关的功能
ZLMediaKit 为WVP-PRO提供国标28181的媒体部分的实现,以及各种视频流格式的分发支持
wvp-pro-assist wvp的辅助录像程序,也可单独跟zlm一起使用,提供录像控制,录像合并下载接口 否(不安装只是影响云端录像功能和国标录像下载)

2 安装依赖

依赖版本用途开发环境需要生产环境需要
jdk >=1.8 运行与编译java代码
maven >=3.3 管理java代码依赖
git   下载/更新/提交代码
nodejs   编译于运行前端文件
npm   管理前端文件依赖

三、服务部署

所以服务部署均在centos7环境

3.1部署准备

步骤1:gcc安装

yum remove gcc
yum -y install bzip2
yum install gcc-c++

 

# 如果下载慢 可以浏览器输入地址下载
curl https://ftp.gnu.org/gnu/gcc/gcc-5.4.0/gcc-5.4.0.tar.bz2 -O
# j对应bz2编码 J对应gz编码
tar xvfj gcc-5.4.0.tar.bz2
yum install gmp-devel mpfr-devel libmpc-devel
mkdir gcc-5.4.0-build
cd gcc-5.4.0-build
../gcc-5.4.0/configure --enable-languages=c,c++ --disable-multilib
make -j$(nproc) && make install # note: nproc is the number of threads (e.g.2or 4 or 8 )

步骤2:cmake安装

删除旧版本cmake
yum remove cmake -y

安装gcc等必备程序包(已安装则略过此步)上面已安装gc yum install
-y gcc gcc-c++ make automake 安装wget (已安装则略过此步) yum install -y wget 获取CMake源码包 wget https://github.com/Kitware/CMake/releases/download/v3.20.5/cmake-3.20.5.tar.gz 解压CMake源码包 tar -zxvf cmake-3.20.5.tar.gz 进入目录 cd cmake-3.20.5 编译安装 ./bootstrap && make -j4 && sudo make install

查看cmake版本
cmake --version

version `GLIBCXX_3.4.20‘ not found 解决方法

su root
cd /usr/local/lib64
# 下载最新版本的libstdc.so_.6.0.26
sudo wget http://www.vuln.cn/wp-content/uploads/2019/08/libstdc.so_.6.0.26.zip
unzip libstdc.so_.6.0.26.zip
# 将下载的最新版本拷贝到 /usr/lib64
cp libstdc++.so.6.0.26 /usr/lib64
cd  /usr/lib64
# 查看 /usr/lib64下libstdc++.so.6链接的版本
ls -l | grep libstdc++
libstdc++.so.6 ->libstdc++.so.6.0.19
# 删除/usr/lib64原来的软连接libstdc++.so.6,删除之前先备份一份
sudo rm libstdc++.so.6
# 链接新的版本
sudo ln -s libstdc++.so.6.0.26 libstdc++.so.6
# 查看新版本,成功
strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
...
GLIBCXX_3.4.18
GLIBCXX_3.4.19
GLIBCXX_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBCXX_3.4.25
GLIBCXX_3.4.26
GLIBCXX_DEBUG_MESSAGE_LENGTH

步骤3:安装ffmpeg

wget http://www.ffmpeg.org/releases/ffmpeg-3.1.tar.gz
tar -zxvf ffmpeg-3.1.tar.gz

cd ffmpeg-3.1
./configure --prefix=/usr/local/ffmpeg
make && make install

vi /etc/profile
在最后PATH添加环境变量:
export PATH=$PATH:/usr/local/ffmpeg/bin
保存退出
查看是否生效
source /ect/profile  设置生效
#查看版本
ffmpeg -version

步骤4:openssl 安装 (openssl版本要求1.1以上)

1、yum 安装
yum install openssl
2、编译安装
$ 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

步骤5:安装 yasm

wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar -zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure
make && make install

https://codeload.github.com/cisco/libsrtp/tar.gz/refs/tags/v2.3.0

步骤6:libsrtp安装

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

 

3.2ZLMediaKit部署

3.2.1参考资料

https://gitee.com/xia-chu/ZLMediaKit

https://github.com/ZLMediaKit/ZLMediaKit/wiki/

3.2.2获取代码

##如果没安装git 那么安装
yum install -y git

#2.国内用户推荐从同步镜像网站gitee下载 
git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit
cd ZLMediaKit
#千万不要忘记执行这句命令
git submodule update --init
 
#3.国内用户推荐从同步镜像网站gitee下载 
git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit
cd ZLMediaKit
#千万不要忘记执行这句命令
git submodule update --init

3.2.3构建和编译项目

zlm不启用webrtc编译指南:

cd ZLMediaKit
mkdir build
cd build
#macOS下可能需要这样指定openss路径:
#cmake .. -DOPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2j/
cmake ..
make -j4

zlm启用webrtc编译指南:

$ mkdir build
$ cd build
$ 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

3.2.4修改配置文件

1)由于webrtc协议需要告知播放器服务器所在ip,如果该ip对播放器不可见,会导致webrtc无法联通。
请修改配置文件中rtc.externIP为播放器可见ip,如果不设置该配置项,zlmediakit将获取网卡ip(一般是内网ip),
那么将无法跨域nat使用webrtc。
[rtc]
#rtc播放推流、播放超时时间
timeoutSec=15
#本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip
externIP=
#rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据,
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
#需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
port=8000
#设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
rembBitRate=10000002)config.ini 配置文件
 注意,如果用不到hook,不要开启。开启后,所有的推拉流都会进行鉴权。
[hook]
#是否启用hook事件,启用后,推拉流都将进行鉴权
#将hook中的该值修改为0 这样推流时不用鉴权,如需鉴权请自行开启
enable=0

(3)与WVP-PRO对接配置
  [general]
   mediaServerId=12345678 ##后面和WVP-PRO对接
  [api]
  secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc ##后面和WVP-PRO对接:

配置说明:

[api]
#是否调试http api,启用调试后,会打印每次http请求的内容和回复
apiDebug=1
#默认截图图片,在启动FFmpeg截图后但是截图还未生成时,可以返回默认的预设图片
defaultSnap=./www/logo.png
#一些比较敏感的http api在访问时需要提供secret,否则无权限调用
#如果是通过127.0.0.1访问,那么可以不提供secret
secret=JvVotkdN01y4qZHlrJsdq4gD7n9rK6wV
#截图保存路径根目录,截图通过http api(/index/api/getSnap)生成和获取
snapRoot=./www/snap/
 
[cluster]
#设置源站拉流url模板, 格式跟printf类似,第一个%s指定app,第二个%s指定stream_id,
#开启集群模式后,on_stream_not_found和on_stream_none_reader hook将无效.
#溯源模式支持以下类型:
#rtmp方式: rtmp://127.0.0.1:1935/%s/%s
#rtsp方式: rtsp://127.0.0.1:554/%s/%s
#hls方式: http://127.0.0.1:80/%s/%s/hls.m3u8
#http-ts方式: http://127.0.0.1:80/%s/%s.live.ts
#支持多个源站,不同源站通过分号(;)分隔
origin_url=
#溯源失败尝试次数,-1时永久尝试
retry_count=3
#溯源总超时时长,单位秒,float型;假如源站有3个,那么单次溯源超时时间为timeout_sec除以3
#单次溯源超时时间不要超过general.maxStreamWaitMS配置
timeout_sec=15
 
[ffmpeg]
#FFmpeg可执行程序路径,支持相对路径/绝对路径
bin=/usr/bin/ffmpeg
#FFmpeg拉流再推流的命令模板,通过该模板可以设置再编码的一些参数
cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
#FFmpeg日志的路径,如果置空则不生成FFmpeg日志
#可以为相对(相对于本可执行程序目录)或绝对路径
log=./ffmpeg/ffmpeg.log
# 自动重启的时间(秒), 默认为0, 也就是不自动重启. 主要是为了避免长时间ffmpeg拉流导致的不同步现象
restart_sec=0
#FFmpeg生成截图的命令,可以通过修改该配置改变截图分辨率或质量
snap=%s -i %s -y -f mjpeg -frames:v 1 %s
 
[general]
check_nvidia_dev=1
#是否启用虚拟主机
enableVhost=0
enable_ffmpeg_log=0
#播放器或推流器在断开后会触发hook.on_flow_report事件(使用多少流量事件),
#flowThreshold参数控制触发hook.on_flow_report事件阈值,使用流量超过该阈值后才触发,单位KB
flowThreshold=1024
#播放最多等待时间,单位毫秒
#播放在播放某个流时,如果该流不存在,最多让播放器等待maxStreamWaitMS毫秒
#如果在这个时间内,该流注册成功,那么会立即返回播放器播放成功
#否则返回播放器未找到该流,该机制的目的是可以先播放再推流
maxStreamWaitMS=15000
#服务器唯一id,用于触发hook时区别是哪台服务器
mediaServerId=nms1
#合并写缓存大小(单位毫秒),合并写指服务器缓存一定的数据后才会一次性写入socket,这样能提高性能,但是会提高延时
#开启后会同时关闭TCP_NODELAY并开启MSG_MORE
mergeWriteMS=0
#拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始,
#如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写)
resetWhenRePlay=1
#某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒
#在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流
streamNoneReaderDelayMS=20000
#如果track未就绪,我们先缓存帧数据,但是有最大个数限制,防止内存溢出
unready_frame_cache=100
#如果流只有单Track,最多等待若干毫秒,超时后未收到其他Track的数据,则认为是单Track
#如果协议元数据有声明特定track数,那么无此等待时间
wait_add_track_ms=3000
#最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track
wait_track_ready_ms=10000
 
[hls]
#是否广播 hls切片(ts/fmp4)完成通知(on_record_ts)
broadcastRecordTs=0
#直播hls文件删除延时,单位秒
deleteDelaySec=10
#hls写文件的buf大小,调整参数可以提高文件io性能
fileBufSize=65536
#hls最大切片时间
segDur=2
#是否保留hls文件,此功能部分等效于segNum=0的情况
#不同的是这个保留不会在m3u8文件中体现
#0为不保留,不起作用
#1为保留,则不删除hls文件,如果开启此功能,注意磁盘大小,或者定期手动清理hls文件
segKeep=0
#m3u8索引中,hls保留切片个数(实际保留切片个数大2~3个)
#如果设置为0,则不删除切片,而是保存为点播
segNum=3
#HLS切片从m3u8文件中移除后,继续保留在磁盘上的个数
segRetain=5
 
[hook]
#keepalive hook触发间隔,单位秒,float类型
alive_interval=10.0
#是否启用hook事件,启用后,推拉流都将进行鉴权
enable=0
#播放器或推流器使用流量事件,置空则关闭
on_flow_report=https://127.0.0.1/index/hook/on_flow_report
#访问http文件鉴权事件,置空则关闭鉴权
on_http_access=https://127.0.0.1/index/hook/on_http_access
#播放鉴权事件,置空则关闭鉴权
on_play=https://127.0.0.1/index/hook/on_play
#推流鉴权事件,置空则关闭鉴权
on_publish=https://127.0.0.1/index/hook/on_publish
#录制mp4切片完成事件
on_record_mp4=https://127.0.0.1/index/hook/on_record_mp4
# 录制 hls ts(或fmp4) 切片完成事件
on_record_ts=https://127.0.0.1/index/hook/on_record_ts
#rtp server 超时未收到数据
on_rtp_server_timeout=https://127.0.0.1/index/hook/on_rtp_server_timeout
#rtsp播放鉴权事件,此事件中比对rtsp的用户名密码
on_rtsp_auth=https://127.0.0.1/index/hook/on_rtsp_auth
#rtsp播放是否开启专属鉴权事件,置空则关闭rtsp鉴权。rtsp播放鉴权还支持url方式鉴权
#建议开发者统一采用url参数方式鉴权,rtsp用户名密码鉴权一般在设备上用的比较多
#开启rtsp专属鉴权后,将不再触发on_play鉴权事件
on_rtsp_realm=https://127.0.0.1/index/hook/on_rtsp_realm
#发送rtp(startSendRtp)被动关闭时回调
on_send_rtp_stopped=https://127.0.0.1/index/hook/on_send_rtp_stopped
#服务器退出报告,当服务器正常退出时触发
on_server_exited=https://127.0.0.1/index/hook/on_server_exited
#server保活上报
on_server_keepalive=https://127.0.0.1/index/hook/on_server_keepalive
#服务器启动报告,可以用于服务器的崩溃重启事件监听
on_server_started=https://127.0.0.1/index/hook/on_server_started
#远程telnet调试鉴权事件
on_shell_login=https://127.0.0.1/index/hook/on_shell_login
#直播流注册或注销事件
on_stream_changed=https://127.0.0.1/index/hook/on_stream_changed
#无人观看流事件,通过该事件,可以选择是否关闭无人观看的流。配合general.streamNoneReaderDelayMS选项一起使用
on_stream_none_reader=https://127.0.0.1/index/hook/on_stream_none_reader
#播放时,未找到流事件,通过配合hook.on_stream_none_reader事件可以完成按需拉流
on_stream_not_found=https://127.0.0.1/index/hook/on_stream_not_found
#hook通知失败重试次数,正整数。为0不重试,1时重试一次,以此类推
retry=1
#hook通知失败重试延时,单位秒,float型
retry_delay=3.0
stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4
#hook api最大等待回复时间,单位秒
timeoutSec=10
 
[http]
#默认允许所有跨域请求
allow_cross_domains=1
allow_ip_range=127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255
#http服务器字符编码,windows上默认gb2312
charSet=utf-8
#是否显示文件夹菜单,开启后可以浏览文件夹
dirMenu=1
#禁止后缀的文件使用mmap缓存,使用“,”隔开
#例如赋值为 .mp4,.flv
#那么访问后缀为.mp4与.flv 的文件不缓存
forbidCacheSuffix=
#可以把http代理前真实客户端ip放在http头中
#切勿暴露此key,否则可能导致伪造客户端ip
forwarded_ip_header=
#http链接超时时间
keepAliveSecond=30
#http请求体最大字节数,如果post的body太大,则不适合缓存body在内存
maxReqSize=40960
#404网页内容,用户可以自定义404网页
notFound=
#http服务器监听端口
port=80
#http文件服务器根目录
#可以为相对(相对于本可执行程序目录)或绝对路径
rootPath=./www
#http文件服务器读文件缓存大小,单位BYTE,调整该参数可以优化文件io性能
sendBufSize=65536
#https服务器监听端口
sslport=443
#虚拟目录, 虚拟目录名和文件路径使用","隔开,多个配置路径间用";"隔开
#例如赋值为 app_a,/path/to/a;app_b,/path/to/b 那么
#访问 http://127.0.0.1/app_a/file_a 对应的文件路径为 /path/to/a/file_a
#访问 http://127.0.0.1/app_b/file_b 对应的文件路径为 /path/to/b/file_b
#访问其他http路径,对应的文件路径还是在rootPath内
virtualPath=
 
[multicast]
#rtp组播截止组播ip地址
addrMax=239.255.255.255
#rtp组播起始组播ip地址
addrMin=239.0.0.0
#组播udp ttl
udpTTL=64
 
###### 以下是按需转协议的开关,在测试接收推流性能时,请把下面开关置1
###### 如果某种协议你用不到,你可以把以下开关置1以便节省资源(但是还是可以播放,只是第一个播放者体验稍微差点)
###### 如果某种协议你想获取最好的用户体验,请置0(第一个播放者可以秒开,且不花屏)
#转协议相关开关;如果addStreamProxy api和on_publish hook回复未指定转协议参数,则采用这些配置项
[protocol]
#添加acc静音音频,在关闭音频时,此开关无效
add_mute_audio=1
#无人观看时,是否直接关闭(而不是通过on_none_reader hook返回close)
#此配置置1时,此流如果无人观看,将不触发on_none_reader hook回调,而是将直接关闭流
auto_close=0
#推流断开后可以在超时时间内重新连接上继续推流,这样播放器会接着播放。
#置0关闭此特性(推流断开会导致立即断开播放器)
#此参数不应大于播放器超时时间;单位毫秒
continue_push_ms=15000
#转协议是否开启音频
enable_audio=1
#是否开启转换为http-fmp4/ws-fmp4
enable_fmp4=1
#是否开启转换为hls(mpegts)
enable_hls=1
#是否开启转换为hls(fmp4)
enable_hls_fmp4=0
#是否开启MP4录制
enable_mp4=0
#是否开启转换为rtmp/flv
enable_rtmp=1
#是否开启转换为rtsp/webrtc
enable_rtsp=1
#是否开启转换为http-ts/ws-ts
enable_ts=1
#http[s]-fmp4、ws[s]-fmp4协议是否按需生成
fmp4_demand=0
#hls协议是否按需生成,如果hls.segNum配置为0(意味着hls录制),那么hls将一直生成(不管此开关)
hls_demand=0
#hls录制保存路径
hls_save_path=./www
#转协议时,是否开启帧级时间戳覆盖
# 0:采用源视频流绝对时间戳,不做任何改变
# 1:采用zlmediakit接收数据时的系统时间戳(有平滑处理)
# 2:采用源视频流时间戳相对时间戳(增长量),有做时间戳跳跃和回退矫正
modify_stamp=2
#是否将mp4录制当做观看者
mp4_as_player=0
#mp4切片大小,单位秒
mp4_max_second=3600
#mp4录制保存路径
mp4_save_path=./www
#rtmp[s]、http[s]-flv、ws[s]-flv协议是否按需生成
rtmp_demand=0
#rtsp[s]协议是否按需生成
rtsp_demand=0
#http[s]-ts协议是否按需生成
ts_demand=0
 
[record]
#mp4录制或mp4点播的应用名,通过限制应用名,可以防止随意点播
#点播的文件必须放置在此文件夹下
appName=record
#mp4录制完成后是否进行二次关键帧索引写入头部
fastStart=0
#mp4录制写文件缓存,单位BYTE,调整参数可以提高文件io性能
fileBufSize=65536
#MP4点播(rtsp/rtmp/http-flv/ws-flv)是否循环播放文件
fileRepeat=0
#mp4点播每次流化数据量,单位毫秒,
#减少该值可以让点播数据发送量更平滑,增大该值则更节省cpu资源
sampleMS=500
 
[rtc]
#本机对rtc客户端的可见ip,作为服务器时一般为公网ip,可有多个,用','分开,当置空时,会自动获取网卡ip
#同时支持环境变量,以$开头,如"$EXTERN_IP";
externIP=
#rtc udp服务器监听端口号,所有rtc客户端将通过该端口传输stun/dtls/srtp/srtcp数据,
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
#需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
port=8000
#rtc支持的音频codec类型,在前面的优先级更高
#以下范例为所有支持的音频codec
preferredCodecA=PCMU,PCMA,opus,mpeg4-generic
#rtc支持的视频codec类型,在前面的优先级更高
#以下范例为所有支持的视频codec
preferredCodecV=H264,H265,AV1,VP9,VP8
#设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
#目前已经实现twcc自动调整码率,关闭remb根据真实网络状况调整码率
rembBitRate=0
#rtc tcp服务器监听端口号,在udp 不通的情况下,会使用tcp传输数据
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
#需要注意的是,如果服务器在nat内,需要做端口映射时,必须确保外网映射端口跟该端口一致
tcpPort=8000
#rtc播放推流、播放超时时间
timeoutSec=15
 
[rtmp]
#rtmp必须在此时间内完成握手,否则服务器会断开链接,单位秒
handshakeSecond=15
#rtmp超时时间,如果该时间内未收到客户端的数据,
#或者tcp发送缓存超过这个时间,则会断开连接,单位秒
keepAliveSecond=15
#rtmp服务器监听端口
port=1935
#rtmps服务器监听地址
sslport=0
 
[rtp]
#音频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
#加大该值会明显增加直播延时
audioMtuSize=600
# H264 rtp打包模式是否采用stap-a模式(为了在老版本浏览器上兼容webrtc)还是采用Single NAL unit packet per H.264 模式
# 有些老的rtsp设备不支持stap-a rtp,设置此配置为0可提高兼容性
h264_stap_a=1
# rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏
lowLatency=0
#rtp包最大长度限制,单位KB,主要用于识别TCP上下文破坏时,获取到错误的rtp
rtpMaxSize=10
#视频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
videoMtuSize=1400
 
[rtp_proxy]
#导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出
dumpDir=
#RtpSender相关功能是否提前开启gop缓存优化级联秒开体验,默认开启
#如果不调用startSendRtp相关接口,可以置0节省内存
gop_cache=1
#rtp h264 负载的pt
h264_pt=98
#rtp h265 负载的pt
h265_pt=99
#rtp opus 负载的pt
opus_pt=100
#udp和tcp代理服务器,支持rtp(必须是ts或ps类型)代理
port=10000
#随机端口范围,最少确保36个端口
#该范围同时限制rtsp服务器udp端口范围
port_range=30001-35000
#rtp ps 负载的pt
ps_pt=96
#rtp超时时间,单位秒
timeoutSec=15
 
[rtsp]
#rtsp专有鉴权方式是采用base64还是md5方式
authBasic=0
#rtsp拉流、推流代理是否是直接代理模式
#直接代理后支持任意编码格式,但是会导致GOP缓存无法定位到I帧,可能会导致开播花屏
#并且如果是tcp方式拉流,如果rtp大于mtu会导致无法使用udp方式代理
#假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
#如果你是rtsp推拉流,但是webrtc播放,也建议关闭直接代理模式,
#因为直接代理时,rtp中可能没有sps pps,会导致webrtc无法播放; 另外webrtc也不支持Single NAL Unit Packets类型rtp
#默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
directProxy=1
#rtsp必须在此时间内完成握手,否则服务器会断开链接,单位秒
handshakeSecond=15
#rtsp超时时间,如果该时间内未收到客户端的数据,
#或者tcp发送缓存超过这个时间,则会断开连接,单位秒
keepAliveSecond=15
#rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟
lowLatency=0
#rtsp服务器监听地址
port=8554
#强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制)
#当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupported transport
#迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC
rtpTransportType=-1
#rtsps服务器监听地址
sslport=0
 
[shell]
#调试telnet服务器接受最大bufffer大小
maxReqSize=1024
#调试telnet服务器监听端口
port=0
 
[srt]
#srt 协议中延迟缓存的估算参数,在握手阶段估算rtt ,然后latencyMul*rtt 为最大缓存时长,此参数越大,表示等待重传的时长就越大
latencyMul=4
#包缓存的大小
pktBufSize=8192
#srt udp服务器监听端口号,所有srt客户端将通过该端口传输srt数据,
#该端口是多线程的,同时支持客户端网络切换导致的连接迁移
port=9000
#srt播放推流、播放超时时间,单位秒
timeoutSec=5
 

3.2.5运行

cd ZLMediaKit/release/linux/Debug
#通过-h可以了解启动参数
./MediaServer -h
#以守护进程模式启动
./MediaServer -d &
#以自定义配置文件启动
./MediaServer -c 配置文件具体地址
(nohup ./MediaServer -c 配置文件具体地址 &)

测试webrtc:

地址为 http://192.168.0.212:8080/webrtc/ 。8080为config.ini文件中http配置的port。

3.3WVP-PRO部署

项目运行依赖redis、jdk1.8,打包依赖git、maven、nodejs、npm。

https://doc.wvp-pro.cn/#/

https://blog.itpub.net/70013909/viewspace-2902384/

3.3.1安装准备

安装mysql以及redis此处忽略

JDK部署
[root@localhost ~]# tar zxvf jdk-8u121-linux-x64.tar.gz
[root@localhost ~]# mv jdk1.8.0_121/ /usr/local/jdk
[root@localhost ~]# vim /etc/profile
##末尾添加
export JAVA_HOME=/usr/local/jdk 
export CLASSPATH=$:CLASSPATH:$JAVA_HOME/lib/ 
export PATH=$PATH:$JAVA_HOME/bin

[root@localhost ~]# source /etc/profile
[root@localhost ~]# java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
Maven部署

历史版本https://archive.apache.org/dist/maven/maven-3/3.5.0/source/

[root@localhost ~]# tar zxvf apache-maven-3.5.0-bin.tar.gz
[root@localhost ~]# mv apache-maven-3.5.0 /usr/local/maven
[root@localhost ~]# vim /etc/profile
##末尾添加
export MAVEN_HOME=/usr/local/maven 
export PATH=$MAVEN_HOME/bin:$PATH

[root@localhost ~]# source /etc/profile
[root@localhost ~]# mvn -version
Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T03:39:06+08:00)
Maven home: /usr/local/maven
编译WVP-PRO
#安装依赖
yum install -y java-1.8.0-openjdk.x86_64 git nodejs npm
## 下载源码
#从gitee克隆
git clone https://gitee.com/pan648540858/wvp-GB28181-pro.git
#从github克隆
git clone https://github.com/648540858/wvp-GB28181-pro.git
 
[root@localhost ~]# cd /usr/local
[root@localhost local]# git clone https://gitee.com/pan648540858/wvp-GB28181-pro.git

## 编译静态页面 [root@localhost ~]# cd /usr/local/wvp-GB28181-pro/web_src/ [root@localhost web_src]# npm --registry=https://registry.npm.taobao.org install [root@localhost web_src]# npm run build
## 打包项目, 生成可执行jar [root@localhost web_src]# cd .. [root@localhost wvp
-GB28181-pro]# mvn package ## 编译完成后在target目录下出现wvp-pro-x.x-xxxxxxxx.jar

初始化数据库:

## 导入MySQL文件
[root@localhost ~]# cd /usr/local/wvp-GB28181-pro/sql
[root@localhost sql]# mysql -uroot -p123456
MariaDB [(none)]> create database wvp;
MariaDB [(none)]> use wvp;
MariaDB [(none)]> source mysql.sql   ## 可能会出现字节错误  将mysql.sql里面的255字节修改小点

配置文件修改:

[root@localhost wvp-GB28181-pro]# mv src/main/resources/application-dev.yml  target/application.yml 
[root@localhost wvp-GB28181-pro]# vim target/application.yml
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: 6379
        # [可选] 数据库 DB
        database: 6
        # [可选] 访问密码,若你的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:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
        username: root
        password: 123456
        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,wall,slf4j             # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j, 防御sql注入的filter:wall
            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
# 作为28181服务器的配置
sip:
    # [必须修改] 本机的IP
    ip: 192.168.1.13
    # [可选] 28181服务监听的端口
    port: 5060
    # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
    # 后两位为行业编码,定义参照附录D.3
    # 3701020049标识山东济南历下区 信息行业接入
    # [可选]
    domain: 4401020049
    # [可选]
    id: 44010200492000000001
    # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
    password: admin123
#zlm 默认服务器配置
media:
    id: 12345678    ##ZLMediaKit配置的ID
    # [必须修改] zlm服务器的内网IP
    ip: 192.168.1.13
    # [必须修改] 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: 18081
# [可选] 日志配置, 一般不需要改
logging:
    config: classpath:logback-spring-local.xml
# 版本信息, 不需修改
version:
    version: "@project.version@"
    description: "@project.description@"
    artifact-id: "@project.artifactId@"

启动和访问服务:

## 启动WVP
[root@localhost wvp-GB28181-pro]#  cd target
[root@localhost target]#  java -jar wvp-pro-2.3.1-06151618.jar

  #start.sh 命令
  nohup java -jar wvp-pro-2.3.1-06151618.jar --spring.config.location=application-dev.yml > log.out 2>&1 &

## 访问管理页面
http://192.168.1.13:18080
默认用户名:admin, 密码:admin
点击控制台--》媒体服务器配置--》有相关信息即可

自启动脚本

[root@localhost target]# cat wvp-pro.sh 
#!/bin/sh
##
if [ -f /etc/init.d/functions ]; then
    . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ]; then
    . /etc/rc.d/init.d/functions
else
    echo -e "\aJnice: unable to locate functions lib. Cannot continue."
    exit 0
fi
ulimit -n 65000
echo 1024 65000 > /proc/sys/net/ipv4/ip_local_port_range
## jar文件名称
export JAVA_HOME=/usr/lib/jvm/java-1.8.0
export CLASSPATH=$:CLASSPATH:$JAVA_HOME/lib/ 
export PATH=$PATH:$JAVA_HOME/bin
JAR_HOME=/usr/local/wvp-GB28181-pro/target
JAR_NAME=wvp-pro-2.3.1-06151618.jar
## 过滤pid进程号
wvp_pro=`ps -ef|grep $JAR_NAME | grep -v grep | grep -v kill | awk '{print $2}'`
#---------------------------------------------------------------------------
# START
#---------------------------------------------------------------------------
Start()
{
    if [ $tpid ]; then
        echo -n "wvp_pro process [${prog}] already running"
        echo_failure
        echo
        return 1
    fi
    if [ ! -f ${JAR_HOME}/${JAR_NAME} ]; then
        echo -n "wvp_pro binary [${prog}] not found."
        echo_failure
        echo
        return 1
    fi
    echo -n "starting service (wvp_pro): "
    cd ${JAR_HOME}
    nohup java -jar ${JAR_HOME}/${JAR_NAME}  > /dev/null 2>&1 &
    retval=$?
    if [ ${retval} == 0 ]; then
        echo_success
        echo
    else
        echo_failure
        echo
        break
    fi
    sleep 1
    return 0
}
#---------------------------------------------------------------------------
# STOP
#---------------------------------------------------------------------------
Stop()
{
    echo -n "stopping service (wvp_pro): "
    kill -9 $wvp_pro
    echo
    return 0
}
#---------------------------------------------------------------------------
# MAIN
#---------------------------------------------------------------------------
case "$1" in
    start)
        Start
        ;;
    stop)
        Stop
        ;;
    restart)
        Stop
        sleep 3
        Start
        ;;
    *)
        echo "please use : $0 {start|stop|restart}"
esac
exit
#开机自启动
[root@localhost target]# crontab -l */1 * * * * sh /usr/local/wvp-GB28181-pro/target/wvp-pro.sh start >/dev/null 2>&1

五、wvp-pro-assist部署

1.下载项目
#从git下载项目代码(此处还是安装在opt文件夹下)
cd /opt
git clone https://gitee.com/pan648540858/wvp-pro-assist
2.编译项目
cd wvp-pro-assist
mvn package
3.修改配置文件
根据实际环境替换修改target中的jar包BOOT-INF/classes/application-dev.yml

修改redis连接信息
修改zlm录像路径等
4.启动项目
#进入target目录后
java -jar wvp-pro-assist(你的jar包名称).jar 
如果不想替换targetjar包内容也可以直接设置配置文件地址,此处我采用的是将wvp-pro-assist/src/main/resource/下的application-dev.yml复制到target目录下进行修改使用。

#进入target目录后
java -jar wvp-pro-assist(你的jar包名称).jar --spring.config.location=application-dev.yml

五、wvp录像功能测试

方式1: 需要开启实时预览

开始和结束录像

先开始实时预览,录像存储路径下应该会产生文件 

方式2: 不间断录像

目前如果要实现不间断录像如果只是关闭无人观看停止推流是不够的,设备可能经历断网,重启,都会导致录像的中断,目前给大家提供一种可用的临时方案。

原理: wvp支持使用流地址自动点播,即你拿到一个流地址直接去播放,即使设备处于未点播状态,wvp会自动帮你点播;ZLM 的拉流代理成功后会无限重试,只要流一恢复就可以拉起来,基于这两个原理。
方案如下:

    1. wvp的配置中user-settings->auto-apply-play设置为团true,开启自动点播;
    2. 点击你要录像的通道,点击播放页面左下角的“更多地址”,点击rtsp,此时复制了rtsp地址到剪贴板;
    3. 在拉流代理中添加一路流,地址填写你复制的地址,启用成功即可。

 

posted on 2023-12-15 14:16  uestc2007  阅读(1666)  评论(0编辑  收藏  举报

导航