Merge branch 'master' into dev/abl支持

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java
#	src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java
#	src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java
#	src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java
#	src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java
#	src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
#	src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java
#	src/main/resources/application.yml
This commit is contained in:
lin
2025-07-03 14:58:24 +08:00
922 changed files with 75892 additions and 44475 deletions

View File

@@ -14,9 +14,10 @@ assignees: ''
- 3. 端口开放情况
- 4. 是否是公网部署
- 5. 是否使用https
- 6. 方便的话提供下使用的设备品牌或平台
- 6. 接入设备/平台品牌
- 7. 你做过哪些尝试
- 8. 代码更新时间
- 9. 是否是4G设备接入
**描述错误**
描述下您遇到的问题

View File

@@ -16,7 +16,7 @@ assignees: ''
- 5. 是否使用https
- 6. 方便的话提供下使用的设备品牌或平台
- 7. 你做过哪些尝试
- 8. 代码更新时间
- 8. 代码更新时间(旧版本请更新最新版本代码测试)
**内容描述:**

101
README.md
View File

@@ -8,44 +8,52 @@
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-yellow.svg)](https://github.com/xia-chu/ZLMediaKit/pulls)
WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台负责实现核心信令与设备管理后台部分支持NAT穿透支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。
WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台负责实现核心信令与设备管理后台部分支持NAT穿透支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。
流媒体服务基于@夏楚 ZLMediaKit [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
播放器使用@dexter jessibuca [https://github.com/langhuihui/jessibuca/tree/v3](https://github.com/langhuihui/jessibuca/tree/v3)
前端页面基于@Kyle MediaServerUI [https://gitee.com/kkkkk5G/MediaServerUI](https://gitee.com/kkkkk5G/MediaServerUI) 进行修改.
播放器使用@Numberwolf-Yanlong h265web.js [https://github.com/numberwolf/h265web.js](https://github.com/numberwolf/h265web.js)
前端页面基于vue-admin-template构建 [https://github.com/PanJiaChen/vue-admin-template?tab=readme-ov-file](https://github.com/PanJiaChen/vue-admin-template?tab=readme-ov-file)
# 应用场景:
支持浏览器无插件播放摄像头视频。
支持国标设备(摄像机、平台、NVR等)设备接入
支持非国标(onvif, rtsp, rtmp直播设备等等)设备接入,充分利旧。
支持国标级联。多平台级联。跨网视频预览。
支持跨网网闸平台互联。
- 支持浏览器无插件播放摄像头视频。
- 支持国标设备(摄像机、平台、NVR等)设备接入
- 支持rtsp, rtmp直播设备设备接入充分利旧。
- 支持国标级联。多平台级联。跨网视频预览。
- 支持跨网网闸平台互联。
# 文档
wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn)
ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
# 付费社群
[![社群](doc/_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm)
> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。
# gitee同步仓库
# gitee仓库
https://gitee.com/pan648540858/wvp-GB28181-pro.git
# 截图
![index](doc/_media/index.png "index.png")
![2](doc/_media/2.png "2.png")
![3](doc/_media/3.png "3.png")
![3-1](doc/_media/3-1.png "3-1.png")
![3-2](doc/_media/3-2.png "3-2.png")
![3-3](doc/_media/3-3.png "3-3.png")
![build_1](https://images.gitee.com/uploads/images/2022/0304/101919_ee5b8c79_1018729.png "2022-03-04_10-13.png")
<table>
<tr>
<td ><center><img src="doc/_media/1.png" >登录页面 </center></td>
<td ><center><img src="doc/_media/2.png" >首页</center></td>
</tr>
<tr>
<td ><center><img src="doc/_media/3.png" >分屏播放 </center></td>
<td ><center><img src="doc/_media/4.png" >国标设备列表</center></td>
</tr>
<tr>
<td ><center><img src="doc/_media/5.png" >行政区划管理 </center></td>
<td ><center><img src="doc/_media/8.png" >业务分组管理</center></td>
</tr>
<tr>
<td ><center><img src="doc/_media/6.png" >录制计划</center></td>
<td ><center><img src="doc/_media/7.png" >平台信息</center></td>
</tr>
</table>
# 功能特性
# 功能特性
- [X] 集成web界面
- [X] 兼容性良好
- [X] 支持电子地图支持接入WGS84和GCJ02两种坐标系并且自动转化为合适的坐标系进行展示和分发
- [X] 跨平台服务,一次编译多端部署, 可以同时用于x86和arm架构
- [X] 接入设备
- [X] 视频预览
- [X] 支持主码流子码流切换
@@ -67,6 +75,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
- [X] 支持播放H264和H265
- [X] 报警信息处理,支持向前端推送报警信息
- [X] 语音对讲
- [X] 支持业务分组和行政区划树自定义展示以及级联推送
- [X] 支持订阅与通知方法
- [X] 移动位置订阅
- [X] 移动位置通知处理
@@ -83,6 +92,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
- [X] 注册
- [X] 心跳保活
- [X] 通道选择
- [X] 支持通道编号自定义, 支持每个平台使用不同的通道编号
- [X] 通道推送
- [X] 点播
- [X] 云台控制
@@ -94,10 +104,11 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
- [X] 录像查看与播放
- [X] GPS订阅与通知直播推流
- [X] 语音对讲
- [X] 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题;
- [X] 多流媒体节点,自动选择负载最低的节点使用。
- [X] 支持同时级联到多个上级平台
- [X] 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题;
- [X] 支持流媒体节点集群,负载均衡。
- [X] 支持启用udp多端口模式, 提高udp模式下媒体传输性能;
- [X] 支持公网部署;
- [X] 支持公网部署;
- [X] 支持wvp与zlm分开部署提升平台并发能力
- [X] 支持拉流RTSP/RTMP分发为各种流格式或者推送到其他国标平台
- [X] 支持推流RTSP/RTMP分发为各种流格式或者推送到其他国标平台
@@ -107,34 +118,50 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
- [X] 支持打包可执行jar和war
- [X] 支持跨域请求,支持前后端分离部署
- [X] 支持MysqlPostgresql金仓等数据库
- [X] 支持Onvif(目前在onvif分支需要安装onvif服务服务请在知识星球获取)
- [X] 支持录制计划, 根据设定的时间对通道进行录制. 暂不支持将录制的内容转发到国标上级
- [X] 支持国标信令集群
# 非开源的内容
- [X] ONVIF设备的接入支持点播云台控制国标级联点播自动点播。在[知识星球](https://t.zsxq.com/10WAnH2MP)放了试用安装包以及使用教程,没有使用时间限制,需要源码可以星球私信我或者邮箱联系。
- [X] 支持国标28181-2022协议支持巡航轨迹查询PTZ精准控制存储卡格式化设备软件升级OSD配置h265+aac支持辅码流录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,需要源码和测试可以在星球私信联系或者发邮件给我
# 闭源内容
- [X] 支持ONVIF协议设备检索支持点播云台控制国标级联点播自动点播等。
- [X] 支持部标1078+808协议支持点播云台控制录像回放位置上报自动点播等。
- [X] 支持国标28181-2022协议支持巡航轨迹查询PTZ精准控制存储卡格式化设备软件升级OSD配置h265+aac支持辅码流录像倒放等。
- [X] 支持国网B接口协议。支持注册获取资源预览, 云台控制,预置位控制等,可免费定制支持语音对讲、录像回放和抓拍图像。
- [X] 功能加强版本
- [X] 支持按权限分配可以使用的通道
- [X] 支持电子地图。支持展示通道位置支持在地图上修改通道位置。可扩展接入高德地图API支持搜索位置附近设备。
- [X] 支持表格导出
- [X] 拉流代理支持按照品牌拼接url。
- [X] 功能持续扩展,可根据用户需要增加支持。
# 授权协议
本项目自有代码使用宽松的MIT协议在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议
# 技术支持
# 技术支持
# 付费社群
<img src="doc/_media/shequ.png" width="50%" height="50%">
> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。
> 加入三天内不满意可以直接自行推出,星球会直接退款给大家。需要发票可以在星球app中直接咨询星球客服获取。
> 星球还提供了包括闭源的全功能试用包, 会随时更新。
> 付费社群即可以对作者提供支持,也可以为大家更加快速的解决问题。如果暂时无法加入,给项目点个星也是极大的鼓励。
[知识星球](https://t.zsxq.com/0d8VAD3Dm)专栏列表:,
- [使用入门系列一WVP-PRO能做什么](https://t.zsxq.com/0dLguVoSp)
有偿技术支持请发送邮件到648540858@qq.com
有偿技术支持,一对一开发辅导,闭源内容合作请发送邮件到648540858@qq.com咨询
# 致谢
感谢作者[夏楚](https://github.com/xia-chu) 提供这么棒的开源流媒体服务框架,并在开发过程中给予支持与帮助。
感谢作者[dexter langhuihui](https://github.com/langhuihui) 开源这么好用的WEB播放器。
感谢作者[Kyle](https://gitee.com/kkkkk5G) 开源了好用的前端页面
感谢作者[dexter langhuihui](https://github.com/langhuihui)和[Numberwolf-Yanlong](https://github.com/numberwolf/h265web.js) 开源这么好用的WEB播放器。
感谢各位大佬的赞助以及对项目的指正与帮助。包括但不限于代码贡献、问题反馈、资金捐赠等各种方式的支持!以下排名不分先后:
[lawrencehj](https://github.com/lawrencehj) [Smallwhitepig](https://github.com/Smallwhitepig) [swwhaha](https://github.com/swwheihei)
[lawrencehj](https://github.com/lawrencehj) [Smallwhitepig](https://github.com/Smallwhitepig) [swwhaha](https://github.com/swwheihei)
[hotcoffie](https://github.com/hotcoffie) [xiaomu](https://github.com/nikmu) [TristingChen](https://github.com/TristingChen)
[chenparty](https://github.com/chenparty) [Hotleave](https://github.com/hotleave) [ydwxb](https://github.com/ydwxb)
[ydpd](https://github.com/ydpd) [szy833](https://github.com/szy833) [ydwxb](https://github.com/ydwxb) [Albertzhu666](https://github.com/Albertzhu666)
[mk1990](https://github.com/mk1990) [SaltFish001](https://github.com/SaltFish001)
同时感谢JetBrains对开源项目的支持本项目使用IntelliJ IDEA开发与调试
![JetBrains](https://resources.jetbrains.com/storage/products/company/brand/logos/IntelliJ_IDEA_icon.svg?_ga=2.143694769.529214288.1712023294-439039083.1711422571&_gl=1*102dv9n*_ga*NDM5MDM5MDgzLjE3MTE0MjI1NzE.*_ga_9J976DJZ68*MTcxMjEyNjg4NC45LjEuMTcxMjEyNzc2My4zMy4wLjA.)

115
bin/wvp.sh Normal file
View File

@@ -0,0 +1,115 @@
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
function log() {
message="[Polaris Log]: $1 "
case "$1" in
*"Fail"* | *"Error"* | *"请使用 root 或 sudo 权限运行此脚本"*)
echo -e "${RED}${message}${NC}" 2>&1 | tee -a
;;
*"Success"*)
echo -e "${GREEN}${message}${NC}" 2>&1 | tee -a
;;
*"Ignore"* | *"Jump"*)
echo -e "${YELLOW}${message}${NC}" 2>&1 | tee -a
;;
*)
echo -e "${BLUE}${message}${NC}" 2>&1 | tee -a
;;
esac
}
echo
cat <<EOF
██████╗ ██████╗ ██╗ █████╗ ██████╗ ██╗███████╗
██╔══██╗██╔═══██╗██║ ██╔══██╗██╔══██╗██║██╔════╝
██████╔╝██║ ██║██║ ███████║██████╔╝██║███████╗
██╔═══╝ ██║ ██║██║ ██╔══██║██╔══██╗██║╚════██║
██║ ╚██████╔╝███████╗██║ ██║██║ ██║██║███████║
╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝
EOF
#配置jdk的路径
export JAVA_HOME=/usr/local/java/jdk1.8.0_202 #此处为JDK路径
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
# WVP-pro defines
AppName=wvp-pro-2.7.2-05131055.jar
AppHome="/root/polaris/wvp/"
# JVM参数
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx2048m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
function start() {
log "======================= 开启流媒体服务 ======================="
log "AppName: $AppName"
log "AppHome: $AppHome"
log "Success:流媒体服务开启成功"
}
function stop() {
log "======================= 停止流媒体服务 ======================="
PID=""
query() {
PID=$(ps -ef | grep java | grep $AppName | grep -v grep | awk '{print $2}')
}
query
if [ x"$PID" != x"" ]; then
log "进程PID: $PID"
kill -TERM $PID
log "$AppName (pid:$PID) exiting..."
while [ x"$PID" != x"" ]; do
sleep 1
query
done
log "Success:$AppName exited."
else
log "Jump:进程不存在"
fi
}
function status() {
log "======================= 运行状态 ======================="
log ""
PID=$(ps -ef | grep java | grep $AppName | grep -v grep | wc -l)
if [ $PID != 0 ]; then
log "进程PID: $PID"
log "$AppName is running..."
else
log "$AppName is not running..."
fi
log ""
log "========================================================"
}
function restart() {
stop
sleep 3
start
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*) ;;
esac

20
buildPackage.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
# 获取当前日期并格式化为 YYYY-MM-DD 的形式
current_date=$(date +"%Y-%m-%d")
mkdir -p "$current_date"/数据库
cp -r ./数据库/2.7.3 "$current_date"/数据库
cp src/main/resources/配置详情.yml "$current_date"
cp src/main/resources/application-dev.yml "$current_date"/application.yml
cp ./target/wvp-pro-*.jar "$current_date"
zip -r "$current_date".zip "$current_date"
rm -rf "$current_date"
exit 0

View File

@@ -3,11 +3,15 @@
> 开箱即用的28181协议视频平台
# 概述
- WVP-PRO基于GB/T 28181-2016标准实现的流媒体平台依托优秀的开源流媒体服务[ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit),提供完善丰富的功能。
- WVP-PRO基于GB/T
28181-2016标准实现的流媒体平台依托优秀的开源流媒体服务[ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit)
,提供完善丰富的功能。
- GB/T 28181-2016 中文标准名称是《公共安全视频监控联网系统信息传输、交换、控制技术要求》是监控领域的国家标准。大量应用于政府视频平台。
- 通过28181协议你可以将IPC摄像头接入平台可以观看也可以使用28181/rtsp/rtmp/flv等协议将视频流分发到其他平台。
# 特性
- 实现标准的28181信令兼容常见的品牌设备比如海康、大华、宇视等品牌的IPC、NVR以及平台。
- 支持将国标设备级联到其他国标平台,也支持将不支持国标的设备的图像或者直播推送到其他国标平台
- 前端完善,自带完整前端页面,无需二次开发可直接部署使用。
@@ -15,92 +19,94 @@
- 支持多流媒体节点负载均衡。
# 付费社群
[![社群](_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm)
> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。
# 我们实现了哪些国标功能
**作为上级平台**
- [X] 注册
- [X] 注销
- [X] 实时视音频点播
- [X] 设备控制
- [X] 云台控制
- [X] 远程启动
- [X] 录像控制
- [X] 报警布防/撤防
- [X] 报警复位
- [X] 强制关键帧
- [X] 拉框放大
- [X] 拉框缩小
- [X] 看守位控制
- [X] 设备配置
- [X] 云台控制
- [X] 远程启动
- [X] 录像控制
- [X] 报警布防/撤防
- [X] 报警复位
- [X] 强制关键帧
- [X] 拉框放大
- [X] 拉框缩小
- [X] 看守位控制
- [X] 设备配置
- [X] 报警事件通知和分发
- [X] 设备目录订阅
- [X] 网络设备信息查询
- [X] 设备目录查询
- [X] 设备状态查询
- [X] 设备配置查询
- [X] 设备预置位查询
- [X] 设备目录查询
- [X] 设备状态查询
- [X] 设备配置查询
- [X] 设备预置位查询
- [X] 状态信息报送
- [X] 设备视音频文件检索
- [X] 历史视音频的回放
- [X] 播放
- [X] 暂停
- [X] 进/退
- [X] 停止
- [X] 播放
- [X] 暂停
- [X] 进/退
- [X] 停止
- [X] 视音频文件下载
- [X] 校时
- [X] 订阅和通知
- [X] 事件订阅
- [X] 移动设备位置订阅
- [X] 报警订阅
- [X] 目录订阅
- [X] 事件订阅
- [X] 移动设备位置订阅
- [X] 报警订阅
- [X] 目录订阅
- [X] 语音广播
- [X] 语音喊话
**作为下级平台**
- [X] 注册
- [X] 注销
- [X] 实时视音频点播
- [X] 设备控制
- [X] 云台控制
- [ ] 远程启动
- [X] 录像控制
- [X] 报警布防/撤防
- [X] 报警复位
- [X] 强制关键帧
- [X] 拉框放大
- [X] 拉框缩小
- [X] 看守位控制
- [ ] 设备配置
- [X] 云台控制
- [ ] 远程启动
- [X] 录像控制
- [X] 报警布防/撤防
- [X] 报警复位
- [X] 强制关键帧
- [X] 拉框放大
- [X] 拉框缩小
- [X] 看守位控制
- [ ] 设备配置
- [ ] 报警事件通知和分发
- [X] 设备目录订阅
- [X] 网络设备信息查询
- [X] 设备目录查询
- [X] 设备状态查询
- [ ] 设备配置查询
- [X] 设备预置位查询
- [X] 设备目录查询
- [X] 设备状态查询
- [ ] 设备配置查询
- [X] 设备预置位查询
- [X] 状态信息报送
- [X] 设备视音频文件检索
- [X] 历史视音频的回放
- [X] 播放
- [x] 暂停
- [x] 进/退
- [x] 停止
- [X] 播放
- [x] 暂停
- [x] 进/退
- [x] 停止
- [X] 视音频文件下载
- [ ] ~~校时~~
- [X] 订阅和通知
- [X] 事件订阅
- [X] 移动设备位置订阅
- [ ] 报警订阅
- [X] 目录订阅
- [X] 事件订阅
- [X] 移动设备位置订阅
- [ ] 报警订阅
- [X] 目录订阅
- [X] 语音广播
- [X] 语音喊话
# 社区
代码目前托管在GitHub和GiteeGitee目前作为加速仓库使用不接受issue。
GitHub [https://github.com/648540858/wvp-GB28181-pro](https://github.com/648540858/wvp-GB28181-pro)
Gitee [https://gitee.com/pan648540858/wvp-GB28181-pro](https://gitee.com/pan648540858/wvp-GB28181-pro)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

@@ -1,2 +1,3 @@
<!-- 自动点播 -->
# 自动点播

View File

@@ -1,34 +1,56 @@
<!-- 国标级联的使用 -->
# 国标级联的使用
国标28181不同平台之间支持两种连接方式平级和上下级WVP目前支持向上级级联。
## 1 接入平台
### 1.1 wvp-pro
#### 1.1.1 wvp-pro管理页面点击添加
![cascade1](_media/cascade1.png)
![cascade1](_media/cascade1.png)
#### 1.1.2 填入wvp-pro上级平台信息
![cascade1](_media/img_4.png)
![cascade1](_media/img_5.png)
![cascade1](_media/img_4.png)
![cascade1](_media/img_5.png)
#### 1.1.3 编辑wvp-pro上级设备信息开启订阅
![cascade1](_media/img_6.png)
![cascade1](_media/img_6.png)
### 1.2 大华平台
### 1.3 海康平台
### 1.4 liveGBS
#### 1.4.1. wvp-pro管理页面点击添加
![添加](_media/cascade1.png)
#### 1.4.2. 填入liveGBS平台信息
![填入liveGBS平台信息1](_media/cascade2.png)
![填入liveGBS平台信息2](_media/cascade3.png)
#### 1.4.3. 编辑liveGBS设备信息,开启目录订阅
![cascade1](_media/cascade4.png)
#### 1.4.4. 编辑liveGBS设备信息开启GPS订阅
![cascade1](_media/img_7.png)
#### 1.4.1. wvp-pro管理页面点击添加
![添加](_media/cascade1.png)
#### 1.4.2. 填入liveGBS平台信息
![填入liveGBS平台信息1](_media/cascade2.png)
![填入liveGBS平台信息2](_media/cascade3.png)
#### 1.4.3. 编辑liveGBS设备信息开启目录订阅
![cascade1](_media/cascade4.png)
#### 1.4.4. 编辑liveGBS设备信息开启GPS订阅
![cascade1](_media/img_7.png)
## 2 添加目录与通道
1. 级联平台添加目录信息
![cascade1](_media/img_1.png)
2. 为目录添加通道
![cascade1](_media/img_2.png)
3. 设置默认流目录
如果需要后续自动生成的流信息都在某一个节点下,可以在对应节点右键设置为默认
如果需要后续自动生成的流信息都在某一个节点下,可以在对应节点右键设置为默认
![cascade1](_media/img_3.png)

View File

@@ -1,18 +1,71 @@
<!-- 国标级联的使用 -->
# 国标级联的使用
国标28181不同平台之间支持两种连接方式平级和上下级WVP目前支持向上级级联。
## 添加上级平台
在国标级联页面点击“添加”按钮以推送到上级WVP为例子参看[接入设备](./_content/ability/device.md)
![cascade17](_media/img_17.png)
点击保存可以在上级的国标通道列表看到新增加的设备;
1. 名称
上级平台看到的下级平台名称;
2. 本地IP
本地连接上级使用的具体哪个网卡;
3. SIP认证用户名
可以设置为与"设备国标编号"一致;
4. 注册周期
间隔多久发起一次注册,单位秒;
5. 心跳周期
间隔多久发送一次心跳,一般上级平台三次收不到心跳就会认为下级离线了, 所以建议{心跳周期}x3 < 注册周期;
6. SDP发流IP
调用媒体节点发送视频流给上级时,使用的本地IP;
7. 信令传输
信令传输模式,支持udp和TCP,没有特殊需求,默认UDP即可;
8. 目录分组
上级发送"CATALOG"消息查询通道信息,每一条消息中携带几条通道信息,默认为1,增大该值,可以加快通道发送速度;
9. 字符集
发送给上级"MESSAGE"消息中的消息体使用的编码格式,国标28181-2016默认为GB2312;
10. 行政区划
如果勾选"其他选项/推送平台信息"选项,会给上级推送平台信息,这里就是平台的行政区划信息
11. 平台厂商
如果勾选"其他选项/推送平台信息"选项,会给上级推送平台信息,这里就是平台的平台厂商信息
12. 平台型号
如果勾选"其他选项/推送平台信息"选项,会给上级推送平台信息,这里就是平台的平台型号信息
13. 平台安装地址
如果勾选"其他选项/推送平台信息"选项,会给上级推送平台信息,这里就是平台的平台安装地址信息
14. 其他选项
- RTCP保活
在上级的流传输模式为UDP时,因为UDP的无状态特性,会无法知道上级是否在正常收流,启用RTCP保活时,就可以主动发送RTCP消息确认上级是否在正常收流,
异常情况下,可以下级主动停止发流;
- 消息通道
支持通过报警消息给上级级WVP推送消息,消息内容由redis消息发送给wvp,wvp编辑成报警消息发送给上级;
- 主动推送通道
WVP模拟一条目录订阅信息,然后在共享通道变化时,发送CATAOLOG事件给上级,通知具体的通道变化,
目前支持的状态有: 状态改变事件 ON:上线,OFF:离线,VLOST:视频丢失,DEFECT:故障,ADD:增加,DEL:删除,UPDATE:更新;
- 推送平台信息
勾选此项,上级收到的通道信息中会多出一个平台信息的通道.内容在平台的编辑中修改;
- 推送分组信息
勾选此项,如果你共享的通道分配了具体的业务分组以及虚拟组织,那么上级收到的通道中会包括业务分组以及虚拟组织节点信息;
- 推送行政区划
勾选此项,如果你共享的通道分配了具体的行政区划,那么上级收到的通道中会包括行政区划信息;
国标级联列表出现了级联的这个平台;同时状态显示为在线,如果状态为离线那么可能是你的服务信息配置有误或者网络不通。
订阅信息列有三个图标,表示上级开启订阅,从左到右依次是:报警订阅,目录订阅,移动位置订阅。
## 推送通道
点击你要推送的平台的“选择通道”按钮。
## 通道共享
点击你要推送的平台的“通道共享”按钮。
![cascade18](_media/img_18.png)
- **页面结构**
- 左侧为目录结构
选择未分配,则右侧显示待分配的通道,可以点击“添加按钮”,在弹窗中选择要放置的位置,保存后即可添加通道成功
选择其他的目录可以看到已经分配在这个目录下的通道,可以对其进行删除后重新在未分配中去分配。
- 右侧为数据展示以及操作
国标通道栏内为来自其他国标设备/平台的通道;直播流通道为来自推流/拉流代理的通道。
1. 添加状态选择"未共享"可以将具体的通道共享给上级;
2. 添加状态选择"已共享"可以看到已经共享的通道,并且支持为这个通道在这个平台设备专门的名称和编号;
3. 点击"按设备添加"可以将某个国标设备下的所有通道共享给上级;
4. 点击"按设备移除"可以将某个国标设备下的所有通道取消共享给上级;
5. 点击"全部添加"可以将所有通道共享给上级;
6. 点击"全部移除"可以将所有通道共享给上级;
## 推送通道
WVP会将所有通道信息按照目录订阅消息通知形式,发送ADD事件给上级.

View File

@@ -0,0 +1,25 @@
# 通道管理
通道管理为了对已经分配国标编号的通道进行统一的行政区划和业务分组管理,国标中对于组织结构有两种表示方式,一种是按照行政区划,一种是业务分组+虚拟组织的方式.
行政区划结构固定,比如: 北京/市辖区/昌平区, 通道可以挂载道何一级行政区划下. 业务分组比较灵活, 可以按照自己的随意取名,
但是通道只能放在业务分组下的虚拟组织里,不能放在业务分组下.
## 行政区划
左侧树结构为行政区划结构, 通过数据鼠标右键可以操作,包括: 刷新节点,新建节点,编辑节点,删除节点,添加设备(
可以将某个国标设备下的通道全部添加道某一个节点下),移除设备(可以将某个国标设备下的通道全部从这个节点移除)
右侧伪通道列表, 对于非国标接入的设备只有配置了国标编号后才可以在这里进行操作。
选择左侧的节点后,可以点击右侧的“添加通道”, 选择需要的通道添加到改节点下,如果找不到通道, 可以选择“异常挂载通道”,点击清理后重新回来选择。
![行政区划](_media/img_21.png)
## 业务分组
左侧树结构为业务分组结构, 通过数据鼠标右键可以操作,包括: 刷新节点,新建节点,编辑节点,删除节点,添加设备(
可以将某个国标设备下的通道全部添加道某一个节点下),移除设备(可以将某个国标设备下的通道全部从这个节点移除)
业务分组下不能挂载设备,所以没有选择该节点的单选框.
右侧为通道列表, 对于非国标接入的设备只有配置了国标编号后才可以在这里进行操作。
选择左侧的节点后,可以点击右侧的“添加通道”, 选择需要的通道添加到改节点下。
如果找不到通道, 可以选择“异常挂载通道”,点击清理后重新回来选择。
注意,根资源组下的那一级为业务分组类型不可以直接挂载设备,需要继续建立节点,后续的节点的都是虚拟组织类型, 就可以挂载通道了。
![业务分组](_media/img_22.png)

View File

@@ -1,8 +1,13 @@
<!-- 云端录像 -->
# 云端录像
![云端录像](_media/img_26.png)
云端录像是对录制在zlm服务下的录像文件的管理录像的文件路径默认在ZLM/www/record下。
如果你需要24小时的录像目前有一个这种方案可以参考[7*24不间断录像](./_content/ability/continuous_recording.md)。
1. 云段录像支持录像文件的查看,播放(可能因为编码的原因导致无法播放);
2. 支持录像的下载;
3. 支持录像的合并下载;
功能没有太多特殊的地方就不一一介绍了,大家自行体验吧。
- 国标设备是否录像: 可以再WVP的配置中user-settings.record-sip设置为true那么每次点播以及录像回放都会录像;
- 推流设备是否录像: 可以再WVP的配置中user-settings.record-push-live设置为true;
- 拉流代理的是否录像: 在添加和编辑拉流代理时可以指定, 每次点播都会进行录像
- 录像文件存储路径配置: 可以修改media.record-path来修改录像路径,但是如果有旧的录像文件,请不要迁移,因为数据库记录了每一个录像的绝对路径,一旦修改会造成找到文件,无法定时移除以及播放
- 录像保存时间: 可以修改media.record-day来修改录像保存时间,单位是天;

View File

@@ -1,9 +1,13 @@
# 语音对讲
## 流程和原理
语音对讲在国标28181-2016中分为broadcast广播和talk对讲两种模式broadcast模式是从服务端把音频传送到设备端是单向的
需要结合点播视频来实现双向对讲talk模式支持双向不过wvp只处理了和broadcast一样的把音频传递设备这样两种模式可以使用一样的逻辑处理即可。
不同的设备对于两种模式的支持不同且通常差异很大不同的设备对同一个设备的支持也有一些不同所以语音对讲中的兼容和适配也是问题最多的。talk模式因为在国标28181-2022中已经移除所以这里不再讨论它了。
### 1. broadcast模式流程
```plantuml
@startuml
"WVP-PRO" -> "设备": 语音广播通知
@@ -16,24 +20,33 @@
"ZLMediaKit" -> "设备": 向设备发送语音流
@enduml
```
与点播的流程不同的是这里的invite消息是由设备发送给wvp的wvp按照invite协商的方式给设备推送语音流所有对讲的使用那种方式UDP/TCP被动/TCP主动传输语音流由设备决定
## 使用条件与限制
因为invite消息是由设备发送给wvp的这决定了发送语音流的方式这也就决定了有的设备不能用于公网对讲比如大部分的海康设备只支持udp方式收流(目前新版的海康设备已经在着手解决这个问题)那么wvp发流时只能按照sdp中指定的ip端口发流所以如果wvp在公网设备在内网中那么wvp无法连接设备提供的IP发流也就失败了。
因为invite消息是由设备发送给wvp的这决定了发送语音流的方式这也就决定了有的设备不能用于公网对讲比如大部分的海康设备只支持udp方式收流(
目前新版的海康设备已经在着手解决这个问题)那么wvp发流时只能按照sdp中指定的ip端口发流所以如果wvp在公网设备在内网中那么wvp无法连接设备提供的IP发流也就失败了。
与海康不同的大华以及很多执法记录仪厂商是支持tcp主动方式取流的这样是可以实现公网对讲的。
## 使用ffmpeg快速测试
由于浏览器对于音频的采集需要网页支持https才可以所以如果想要实现网页音频对讲那么你必须给wvp和zlm配置证书以使用https。
测试阶段如果只是想测试功能可以用ffmpeg来模拟语音流推送到wvp后可以实现把音频文件推送到摄像头。
测试命令格式如下:
```shell
ffmpeg -re -i {音频文件} -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp 'rtsp://{zlm的IP}:{zlm的RTSP端口}/broadcast/{设备国标编号}_{通道国标编号}?sign={md5(pushKey)}'
```
例如
```shell
ffmpeg -re -i test.mp3 -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp 'rtsp://192.168.1.3:22554/broadcast/34020000001320000001_34020000001320000001?sign=41db35390ddad33f83944f44b8b75ded'
```
测试流程如下:
```plantuml
@startuml
"FFMPEG" -> "ZLMediaKit": 推流到zlm
@@ -44,33 +57,48 @@ ffmpeg -re -i test.mp3 -acodec pcm_alaw -ar 8000 -ac 1 -f rtsp 'rtsp://192.168.1
"ZLMediaKit" -> "设备": 向设备推流
@enduml
```
如果听到设备播放你推送的音频,那么意味着调用成功,此过程推流即可需要调用任何接口
## 生产环境网页发起语音对讲
生产环境下使用语音对讲如果是自己的客户端设备那么直接上面的ffmpeg测试方式按照固定格式推流到zlm即可。
对于WEB程序主要是局域网和公网的区别两个原因
1. 很多设备不支持公网对讲
2. 公网和局域网获取证书实现https支持的方式不同
### 公网使用
公网你可以直接使用证书厂商或者云服务器厂商提供的证书,这是很方便的。
### 局域网使用
局域网你需要为wvp和zlm生成自签名证书这里我推荐一种生成自签名证书相对方便的方式,
此方式为linux下的一种方式。
下载证书生成工具:
[https://github.com/FiloSottile/mkcert/releases/tag/v1.4.4](https://github.com/FiloSottile/mkcert/releases/tag/v1.4.4)
安装此工具, 进入解压的工具目录,执行
```shell
./mkcert-v1.4.4-linux-amd64 -install
```
生成pem证书
```shell
./mkcert-v1.4.4-linux-amd64 局域网IP 局域网IP2 局域网IP3
```
你会得到两文件*-key.pem和*.pem, 此文件配置到wvp后既可实现证书的加载
生成zlm使用的证书
```shell
cat *.pem *-key.pem> ./zlm.pem
```
得到的文件就是可以给zlm使用的证书
zlm下使用证书有两种方式
1. 替换zlm下的default.pem, 即删除此文件并把zlm.pem重命名为default.pem
2. 在启动zlm的使用添加 `-s zlm.pem`

View File

@@ -1,14 +1,16 @@
<!-- 7*24不间断录像 -->
# 7*24不间断录像
目前如果要实现不间断录像如果只是关闭无人观看停止推流是不够的,设备可能经历断网,重启,都会导致录像的中断,目前给大家提供一种可用的临时方案。
目前如果要实现不间断录像如果只是关闭无人观看停止推流是不够的,设备可能经历断网,重启,都会导致录像的中断,目前给大家提供一种可用的临时方案。
**原理:** wvp支持使用流地址自动点播即你拿到一个流地址直接去播放即使设备处于未点播状态wvp会自动帮你点播ZLM
的拉流代理成功后会无限重试,只要流一恢复就可以拉起来,基于这两个原理。
**方案如下:**
1. wvp的配置中user-settings->auto-apply-play设置为团true,开启自动点播;
2. 点击你要录像的通道点击播放页面左下角的“更多地址”点击rtsp此时复制了rtsp地址到剪贴板
3. 在拉流代理中添加一路流,地址填写你复制的地址,启用成功即可。
**前提:**
**前提:**
1. wvp使用多端口收流不然你无法得到一个固定的流地址也就无法实现自动点播。

View File

@@ -1,33 +1,72 @@
<!-- 接入设备 -->
# 接入设备
设备接入主要是需要在设备上配置28181上级也就是WVP-PRO的信息只有信息一致的情况才可以注册成功。设备注册成功后打开WVP->国标设备,可以看到新增加的设备;[设备使用](./_content/ability/device_use.md)
主要有以下字段需要配置:
## 国标28181设备
设备接入主要是需要在设备上配置28181上级也就是WVP-PRO的信息只有信息一致的情况才可以注册成功。设备注册成功后打开WVP->
国标设备,可以看到新增加的设备;[设备使用](./_content/ability/device_use.md)
主要有以下字段需要配置:
- sip->port
28181服务监听的端口
28181服务监听的端口
- sip->domain
domain宜采用ID统一编码的前十位编码。
domain宜采用ID统一编码的前十位编码。
- sip->id
28181服务ID
28181服务ID
- sip->password
28181服务密码
28181服务密码
- 配置信息在如下位置
- 配置信息在如下位置
![_media/img_16.png](_media/img_16.png)
***
## 大华摄像头
### 1. 大华摄像头
![_media/img_10.png](_media/img_10.png)
## 大华NVR
### 2. 大华NVR
![_media/img_11.png](_media/img_11.png)
## 艾科威视摄像头
### 3. 宇视科技
![_media/img_25.png](_media/img_25.png)
### 3. 艾科威视摄像头
![_media/img_15.png](_media/img_15.png)
## 水星摄像头
### 4. 水星摄像头
![_media/img_12.png](_media/img_12.png)
## 海康摄像头
### 5. 海康摄像头
![_media/img_9.png](_media/img_9.png)
## 直播推流设备
这里以obs推流为例,很多无人机也是一样的,设置下推流地址就可以接入了
1. 从wvp获取推流地址, 选择节点管理菜单,查看要推流的节点;
![_media/img_19.png](_media/img_19.png)
2. 拼接推流地址
得到的rtsp地址就是: rtsp://{流IP}:{RTSP PORT}/{app}/{stream}
得到的rtmp地址就是: rtsp://{流IP}:{RTMP PORT}/{app}/{stream}
其中流IP是设备可以连接到zlm的IP,端口是对应协议的端口号, app和stream自己定义就可以.
3. 增加推流鉴权信息
wvp默认开启推流鉴权,拼接好的地址是不能直接推送的,会被返回鉴权失败,参考[推流规则](_content/ability/push?id=推流规则)
4. 推流成功后可以再推流列表中看到推流设备,可以播放
此方式只支持设备实时流的播放,无其他功能, 推流信息在推流结束后会自动移除,在列表里就看不到了,如果需要推流信息需要为设备配置国标编号,这样才可以作为wvp的一个永久通道存在.
## 接入非国标IPC设备或者其他流地址形式的设备
这类设备的接入主要通过拉流代理的方式接入,原理就是zlm主动像播放器一样拉取这个流缓存在自己服务器供其他人播放.可以解决源设备并发访问能力差的问题.
在拉流代理/添加代理后可以直接播放, 拉流代理也是同样只支持播放当前配置的流.
[设备使用](_content/ability/device_use.md)

View File

@@ -1,21 +1,30 @@
<!-- 设备使用 -->
# 设备使用
### 更新设备通道
点击列表末尾的“刷新”按钮,可以看到一个圆形进度条,等进度结束提示成功后即可更新完成,如果通道数量有变化你可以看点击左上角的![刷新](_media/img_14.png)即可看到通道数量的变化如果通道数量仍未0,那么可能时对方尚未推送通道给你。
### 查看设备通道
点击列表末尾的“通道”按钮,
### 查看设备定位
点击列表末尾的“定位”按钮,即可跳转到地图页面看到设备的位置
### 编辑设备在WVP中一些功能
# 国标设备
### 更新设备通道
点击列表末尾的“刷新”按钮,可以看到一个圆形进度条,等进度结束提示成功后即可更新完成,如果通道数量有变化你可以看点击左上角的![刷新](_media/img_14.png)
即可看到通道数量的变化如果通道数量仍未0,那么可能时对方尚未推送通道给你。
### 查看设备通道
点击列表末尾的“通道”按钮,
### 编辑设备
点击列表末尾的“编辑”按钮,即可在打开的弹窗中对设备功能进行修改
- 设备名称
如何未能从设备里读取到设备名称或者需要自己重命名,那么可以修改此选项。
- 密码
支持为设备配置独立的密码.
- 收流IP
如果你需要设备从指定的网络地址接入视频流,那么可以配置此IP,设备将会发流到这个IP,比如多网卡接入的服务器.或者存在网络映射的情况.
- 流媒体ID
固定设备使用的流媒体ID,默认根据负载自动分配.
- 字符集
修改读取设备数据时使用的字符集默认为GB2312,但是GB2312收录的汉字不全所以有时候回遇到乱码可以修改为UTF-8来解决。
- 地理坐标系
展示此设备定位信息时使用的设用什么坐标系来解析经纬度,一般不用修改,如果遇到定位不准,可以修改尝试修改此选项解决。
- 目录结构
展示设备的通道信息时使用设备作为树形结构的依据国标28181定义了两种树形结构详情查看[国标28181的树形结构](./_content/theory/channel_tree.md)
- 目录订阅
填写订阅周期即可对设备开启目录订阅设备如果支持目录订阅那么设备在通道信息发生变化时就会通知WVP哪些通道发生了那些变化包括通道增加/删除/更新/上线/下线/视频丢失/故障。0为取消订阅。
一般NVR和平台对接可以开启此选项直接接摄像机开启此选项意义不大。
@@ -23,13 +32,31 @@
对设备开启移动位置订阅设备如果支持目录订阅那么设备位置发生变化时会通知到WVP,一般执法记录仪可以开启此选项,对固定位置的设备意义不大。
- SSRC校验
为了解决部分设备出现的串流问题可以打开此选项。ZLM会严格按照给定的ssrc处理视频流。部分设备流信息不标准开启可能导致无法点播。
### 删除设备
可以删除WVP中的设备信息如果设备28181配置未更改那么设备在下一次注册后仍然会注册上来。
### 点播视频
进入通道列表后,点击列表末尾的“播放”按钮,稍等即可弹出播放页面
### 设备录像
进入通道列表后,点击列表末尾的“设备录像”按钮,也可以在播放页面点击录像查询进入录像查看页面,选择要查看的日期即可对录像进行播放和下载。
### 云台控制
可以对支持云台功能的设备进行上下左右的转动以及拉近拉远的操作。
### 获取视频的播放器地址
视频点播成功后在实时视频页面点击“更多地址”可以看到所有的播放地址地址是否可以播放与你是否完整编译启用zlm功能有关更与网络有关。
- 作为消息通道
wvp支持通过报警消息给下级WVP互相推送消息,消息内容由redis消息发送给wvp,wvp编辑成报警消息发送给下级
- 收到ACK后发流
语音对讲策略: 不同的设备对于语音对讲的收流时机要求不一,勾选后会在收到设备发送的ack后再开始发流,不勾选则在回复200OK后开始发流,目前已知大华设备不勾选,海康需要勾选.
### 删除设备
可以删除WVP中的设备信息如果设备28181配置未更改那么设备在下一次注册后仍然会注册上来
### 点播视频
进入通道列表后,点击列表末尾的“播放”按钮,稍等即可弹出播放页面
### 设备录像
进入通道列表后,点击列表末尾的“设备录像”按钮,也可以在播放页面点击录像查询进入录像查看页面,选择要查看的日期即可对录像进行播放和下载。
### 云台控制
可以对支持云台功能的设备进行上下左右的转动以及拉近拉远的操作。
### 获取视频的播放器地址
视频点播成功后在实时视频页面点击“更多地址”可以看到所有的播放地址地址是否可以播放与你是否完整编译启用zlm功能有关更与网络有关。
### 语音对讲
[语音对讲](_content/ability/continuous_broadcast.md)

View File

@@ -1,20 +1,26 @@
<!-- 电子地图 -->
# 电子地图
WVP提供了简单的电子地图用于设备的定位以及移动设备的轨迹信息电子地图基于开源的地图引擎openlayers开发。
### 查看设备定位
1. 可以在设备列表点击“定位”按钮,自动跳转到电子地图页面;
2. 在电子地图页面在设备上右键点击“定位”获取设备/平台下的所有通道位置。
3. 单击通道信息可以定位到具体的通道
# 电子地图
WVP提供了简单的电子地图用于设备的定位以及移动设备的轨迹信息电子地图基于开源的地图引擎openlayers开发。
### 查看设备定位
1. 可以在设备列表点击“定位”按钮,自动跳转到电子地图页面;
2. 在电子地图页面在设备上右键点击“定位”获取设备/平台下的所有通道位置。
3. 单击通道信息可以定位到具体的通道
### 查询设备轨迹
查询轨迹需要提前配置save-position-history选项开启轨迹信息的保存目前WVP此处未支持分库分表对于大数据量的轨迹信息无法胜任有需求请自行二次开发或者定制开发。
在电子地图页面在设备上右键点击“查询轨迹”获取设备轨迹信息。
PS 目前的底图仅用用作演示和学习,商用情况请自行购买授权使用。
### 更换底图以及底图配置
目前WVP支持使用了更换底图配置文件在web_src/static/js/config.js请修改后重新编译前端文件。
```javascript
window.mapParam = {
// 开启/关闭地图功能

View File

@@ -1,9 +1,20 @@
<!-- 节点管理 -->
# 节点管理
![节点管理](_media/img_26.png)
WVP支持单个WVP多个ZLM的方案来扩展WVP的视频并发能力并发点播是因为带宽和性能的原因单个ZLM节点能支持的路数有限所以WVP增加了ZLM集群来扩展并发并且保证ZLM的高可用。
## 默认节点
WVP中为了保证功能的完整性ZLM节点至少要有一个默认节点这个节点不是在管理页面添加的而是在WVP的配置文件中配置的这个节点不可在页面删除。每次启动会自动从配置文件中读取配置写入数据库备用。
## 新增节点
启动你要添加的zlm节点然后点击“添加节点”按钮输入zlm的ip http端口SECRET。点击测试测试完成则开始对节点进行详细的设置如果你的zlm是使用docker启动的可能存在zlm使用的端口与宿主机端口不一致的情况需要在这里一一配置。
启动你要添加的zlm节点然后点击“添加节点”按钮输入zlm的ip
http端口SECRET。点击测试测试完成则开始对节点进行详细的设置如果你的zlm是使用docker启动的可能存在zlm使用的端口与宿主机端口不一致的情况需要在这里一一配置。
## wvp使用多个节点的原理
wvp会把连接的节点统一记录在redis中并记录zlm的负载情况当新的请求到来时会取出负载最低的那个zlm进行使用。以此保证节点负载均衡。

View File

@@ -1,2 +1,3 @@
<!-- 在线文档 -->
# 在线文档

View File

@@ -1,12 +1,17 @@
<!-- 拉流代理 -->
# 拉流代理
不是所有的摄像机都支持国标或者推流的但是这些设备可以得到一个视频播放地址通常为rtsp协议
以大华为例:
```text
rtsp://{user}:{passwd}@{ipc_ip}:{rtsp_port}/cam/realmonitor?channel=1&subtype=0
```
可以得到这样一个流地址可以直接用vlc进行播放此时我们可以通过拉流代理功能将这个设备推送给其他国标平台了。
流程如下:
```plantuml
@startuml
"摄像机" <- "ZLMediaKit": 1. 流去流信息到ZLM
@@ -15,10 +20,13 @@ rtsp://{user}:{passwd}@{ipc_ip}:{rtsp_port}/cam/realmonitor?channel=1&subtype=0
"WVP-PRO" -> "ZLMediaKit": 4. 通知推流到上级国标平台
@enduml
```
## 添加代理
拉流代理支持两种方式:
1. ZLM中直接代理流支持RTSP/RTMP不支持转码
2. 借助ffmpeg完成拉转可以通过修改ffmpeg拉转参数完成转码。
点击页面的“添加代理”,安装提示操作即可,保存并启用成功后,可以在国标级联中[添加通道推送给上级平台](./_content/ability/cascade?id=_2-%e6%b7%bb%e5%8a%a0%e7%9b%ae%e5%bd%95%e4%b8%8e%e9%80%9a%e9%81%93)
点击页面的“添加代理”,添加信息后保存即可,如果你需要共享推流信息到其他国标平台,那么你需要编辑/国标通道配置,配置国标编码.
PS ffmpeg默认模板不需修改需要修改参数自行去ZLM配置文件中添加一个即可。
`PS ffmpeg默认模板不需修改需要修改`参数自行去ZLM配置文件中添加一个即可。

View File

@@ -1,8 +1,11 @@
<!-- 推流列表 -->
# 推流列表
## 功能说明
WVP支持三种图像输入方式直播[拉流代理](_content/ability/proxy.md)[国标](_content/ability/device.md),直播设备接入流程如下
```plantuml
@startuml
"直播设备" -> "ZLMediaKit": 1. 发起推流
@@ -11,30 +14,41 @@ WVP支持三种图像输入方式直播[拉流代理](_content/ability/pro
"WVP-PRO" -> "ZLMediaKit": 4. 通知推流到上级国标平台
@enduml
```
1. 默认情况下WVP收到推流信息后列表中出现这条推流信息此时你可以点击“加入国标”按钮为此路推流配置名称以及国标编号只有有国标编号的推流才可以添加到级联平台保存成功后可以在国标级联中[添加通道推送给上级平台](_content/ability/cascade?id=_2-%e6%b7%bb%e5%8a%a0%e7%9b%ae%e5%bd%95%e4%b8%8e%e9%80%9a%e9%81%93)
2. WVP也支持推流前导入大量通道直接推送给上级点击“下载模板”按钮根据示例修改模板后点击“通道导入”按钮导入通道数据保存成功后可以在国标级联中[添加通道推送给上级平台](_content/ability/cascade?id=_2-%e6%b7%bb%e5%8a%a0%e7%9b%ae%e5%bd%95%e4%b8%8e%e9%80%9a%e9%81%93)
1. 默认情况下WVP收到推流信息后列表中出现这条推流信息如果你需要共享推流信息到其他国标平台,那么你需要编辑/国标通道配置,配置国标编码.
2. WVP也支持推流前导入大量通道直接推送给上级点击“下载模板”按钮根据示例修改模板后点击“通道导入”按钮导入通道数据.
## 推拉流鉴权规则
为了保护服务器的WVP默认开启推流鉴权目前不支持关闭此功能
### 推流规则
推流时需要携带推流鉴权的签名signsign=md5(pushKey),pushKey来自用户表每个用户会有一个不同的pushKey.
例如app=teststream=livepushKey=1000ip=192.168.1.4, port=10554 那么推流地址为:
```
rtsp://192.168.1.4:10554/test/live?sign=a9b7ba70783b617e9998dc4dd82eb3c5
```
支持推流时自定义播放鉴权Id参数名为callId此时sign=md5(callId_pushKey)
例如app=teststream=livepushKey=1000callId=12345678, ip=192.168.1.4, port=10554 那么推流地址为:
```
rtsp://192.168.1.4:10554/test/live?callId=12345678&sign=c8e6e01dde2d60c66dcea8d2498ffef1
```
### 播放规则
默认情况播放不需要鉴权但是如果推流时携带了callId那么播放时必须携带callId
例如app=teststream=live无callId, ip=192.168.1.4, port=10554 那么播放地址为:
```
rtsp://192.168.1.4:10554/test/live
```
例如app=teststream=livecallId=12345678, ip=192.168.1.4, port=10554 那么播放地址为:
```
rtsp://192.168.1.4:10554/test/live?callId=12345678
```

View File

@@ -1,2 +1,3 @@
<!-- 用户管理 -->
# 用户管理

View File

@@ -1,5 +1,7 @@
<!-- 关于本文档 -->
# 关于本文档
本文档开源在gitee上[https://gitee.com/pan648540858/wvp-pro-doc.git](https://gitee.com/pan648540858/wvp-pro-doc.git),如果文档出现任何错误或者不易理解的语句请大家提ISSUE帮助我及时更正。欢迎大家提交PR一起维护这份文档让更多的人可以使用到这个开源的视频平台。
本文档开源在gitee上[https://gitee.com/pan648540858/wvp-pro-doc.git](https://gitee.com/pan648540858/wvp-pro-doc.git)
,如果文档出现任何错误或者不易理解的语句请大家提ISSUE帮助我及时更正。欢迎大家提交PR一起维护这份文档让更多的人可以使用到这个开源的视频平台。

View File

@@ -1,6 +1,7 @@
# 原理图
## 使用ffmpeg测试语音对讲原理
```plantuml
@startuml
"FFMPEG" -> "ZLMediaKit": 推流到zlm
@@ -13,6 +14,7 @@
```
## 使用网页测试语音对讲原理
```plantuml
@startuml
"前端页面" -> "WVP-PRO": 请求推流地址

View File

@@ -1,2 +1,5 @@
# 免责声明
WVP-PRO自有代码使用宽松的MIT协议在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议
WVP-PRO自有代码使用宽松的MIT协议在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。
但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。
在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

@@ -1,50 +1,63 @@
<!-- 编译 -->
# 编译
WVP-PRO不只是实现了国标28181的协议本身也是一个完整的视频平台。所以对于新手来说你可能需要一些耐心来完成。遇到问题不要焦躁你可以
1. 百度
2. 如果身边有熟悉java的朋友可以咨询下朋友
3. 来群里901799015咨询群友
4. 向作者发送邮件648540858@qq.com
5. 作者远程支持(有偿)。
如果这些仍不能解决你的问题,那么你可能需要与作者我一起合作完成这个项目,解决你遇到的问题。
# 编译
WVP-PRO不只是实现了国标28181的协议本身也是一个完整的视频平台。所以对于新手来说你可能需要一些耐心来完成。遇到问题不要焦躁你可以
1. 百度
2. 加入星球体提问;[知识星球](https://t.zsxq.com/0d8VAD3Dm)
3. 向作者发送邮件648540858@qq.com,寻求技术支持(有偿);
WVP-PRO使用Spring boot开发maven管理依赖。对于熟悉spring开发的朋友是很容易进行编译部署以及运行的。
下面将提供一种通用方法方便大家运行项目。
## 1 服务介绍
| 服务 | 作用 | 是否必须 |
|----------------|------------------------------------------|-------------------------|
| WVP-PRO | 实现国标28181的信令以及视频平台相关的功能 | 是 |
| ZLMediaKit | 为WVP-PRO提供国标28181的媒体部分的实现以及各种视频流格式的分发支持 | 是 |
| 服务 | 作用 | 是否必须 |
|------------|------------------------------------------|------|
| WVP-PRO | 实现国标28181的信令以及视频平台相关的功能 | 是 |
| ZLMediaKit | 为WVP-PRO提供国标28181的媒体部分的实现以及各种视频流格式的分发支持 | 是 |
## 2 安装依赖
| 依赖 | 版本 | 用途 | 开发环境需要 | 生产环境需要 |
|--------|------------|-------------|--------|--------|
| jdk | >=1.8 | 运行与编译java代码 | 是 | 是 |
| maven | >=3.3 | 管理java代码依赖 | | |
| git || 下载/更新/提交代码 | 否 | 否 |
| nodejs || 编译于运行前端文件 | 否 | 否 |
| npm || 管理前端文件依赖 | 否 | 否 |
| 依赖 | 版本 | 用途 | 开发环境需要 | 生产环境需要 |
|--------|-------|-------------|--------|--------|
| jdk | >=1.8 | 运行与编译java代码 | | |
| maven | >=3.3 | 管理java代码依赖 | 否 | 否 |
| git | | 下载/更新/提交代码 | 否 | 否 |
| nodejs | | 编译于运行前端文件 | 否 | 否 |
| npm | | 管理前端文件依赖 | 否 | 否 |
如果你是一个新手建议你使用linux或者macOS平台。windows不推荐。
ubuntu环境以ubuntu 18为例
``` bash
apt-get install -y openjdk-11-jre git maven nodejs npm
```
centos环境,以centos 8为例
```bash
yum install -y java-1.8.0-openjdk.x86_64 git maven nodejs npm
```
window环境以windows10为例
```bash
这里不细说了,百度或者谷歌一搜一大把,基本都是下一步下一步,然后配置环境变量。
```
## 3 安装mysql以及redis
这里依然是参考网上教程,自行安装吧。
## 4 编译ZLMediaKit
参考ZLMediaKit[WIKI](https://github.com/ZLMediaKit/ZLMediaKit/wiki),如果需要使用语音对讲功能,请参考[zlm启用webrtc编译指南](https://github.com/ZLMediaKit/ZLMediaKit/wiki/zlm%E5%90%AF%E7%94%A8webrtc%E7%BC%96%E8%AF%91%E6%8C%87%E5%8D%97)开启zlm的webrtc功能。截取一下关键步骤
参考ZLMediaKit[WIKI](https://github.com/ZLMediaKit/ZLMediaKit/wiki)
,如果需要使用语音对讲功能,请参考[zlm启用webrtc编译指南](https://github.com/ZLMediaKit/ZLMediaKit/wiki/zlm%E5%90%AF%E7%94%A8webrtc%E7%BC%96%E8%AF%91%E6%8C%87%E5%8D%97)
开启zlm的webrtc功能。截取一下关键步骤
```bash
# 国内用户推荐从同步镜像网站gitee下载
git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit
@@ -52,42 +65,54 @@ cd ZLMediaKit
# 千万不要忘记执行这句命令
git submodule update --init
```
## 5 编译WVP-PRO
### 5.1 可以通过git克隆也可以在项目下载点击下载
![点击下载](_media/img_1.png)
![点击下载](_media/img_2.png)
从gitee克隆
```bash
git clone https://gitee.com/pan648540858/wvp-GB28181-pro.git
```
从github克隆
```bash
git clone https://github.com/648540858/wvp-GB28181-pro.git
```
### 5.2 编译前端页面
```shell script
cd wvp-GB28181-pro/web_src/
cd wvp-GB28181-pro/web/
npm --registry=https://registry.npmmirror.com install
npm run build
npm run build:prod
```
编译如果报错, 一般都是网络问题, 导致的依赖包下载失败
编译完成后在src/main/resources下出现static目录
**编译完成一般是这个样子,中间没有报红的错误信息**
![编译成功](_media/img.png)
### 5.3 生成可执行jar
```bash
cd wvp-GB28181-pro
mvn package
```
### 5.4 生成war
```bash
cd wvp-GB28181-pro
mvn package -P war
```
编译如果报错, 一般都是网络问题, 导致的依赖包下载失败
编译完成后在target目录下出现wvp-pro-***.jar/wvp-pro-***.war
编译完成后在target目录下出现 `wvp-pro-VERSION.jar` 和 `wvp-pro-VERSION.war` 文件
接下来[配置服务](./_content/introduction/config.md)

View File

@@ -1,5 +1,7 @@
<!-- 配置 -->
# 配置
对于首次测试或者新手同学我建议在局域网测试并且关闭服务器与客户机的防火墙测试。建议部署在linux进行测试。
```plantuml
@@ -8,93 +10,115 @@
"WVP-PRO" <-- "ZLMediaKit": Web Hook 接口
@enduml
```
WVP-PRO通过调用ZLMediaKit的RESTful接口实现对ZLMediaKit行为的控制; ZLMediaKit通过Web Hook 接口把消息通知WVP-PRO。通过这种方式实现了两者的互通。
对于最简单的配置你不需要修改ZLMediaKit的任何默认配置。你只需要在WVP-PRO中配置的ZLMediaKit信息即可
## 1 WVP配置文件位置
基于spring boot的开发方式配置文件的加载是很灵活的。默认在src/main/resources/application.yml部分配置项是可选你不需要全部配置在配置文件中
完全的配置说明可以参看all-application.yml。
完全的配置说明可以参看"src/main/resources/配置详情.yml"
### 1.1 默认加载配置文件方式
使用maven打包后的target里已经存在了配置文件默认加载配置文件为application.yml查看内容发现其中spring.profiles.active配置的内容将入配置的值为dev那么具体加载的配置文件就是application-dev.yml如果配置的值找不到对应的配置文件修改值为dev。
```shell
cd wvp-GB28181-pro/target
java -jar wvp-pro-*.jar
```
## 2 配置WVP-PRO
wvp支持多种数据库包括MysqlPostgresql金仓等配置任选一种即可。
### 2.1 数据库配置
#### 2.1.1 初始化数据库
#### 2.1.1 初始化数据库
首先使用创建数据库然后使用sql/初始化.sql初始化数据库如果是从旧版升级上来的使用升级sql更新。
#### 2.1.2 Mysql数据库配置
#### 2.1.2 Mysql数据库配置
数据库名称以wvp为例
```yaml
spring:
dynamic:
primary: master
datasource:
master:
type: com.zaxxer.hikari.HikariDataSource
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: root123
datasource:
type: com.zaxxer.hikari.HikariDataSource
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: root123
```
#### 2.1.3 Postgresql数据库配置
#### 2.1.3 Postgresql数据库配置
数据库名称以wvp为例
```yaml
spring:
dynamic:
primary: master
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password: 12345678
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password: 12345678
pagehelper:
helper-dialect: postgresql
```
#### 2.1.4 金仓数据库配置
#### 2.1.4 金仓数据库配置
数据库名称以wvp为例
```yaml
spring:
dynamic:
primary: master
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.kingbase8.Driver
url: jdbc:kingbase8://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=utf8
username: root
password: 12345678
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.kingbase8.Driver
url: jdbc:kingbase8://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=utf8
username: root
password: 12345678
pagehelper:
helper-dialect: postgresql
```
### 2.2 Redis数据库配置
配置wvp中的redis连接信息建议wvp自己单独使用一个db。
### 2.3 配置服务启动端口(可直接使用默认配置)
```yaml
# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
server:
port: 18080
port: 18080
```
### 2.4 配置28181相关信息可直接使用默认配置
```yaml
# 作为28181服务器的配置
sip:
# [可选] 28181服务监听的端口
port: 5060
# 根据国标6.1.2中规定domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码由省级、市级、区级、基层编号组成参照GB/T 2260-2007
# 后两位为行业编码定义参照附录D.3
# 3701020049标识山东济南历下区 信息行业接入
# [可选]
domain: 3402000000
# [可选]
id: 34020000002000000001
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
password: 12345678
# [可选] 28181服务监听的端口
port: 5060
# 根据国标6.1.2中规定domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码由省级、市级、区级、基层编号组成参照GB/T 2260-2007
# 后两位为行业编码定义参照附录D.3
# 3701020049标识山东济南历下区 信息行业接入
# [可选]
domain: 3402000000
# [可选]
id: 34020000002000000001
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
password: 12345678
```
### 2.5 配置ZLMediaKit连接信息
```yaml
#zlm 默认服务器配置
media:
@@ -118,7 +142,9 @@ media:
# [可选] 国标级联在此范围内选择端口发送媒体流,
send-port-range: 40000,40300 # 端口范围
```
### 2.4 个性化定制信息配置
### 2.4 策略配置
```yaml
# [根据业务需求配置]
user-settings:
@@ -133,7 +159,8 @@ user-settings:
# 国标点播 按需拉流, true有人观看拉流无人观看释放 false拉起后不自动释放
stream-on-demand: true
```
更多完整的配置信息参考all-application.yml文件需要那个配置项复制到正在使用的配置文件中对应的文件即可。
更多完整的配置信息参考"src/main/resources/配置详情.yml"文件,需要那个配置项,复制到正在使用的配置文件中对应的文件即可。
如果配置信息无误你可以启动zlm再启动wvp来测试了启动成功的话你可以在wvp的日志下看到zlm已连接的提示。
接下来[部署到服务器](./_content/introduction/deployment.md) 如果你只是本地运行直接在本地运行即可。

View File

@@ -1,47 +1,51 @@
<!-- 部署 -->
# 部署
**请仔细阅读以下内容**
1. WVP-PRO与ZLM支持分开部署;
2. 需要开放的端口
| 服务 | 端口 | 类型 | 必选 |
|-----|:-------------------------|-------------|-------|
| wvp | server.port | tcp | 是 |
| wvp | sip.port | udp and tcp | 是 |
| zlm | http.port | tcp | 是 |
| zlm | http.sslport | tcp | 否 |
| zlm | rtmp.port | tcp | 否 |
| zlm | rtmp.sslport | tcp | 否 |
| zlm | rtsp.port | udp and tcp | 否 |
| zlm | rtsp.sslport | udp and tcp | 否 |
| zlm | rtp_proxy.port | udp and tcp | 单端口开放 |
| zlm | rtp.port-range(在wvp中配置) | udp and tcp | 多端口开放 |
| 服务 | 端口 | 类型 | 必选 |
|-----|:-------------------------|-------------|-------|
| wvp | server.port | tcp | 是 |
| wvp | sip.port | udp and tcp | 是 |
| zlm | http.port | tcp | 是 |
| zlm | http.sslport | tcp | 否 |
| zlm | rtmp.port | tcp | 否 |
| zlm | rtmp.sslport | tcp | 否 |
| zlm | rtsp.port | udp and tcp | 否 |
| zlm | rtsp.sslport | udp and tcp | 否 |
| zlm | rtp_proxy.port | udp and tcp | 单端口开放 |
| zlm | rtp.port-range(在wvp中配置) | udp and tcp | 多端口开放 |
3. 测试环境部署建议所有服务部署在一台主机,关闭防火墙,减少因网络出现问题的可能;
4. 生产环境按需开放端口但是建议修改默认端口尤其是5060端口易受到攻击;
5. zlm使用docker部署的情况请使用host模式或者端口映射一致比如映射5060,应将外部端口也映射为5060端口;
6. zlm与wvp会保持高频率的通信所以不要去将wvp与zlm分属在两个网络比如wvp在内网zlm却在公网的情况。
7. 启动服务以linux为例
**启动WVP-PRO**
**启动WVP-PRO**
```shell
nohup java -jar wvp-pro-*.jar &
```
**war包**
下载Tomcat后将war包放入webapps中启动Tomcat以解压war包停止Tomcat后删除ROOT目录以及war包将解压后的war包目录重命名为ROOT将配置文件中的Server.port配置为与Tomcat端口一致
然后启动Tomcat。
**启动ZLM**
```shell
nohup ./MediaServer -d -m 3 &
```
### 前后端分离部署
前后端部署目前在最新的版本已经支持请使用3月15日之后的版本部署
前端编译后的文件在`src/main/resources/static`中,将此目录下的文件部署。
WVP默认开启全部接口支持跨域。部署前端文件到WEB容器并将访问的地址设置为WVP的地址即可。
**配置前端服务器**
1.`src/main/resources/static/static/js/config.js`下配置服务器的地址也就是wvp服务的地址
```javascript
window.baseUrl = "http://xxx.com:18080"
```
`这里的地址是需要客户电脑能访问到的,因为请求是客户端电脑发起,与代理不同`
[接入设备](./_content/ability/device.md)
### 前后端分离部署
前端基于 [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template/blob/master/README-zh.md) 构建, 参考这儿即可。
### 默认账号和密码
部署完毕后,可以通过访问 ip加端口的方式访问 WVP WVP的默认登录账号和密码均为 admin。

View File

@@ -1,12 +1,18 @@
<!-- 反馈bug -->
# 反馈bug
代码是在不断的完善的不断修改会修复旧的问题也有可能引入新的问题所以遇到BUG是很正常的一件事。所以遇到问题不要烦燥咱们就事论事就好了。
## 如何反馈
1. 在知识星球提问。
2. 更新代码,很可能你遇到问题别人已经更早的遇到了,或者是作者自己发现了,已经解决了,所以你可以更新代码再次进行测试;
3. 可以在github提ISSUE我几乎每天都会去看issue你的问题我会尽快给予答复;
> 有偿支持可以给我发邮件, 648540858@qq.com
## 社群
[![社群](../../_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm)
> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。

View File

@@ -1,7 +1,11 @@
<!-- 参与开发 -->
# 参与到开发中来
非常欢迎有兴趣的小伙伴一起来维护这个项目
## 与开发有关的信息
- 开发语言后端java + 前端vue
- jdk版本 1.8
- 作者自用开发ide jetbrains intellij idea
@@ -9,7 +13,9 @@
- 后端使用Spring boot框架开发
- 项目大量使用了异步操作;
- 跟代码学流程需要参考28181文档只看代码你会很懵的
- 必须学会[抓包](_content/skill/tcpdump.md),这是必须的
- 必须学会[抓包](_content/skill/tcpdump.md),这是必须的
## 提交代码
大家可以通过fork项目的方式提交自己的代码然后提交PR我来合并到主线。提交代码的过程中我们需要遵循“**阿里编码规约**”,现有代码也有很多代码没有做到,但是我们在朝这个方向努力。
大家可以通过fork项目的方式提交自己的代码然后提交PR我来合并到主线。提交代码的过程中我们需要遵循“**阿里编码规约**
”,现有代码也有很多代码没有做到,但是我们在朝这个方向努力。

View File

@@ -1,6 +1,9 @@
<!-- 点播错误 -->
# 点播错误
排查点播错误你首先要清楚[点播的基本流程](_content/theory/play.md),一般的流程如下:
```plantuml
@startuml
"WEB用户" -> "WVP-PRO": 1. 发起点播请求
@@ -15,11 +18,16 @@
"设备" --> "WVP-PRO": 10 200OK
@enduml
```
针对几种常见的错误,我们来分析一下,也方便大家对号入座解决常见的问题
## 点播收到错误码
这个错误一般表现为点击"播放"按钮后很快得到一个错误。
1. **400错误码**
出现400错误玛时一般是这样的流程是这样的
出现400错误玛时一般是这样的流程是这样的
```plantuml
@startuml
"WEB用户" -> "WVP-PRO": 1. 发起点播请求
@@ -27,30 +35,39 @@
"设备" --> "WVP-PRO": 3. 400错误
@enduml
```
此时通常是设备认为WVP发送了错误的消息给它它认为消息不全或者错误所以直接返回400错误此时我们需要[抓包](_content/skill/tcpdump.md)来分析是否缺失了内容也可以直接联系对方询问为什么返回了400。
WVP不能保证兼容所有的设备有些实现不规范的设备可能在对接时就会出现上述问题你可以联系作者帮忙对接。
2. **500错误码**
500或者大于500小于600的错误码一般多是设备内部出了问题解决方式有两个第一种直接联系设备/平台客服寻求解决第二种如果你有确定可以对接这个设备的平台那么可以把对接这个平台的抓包和对接wvp的抓包同时发送给我我来尝试解决。
此时通常是设备认为WVP发送了错误的消息给它它认为消息不全或者错误所以直接返回400错误此时我们需要[抓包](_content/skill/tcpdump.md)
来分析是否缺失了内容也可以直接联系对方询问为什么返回了400。
WVP不能保证兼容所有的设备有些实现不规范的设备可能在对接时就会出现上述问题你可以联系作者帮忙对接。
2. **500错误码**
500或者大于500小于600的错误码一般多是设备内部出了问题解决方式有两个第一种直接联系设备/平台客服寻求解决第二种如果你有确定可以对接这个设备的平台那么可以把对接这个平台的抓包和对接wvp的抓包同时发送给我我来尝试解决。
## 点播超时
点播超时的情况大致分为两种:点播超时和收流超时
1. **点播超时**
点播超时错误一般为信令的超时,比如长时间为收到对方的回复,可能出现在流程中 “3. 200OK(携带SDP消息体)”这个位置,即我们发送点播消息,但是设备没有回复,可能的原因:
点播超时错误一般为信令的超时,比如长时间为收到对方的回复,可能出现在流程中 “3. 200OK(携带SDP消息体)
”这个位置,即我们发送点播消息,但是设备没有回复,可能的原因:
> 1. 设备内部错误,未能回复消息
> 2. 网络原因消息未到到达设备
> 2. 网络原因消息未到到达设备
大部分时候是原因2所以遇到这个错误我们首先要排查我们我的网路如果你是公网部署那么也可能时心跳周期太长导致的路由NAT失效WVP的消息无法通道原来的IP端口号发送给设备。
2. **收流超时**
收流超时可能发生在流程中的5和6,可能的原因有:
> 1. 设备发送了流但是发送到了错误的ip和端口上而这个信息是在invite消息的sdp中指定的就是流程2Invite(携带SDP消息体)中而这个错误很可能来自你的配置错误比如你设置了127.0.0.1导致设备网127.0.0.1上发流或者是你WVP在公网但是你给设备了一个内网ip导致设备无法把流发送过来
收流超时可能发生在流程中的5和6,可能的原因有:
> 1. 设备发送了流但是发送到了错误的ip和端口上而这个信息是在invite消息的sdp中指定的就是流程2Invite(携带SDP消息体)
而这个错误很可能来自你的配置错误比如你设置了127.0.0.1导致设备网127.0.0.1上发流或者是你WVP在公网但是你给设备了一个内网ip导致设备无法把流发送过来
> 2. 设备内部错误未发送流;
> 2. 设备发送了流,但是流无法识别,可能存在于流不规范和网络很差的情况下;
> 3. 设备发送了流zlm也收到了但是zlm无法通过hook通知到wvp此时原因是你可以检查zlm的配置文件中的hook配置看看是否无法从zlm连接到wvp
> 4. 设备发送了流但是开启SSRC校验设备的流不够规范采用错误的ssrc导致zlm选择丢弃
针对这些可能的错误原因我建议的排查顺序:
针对这些可能的错误原因我建议的排查顺序:
- 关闭ssrc校验
- 查看zlm配置的hook是否可以连接到zlm
- 查看zlm日志是否有流注册

View File

@@ -1,8 +1,10 @@
<!-- 设备注册不上来的解决办法 -->
# 设备注册不上来的解决办法
一般的原因有两个
1. 信息填写错误,比如密码错误;
2. 网络不通导致注册消息无法发送到WVP
# 设备注册不上来的解决办法
一般的原因有两个
1. 信息填写错误,比如密码错误;
2. 网络不通导致注册消息无法发送到WVP
遇到问题首先仔细校验填写信息,例如海康可能需要勾选鉴权才可以输入密码。网络问题请自行测试。

View File

@@ -1,17 +1,19 @@
<!-- 启动时报错 -->
# 启动时报错
启动时的报错大部分时候是因为你的配置有问题比如mysql没连接上redis没连接上18080/15060端口占用了这些都会导致启动是报错修改配置配置之后都可以解决
下面我整理的一些常见的错误,大家可以先对号入座的简单排查下。
> **常见错误**
> **常见错误**
![_media/img.png](_media/img.png)
**错误原因:** redis配置错误可能原因 redis未启动/ip错误/端口错误/网络不通
**错误原因:** redis配置错误可能原因 redis未启动/ip错误/端口错误/网络不通
---
![_media/img_1.png](_media/img_1.png)
**错误原因:** redis配置错误可能原因 密码错误
---
![_media/img_2.png](_media/img_2.png)
**错误原因:** mysql配置错误可能原因 mysql未启动/ip错误/端口错误/网络不通
**错误原因:** mysql配置错误可能原因 mysql未启动/ip错误/端口错误/网络不通
---
![_media/img_3.png](_media/img_3.png)
**错误原因:** mysql配置错误可能原因 用户名/密码错误

View File

@@ -1,15 +1,25 @@
<!-- 抓包 -->
# 抓包
如果说对于网络编程有什么工具是必会的我觉得抓包肯定是其中之一了。作为GB/T 28181调试过程中最重要的手段我觉得如果你真对他有兴趣或者系统遇到问题可以最快的得到解决那么抓包你就一定要学会了。
如果说对于网络编程有什么工具是必会的我觉得抓包肯定是其中之一了。作为GB/T
28181调试过程中最重要的手段我觉得如果你真对他有兴趣或者系统遇到问题可以最快的得到解决那么抓包你就一定要学会了。
## 抓包工具的选择
### 1. Wireshark
在具备图形界面的系统上比如windowslinux发行版ubuntuopensuse等我一般直接使用Wireshark直接进行抓包也方便进行内容的查看。
### 2. Tcpdump
在使用命令行的系统比如linux服务器我一般使用Tcpdump进行抓包无需额外安装系统一般自带抓包的到的文件可以使用Wireshark打开在图形界面下方便查看内容。
## 工具安装
Wireshark的安装很简单根据提示一步步点击就好了在linux需要解决权限的问题如果和我一样使用图形界面的linux发行版的话可以参看如下步骤; windows的小伙伴直接略过即可
Wireshark的安装很简单根据提示一步步点击就好了在linux需要解决权限的问题如果和我一样使用图形界面的linux发行版的话可以参看如下步骤;
windows的小伙伴直接略过即可
```shell
# 1. 添加wireshark用户组
sudo groupadd wireshark
@@ -20,43 +30,65 @@ sudo chmod 4755 /usr/bin/dumpcap
# 4. 将需要使用的用户名加入wireshark用户组
sudo gpasswd -a $USER wireshark
```
tcpdump一般linux都是自带无需安装可以这样验证;显示版本信息即是已安装
```shell
tcpdump --version
```
## 开始抓包
### 使用Wireshark
在28181中我一般只关注sip包和rtp包所以我一般是直接过滤sip和rtp可以输入框输入 `sip or rtp`这样即可如果设备来源比较多还可以加上ip和端口号的过滤`(sip or rtp )and ip.addr==192.168.1.3 and udp.port==5060`
在28181中我一般只关注sip包和rtp包所以我一般是直接过滤sip和rtp可以输入框输入 `sip or rtp`这样即可如果设备来源比较多还可以加上ip和端口号的过滤
`(sip or rtp )and ip.addr==192.168.1.3 and udp.port==5060`
详细的过滤规则可以自行百度,我可以提供一些常用的给大家参考
![img.png](_media/img.png)
**只过滤SIP**
```shell
sip
```
**只获取rtp数据**
```shell
rtp
```
**默认方式:**
```shell
sip or rtp
```
**过滤IP**
```shell
sip and ip.addr==192.168.1.3
```
**过滤端口:**
```shell
sip and udp.port==5060
```
输入命令开启抓包后此时可以进行操作比如点播录像回访等操作完成回到Wireshark点击红色的停止即可需要保存文件可以点击`文件->导出特定分组`导出过滤后的数据,也可以直接`文件->另存为`保存未过滤的数据。
输入命令开启抓包后此时可以进行操作比如点播录像回访等操作完成回到Wireshark点击红色的停止即可需要保存文件可以点击
`文件->导出特定分组`导出过滤后的数据,也可以直接`文件->另存为`保存未过滤的数据。
### 使用tcpdump
对于服务器抓包,为了得到足够完整的数据,我一般会要求直接抓取网卡数据而不过滤,如下:
抓取网卡首先需要获取网卡名在linux我一般使用`ip addr`获取网卡信息,如下所示:
![img_1.png](_media/img_1.png)
```shell
sudo tcpdump -i wlp3s0 -w demo.pcap
```
![img_2.png](_media/img_2.png)
命令行会停留在这个位置,此时可以进行操作,比如点播,录像回放等,操作完成回到命令行使用`Ctrl+C`结束命令行在当前目录下得到demo.pcap将这个文件下载到图形界面操作系统里即可使用Wireshark查看了
命令行会停留在这个位置,此时可以进行操作,比如点播,录像回放等,操作完成回到命令行使用`Ctrl+C`
结束命令行在当前目录下得到demo.pcap将这个文件下载到图形界面操作系统里即可使用Wireshark查看了
更多的操作可以参考: [https://www.cnblogs.com/jiujuan/p/9017495.html](https://www.cnblogs.com/jiujuan/p/9017495.html)

View File

@@ -1,6 +1,7 @@
<!-- 点播流程 -->
# 点播流程
> 以下为WVP-PRO级联语音喊话流程。
```plantuml
@@ -31,8 +32,8 @@
@enduml
```
## 注册流程描述如下:
## 注册流程描述如下:
1. 用户从网页或调用接口发起点播请求;
2. WVP-PRO向摄像机发送Invite消息,消息头域中携带 Subject字段,表明点播的视频源ID、发送方媒体流序列号、ZLMediaKit接收流使用的IP、端口号、
接收端媒体流序列号等参数,SDP消息体中 s字段为“Play”代表实时点播y字段描述SSRC值,f字段描述媒体参数。

View File

@@ -1,14 +0,0 @@
<!-- 通道的树形结构 -->
# 通道的树形结构
国标28181规定了两种组织设备树的方式
1. **行政区划**
行政区划模式下主要是以行政区划作为目录节点例如:河北省->邯郸市->广平县
![_media/img_8.png](_media/img_8.png)
2. **业务分组**
业务分组主要自定义的目录树的一种组织形式,但是对定义的目录的国标编号有一定的要求。
第一级别需要是业务分组类型即国标编码中的11、12、13是215,例如65010200002150000001
业务分组下是虚拟组织即国标编码中的11、12、13是216,例如65010200002160000002。
虚拟组织下不可是业务分组,虚拟组织下可以继续添加虚拟组织。
![_media/img_9.png](_media/img_9.png)

View File

@@ -1,25 +1,29 @@
<!-- 统一编码规则 -->
# 统一编码规则
## D.1 编码规则 A
>&emsp;&emsp;编码规则 A 由中心编码(8位)、行业编码(2位)、类型编码(3位)和序号(7位)四个码段共20位十
>进制数字字符构成,即系统编码 =中心编码 + 行业编码 + 类型编码 + 序号。
>&emsp;&emsp;编码规则 A 的详细说明见表 D.1。其中,中心编码指用户或设备所归属的监控中心编码,按照监控中心所在地的行政区划代码确定,
> 当不是基层单位时空余位为0。行政区划代码采用 GB/T2260— 2007规定的行政区划代码表示。行业编码指用户或设备所归属的行业,行业编码对照表见 D.3。
> 类型编码指定了设备或用户的具体类型,其中的前端设备包含公安系统和非公安系统的前端设备,终端用 户包含公安系统和非公安系统的终端用户。
> &emsp;&emsp;编码规则 A 由中心编码(8位)、行业编码(2位)、类型编码(3位)和序号(7位)四个码段共20位十
> 进制数字字符构成,即系统编码 =中心编码 + 行业编码 + 类型编码 + 序号。
> &emsp;&emsp;编码规则 A 的详细说明见表 D.1。其中,中心编码指用户或设备所归属的监控中心的编码,按照监控中心所在地的行政区划代码确定,
> 当不是基层单位时空余位为0。行政区划代码采用 GB/T2260— 2007规定的行政区划代码表示。行业编码是指用户或设备所归属的行业,行业编码对照表见
> D.3。
> 类型编码指定了设备或用户的具体类型,其中的前端设备包含公安系统和非公安系统的前端设备,终端用
> 户包含公安系统和非公安系统的终端用户。
![img_7.png](_media/img_7.png)
![img_1.png](_media/img_1.png)
![img_2.png](_media/img_2.png)
![img_2.png](_media/img_2.png)
## D.2 编码规则 B
>&emsp;&emsp;编码规则 B由中心编码(8位)、行业编码(2位)、序号(4位)和类型编码(2位)四个码段构成,即系
>统编码 =中心编码 + 行业编码 +序号+类型编码。编码规则 B的详细说明见表 D.2。
> &emsp;&emsp;编码规则 B由中心编码(8位)、行业编码(2位)、序号(4位)和类型编码(2位)四个码段构成,即系
> 统编码 =中心编码 + 行业编码 +序号+类型编码。编码规则 B的详细说明见表 D.2。
![img_3.png](_media/img_3.png)
![img_4.png](_media/img_4.png)
## D.3 行业编码对照表
>&emsp;&emsp;行业编码对照表见表 D.3。
> &emsp;&emsp;行业编码对照表见表 D.3。
![img_5.png](_media/img_5.png)
![img_6.png](_media/img_6.png)

View File

@@ -1,6 +1,7 @@
<!-- 点播流程 -->
# 点播流程
> 以下为WVP-PRO点播流程。点播成功前的任何一个环节出现问题都可能出现点播超时这也是排查点播超时的依据。
```plantuml
@@ -18,11 +19,11 @@
@enduml
```
## 注册流程描述如下:
## 注册流程描述如下:
1. 用户从网页或调用接口发起点播请求;
1. 用户从网页或调用接口发起点播请求;
2. WVP-PRO向摄像机发送Invite消息,消息头域中携带 Subject字段,表明点播的视频源ID、发送方媒体流序列号、ZLMediaKit接收流使用的IP、端口号、
接收端媒体流序列号等参数,SDP消息体中 s字段为“Play”代表实时点播y字段描述SSRC值,f字段描述媒体参数。
接收端媒体流序列号等参数,SDP消息体中 s字段为“Play”代表实时点播y字段描述SSRC值,f字段描述媒体参数。
3. 摄像机向WVP-PRO回复200OK消息体中描述了媒体流发送者发送媒体流的IP、端口、媒体格式、SSRC字段等内容。
4. WVP-PRO向设备回复Ack 会话建立成功。
5. 设备向ZLMediaKit发送实时流。

View File

@@ -1,6 +1,7 @@
<!-- 注册流程 -->
# 注册流程
WVP-PRO目前仅支持国标中描述的基本注册流程也是最常用的
> 基本注册即采用IETFRFC3261规定的基于数字摘要的挑战应答式安全技术进行注册.
@@ -13,9 +14,8 @@ WVP-PRO目前仅支持国标中描述的基本注册流程也是最常用的
@enduml
```
> 注册流程描述如下:
> 1. 摄像机向WVP-PRO服务器发送 Register请求;
> 注册流程描述如下:
> 1. 摄像机向WVP-PRO服务器发送 Register请求;
> 2. WVP-PRO向摄像机发送响应401,并在响应的消息头 WWW_Authenticate字段中给出适合摄像机的认证体制和参数;
> 3. 摄像机重新向WVP-PRO发送 Register请求,在请求的 Authorization字段给出信任书, 包含认证信息;
> 4. WVP-PRO对请求进行验证,如果检查出 摄像机身份合法,向摄像机发送成功响应 200OK,如果身份不合法则发送拒绝服务应答。

View File

@@ -5,8 +5,8 @@
> 开箱即用的28181协议视频平台。
- 基于GB/T28181-2016标准信令实现兼容GB/T28181-2011。
- 自带完整前端页面,开箱即用。
- 基于GB/T28181-2016标准信令实现兼容GB/T28181-2011。
- 自带完整前端页面,开箱即用。
- 完全开源且使用MIT许可协议。可以在保留版权信息的基础上商用。
[GitHub](https://github.com/648540858/wvp-GB28181-pro)

BIN
doc/_media/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 469 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
doc/_media/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
doc/_media/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
doc/_media/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
doc/_media/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
doc/_media/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

BIN
doc/_media/log.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

View File

@@ -1,34 +1,32 @@
<!-- 侧边栏 -->
* **编译与部署**
* [编译](_content/introduction/compile.md)
* [配置](_content/introduction/config.md)
* [部署](_content/introduction/deployment.md)
* [编译](_content/introduction/compile.md)
* [配置](_content/introduction/config.md)
* [部署](_content/introduction/deployment.md)
* **功能与使用**
* [接入设备](_content/ability/device.md)
* [设备使用](_content/ability/device_use.md)
* [国标级联](_content/ability/cascade2.md)
* [推流列表](_content/ability/push.md)
* [拉流代理](_content/ability/proxy.md)
* [电子地图](_content/ability/gis.md)
* [节点管理](_content/ability/node_manger.md)
* [云端录像](_content/ability/cloud_record.md)
* [不间断录像](_content/ability/continuous_recording.md)
* [语音对讲](_content/ability/continuous_broadcast.md)
* [接入设备](_content/ability/device.md)
* [国标设备](_content/ability/device_use.md)
* [推流列表](_content/ability/push.md)
* [拉流代理](_content/ability/proxy.md)
* [云端录像](_content/ability/cloud_record.md)
* [节点管理](_content/ability/node_manager.md)
* [通道管理](_content/ability/channel.md)
* [国标级联](_content/ability/cascade2.md)
* **流程与原理**
* [统一编码规则](_content/theory/code.md)
* [树形结构](_content/theory/channel_tree.md)
* [注册流程](_content/theory/register.md)
* [点播流程](_content/theory/play.md)
* [级联语音喊话流程](_content/theory/broadcast_cascade.md)
* [统一编码规则](_content/theory/code.md)
* [注册流程](_content/theory/register.md)
* [点播流程](_content/theory/play.md)
* [级联语音喊话流程](_content/theory/broadcast_cascade.md)
* [语音对讲](_content/ability/continuous_broadcast.md)
* **必备技巧**
* [抓包](_content/skill/tcpdump.md)
* [抓包](_content/skill/tcpdump.md)
* **常见问答**
- [如何反馈BUG](_content/qa/bug.md)
- [如何参与开发](_content/qa/development.md)
- [启动报错的解决办法](_content/qa/start_error.md)
- [设备注册不上来的解决办法](_content/qa/regiser_error.md)
- [点播超时/报错的解决办法](_content/qa/play_error.md)
- [如何反馈BUG](_content/qa/bug.md)
- [如何参与开发](_content/qa/development.md)
- [启动报错的解决办法](_content/qa/start_error.md)
- [设备注册不上来的解决办法](_content/qa/regiser_error.md)
- [点播超时/报错的解决办法](_content/qa/play_error.md)
* [**免责声明**](_content/disclaimers.md)
* [**关于本文档**](_content/about_doc.md)

View File

@@ -1,59 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WVP-PRO文档</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="icon" href="_media/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="./lib/css/vue.css">
<!-- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/dark.css">-->
<style>
.cover{
background: linear-gradient(to left bottom, hsl(82, 100%, 85%) 0%,hsl(199, 100%, 85%) 100%) !important;
}
</style>
<meta charset="UTF-8">
<title>WVP-PRO文档</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="icon" href="_media/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="./lib/css/vue.css">
<!-- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/dark.css">-->
<style>
.cover {
background: linear-gradient(to left bottom, hsl(82, 100%, 85%) 0%, hsl(199, 100%, 85%) 100%) !important;
}
</style>
</head>
<body>
<div id="app">加载中</div>
<script>
<div id="app">加载中</div>
<script>
window.$docsify = {
name: 'WVP-RPO使用文档',
repo: 'https://github.com/648540858/wvp-GB28181-pro',
loadSidebar: true, // 开启侧边栏
loadNavbar: true, // 开启导航栏
coverpage: true, // 开启封面
name: 'WVP-RPO使用文档',
repo: 'https://github.com/648540858/wvp-GB28181-pro',
loadSidebar: true, // 开启侧边栏
loadNavbar: true, // 开启导航栏
coverpage: true, // 开启封面
subMaxLevel: 3,
plantuml: {
skin: 'default',
},
search: {
maxAge: 86400000, // 过期时间,单位毫秒,默认一天
paths: 'auto', // or 'auto'
placeholder: '搜索',
noData: '找不到结果',
// 搜索标题的最大层级, 1 - 6
depth: 4,
hideOtherSidebarContent: false, // 是否隐藏其他侧边栏内容
},
copyCode: {
buttonText : '复制',
errorText : '错误',
successText: '已复制'
},
// disqus: 'shortname'
subMaxLevel: 3,
plantuml: {
skin: 'default',
},
search: {
maxAge: 86400000, // 过期时间,单位毫秒,默认一天
paths: 'auto', // or 'auto'
placeholder: '搜索',
noData: '找不到结果',
// 搜索标题的最大层级, 1 - 6
depth: 4,
hideOtherSidebarContent: false, // 是否隐藏其他侧边栏内容
},
copyCode: {
buttonText: '复制',
errorText: '错误',
successText: '已复制'
},
// disqus: 'shortname'
}
</script>
<!-- Docsify v4 -->
<script src="./lib/js/docsify@4.js"></script>
<script src="./lib/js/docsify-plantuml.min.js"></script>
<script src="./lib/js/search.min.js"></script>
<script src="./lib/js/zoom-image.min.js"></script>
<script src="./lib/js/docsify-copy-code.min.js"></script>
</script>
<!-- Docsify v4 -->
<script src="./lib/js/docsify@4.js"></script>
<script src="./lib/js/docsify-plantuml.min.js"></script>
<script src="./lib/js/search.min.js"></script>
<script src="./lib/js/zoom-image.min.js"></script>
<script src="./lib/js/docsify-copy-code.min.js"></script>
</script>
</script>
<!-- <script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/disqus.min.js"></script>-->
</body>
</html>

45
docker/build.sh Executable file
View File

@@ -0,0 +1,45 @@
#/bin/bash
set -e
version=2.7.3
git clone https://gitee.com/pan648540858/wvp-GB28181-pro.git
cd wvp-GB28181-pro/web_src && \
npm install && \
npm run build
cd ../../
mkdir -p ./nginx/dist
cp -r wvp-GB28181-pro/src/main/resources/static/* ./nginx/dist
echo "构建ZLM容器"
cd ./media/
chmod +x ./build.sh
./build.sh
cd ../
echo "构建数据库容器"
cd ./mysql/
chmod +x ./build.sh
./build.sh
cd ../
echo "构建Redis容器"
cd ./redis/
chmod +x ./build.sh
./build.sh
cd ../
echo "构建WVP容器"
cd ./wvp/
chmod +x ./build.sh
./build.sh
cd ../
echo "构建Nginx容器"
cd ./nginx/
chmod +x ./build.sh
./build.sh
cd ../
./push.sh

View File

@@ -1,49 +1,125 @@
version: '3'
services:
redis:
image: redis
restart: always
volumes:
- ./redis/redis.conf:/etc/redis/redis_default.conf
- ./redis/data/:/data
environment:
TZ: "Asia/Shanghai"
command: redis-server /etc/redis/redis_default.conf --appendonly yes
wvp:
build:
context: ./wvp
args:
gitUrl: "https://gitee.com/pan648540858"
zlmGitUrl: "https://gitee.com/xia-chu/ZLMediaKit"
restart: always
polaris-redis:
image: polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-redis:latest
restart: unless-stopped
healthcheck:
test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
interval: 15s
timeout: 5s
retries: 10
start_period: 10s
networks:
- media-net
ports:
- "5060:5060"
- "5060:5060/udp"
- "18080:18080"
- "80:80"
- "10000:10000/tcp"
- "10000:10000/udp"
- "30000-30500:30000-30500/tcp"
- "30000-30500:30000-30500/udp"
- 6379:6379
volumes:
- ./video:/opt/media/www/record/
- ./logs/wvp:/opt/wvp/logs/
- ./logs/assist:/opt/assist/logs/
- ./logs/media:/opt/media/log/
- ./redis/conf/redis.conf:/opt/polaris/redis/redis.conf
- ./volumes/redis/data/:/data
environment:
TZ: "Asia/Shanghai"
# [必须修改] 本机的IP
WVP_HOST: 172.18.0.61
WVP_PWD: aseqw_+hiy123
WVP_DOMAIN: 6101130049
WVP_ID: 61011300490000000001
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_DB: 6
REDIS_PWD: root
ASSIST_JVM_CONFIG: -Xms128m -Xmx256m
WVP_JVM_CONFIG: -Xms128m -Xmx256m
ASSIST_CONFIG:
WVP_CONFIG:
command: redis-server /opt/polaris/redis/redis.conf --appendonly yes
polaris-mysql:
image: polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-mysql:latest
restart: unless-stopped
healthcheck:
test: [ "CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/3306" ]
interval: 15s
timeout: 5s
retries: 10
start_period: 10s
networks:
- media-net
environment:
MYSQL_DATABASE: wvp
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: root
MYSQL_PASSWORD: root
TZ: Asia/Shanghai
ports:
- 3306:3306
volumes:
- ./mysql/conf:/etc/mysql/conf.d
- ./logs/mysql:/logs
- ./volumes/mysql/data:/var/lib/mysql
command: [
'mysqld',
'--default-authentication-plugin=mysql_native_password',
'--innodb-buffer-pool-size=80M',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--default-time-zone=+8:00',
'--lower-case-table-names=1'
]
polaris-media:
image: polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-media:latest
restart: always
networks:
- media-net
ports:
- "10935:10935"
- "5540:5540"
- "6080:6080"
volumes:
- ./volumes/video:/opt/media/www/record/
- ./logs/media:/opt/media/log/
polaris-wvp:
image: polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-wvp:latest
restart: always
networks:
- media-net
ports:
- "18978:18978"
- "8116:8116/udp"
- "8116:8116/tcp"
depends_on:
- redis
- polaris-redis
- polaris-mysql
- polaris-media
links:
- polaris-redis
- polaris-mysql
- polaris-media
volumes:
- ./wvp/wvp/:/opt/wvp/wvp/
- ./logs/wvp:/opt/wvp/logs/
environment:
TZ: "Asia/Shanghai"
# 本机的IP
SIP_HOST: 127.0.0.1
STREAM_HOST: 127.0.0.1
ZLM_HOST: polaris-media
ZLM_PORT: 6080
ZLM_SERCERT: su6TiedN2rVAmBbIDX0aa0QTiBJLBdcf
REDIS_HOST: polaris-redis
REDIS_PORT: 6379
DATABASE_HOST: polaris-mysql
DATABASE_PORT: 3306
DATABASE_USER: wvp
DATABASE_PASSWORD: wvp
# 前端跨域配置nginx容器所在物理机IP
NGINX_HOST: http://127.0.0.1:8080
polaris-nginx:
image: polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-nginx:latest
ports:
- "8080:8080"
depends_on:
- polaris-wvp
links:
- polaris-wvp
environment:
WVP_HOST: polaris-wvp
WVP_PORT: 18978
volumes:
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf
- ./logs/nginx:/var/log/nginx
networks:
- media-net
networks:
media-net:
driver: bridge

5
docker/docker-upgrade.sh Executable file
View File

@@ -0,0 +1,5 @@
#/bin/bash
set -e
docker compose down
docker compose up -d --remove-orphans

91
docker/media/Dockerfile Normal file
View File

@@ -0,0 +1,91 @@
FROM ubuntu:20.04 AS build
#shell,rtmp,rtsp,rtsps,http,rtp
EXPOSE 10935/tcp
EXPOSE 5540/tcp
EXPOSE 6080/tcp
EXPOSE 10000/udp
EXPOSE 10000/tcp
EXPOSE 8000/udp
EXPOSE 8000/tcp
EXPOSE 9000/udp
# ADD sources.list /etc/apt/sources.list
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" \
apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
curl \
vim \
wget \
ca-certificates \
tzdata \
libssl-dev \
gcc \
g++ \
gdb && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /opt/media
WORKDIR /opt/media
RUN git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init
# 3rdpart init
WORKDIR /opt/media/ZLMediaKit/3rdpart
RUN wget https://polaris-tian-generic.pkg.coding.net/qt/dependencies/openssl-1.1.1k.tar.gz?version=latest -O openssl-1.1.1k.tar.gz && \
tar -xvzf openssl-1.1.1k.tar.gz && \
cd openssl-1.1.1k && ./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
WORKDIR /opt/media/ZLMediaKit/3rdpart
RUN wget https://github.com/cisco/libsrtp/archive/v2.3.0.tar.gz -O libsrtp-2.3.0.tar.gz && \
tar xfv libsrtp-2.3.0.tar.gz && \
mv libsrtp-2.3.0 libsrtp && \
cd libsrtp && ./configure --enable-openssl --with-openssl-dir=/usr/local/openssl && make -j $(nproc) && make install
WORKDIR /opt/media/ZLMediaKit/build
RUN cmake .. -DENABLE_WEBRTC=true -DOPENSSL_ROOT_DIR=/usr/local/openssl -DOPENSSL_LIBRARIES=/usr/local/openssl/lib && \
cmake --build . --target MediaServer
COPY config.ini /opt/media/ZLMediaKit/release/linux/Debug/
FROM ubuntu:20.04
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" \
apt-get install -y --no-install-recommends \
vim \
wget \
ca-certificates \
tzdata \
curl \
libssl-dev \
ffmpeg \
gcc \
g++ \
gdb && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone && \
mkdir -p /opt/media/bin/www
WORKDIR /opt/media/bin/
COPY --from=build /opt/media/ZLMediaKit/release/linux/Debug/MediaServer /opt/media/ZLMediaKit/default.pem /opt/media/bin/
COPY --from=build /opt/media/ZLMediaKit/release/linux/Debug/config.ini /opt/media/conf/
COPY --from=build /opt/media/ZLMediaKit/www/ /opt/media/bin/www/
ENV PATH /opt/media/bin:$PATH
CMD ["./MediaServer","-s", "default.pem", "-c", "../conf/config.ini", "-l","0"]

8
docker/media/build.sh Executable file
View File

@@ -0,0 +1,8 @@
#/bin/bash
set -e
version=2.7.3
docker build -t polaris-media:${version} .
docker tag polaris-media:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-media:${version}
docker tag polaris-media:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-media:latest

196
docker/media/config.ini Normal file
View File

@@ -0,0 +1,196 @@
; auto-generated by mINI class {
[api]
apiDebug=1
defaultSnap=./www/logo.png
downloadRoot=./www;
secret=su6TiedN2rVAmBbIDX0aa0QTiBJLBdcf
snapRoot=./www/snap/
[cluster]
origin_url=
retry_count=3
timeout_sec=15
[ffmpeg]
bin=/usr/bin/ffmpeg
cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
log=./ffmpeg/ffmpeg.log
restart_sec=0
snap=%s -rtsp_transport tcp -i %s -y -f mjpeg -frames:v 1 %s
[general]
broadcast_player_count_changed=0
check_nvidia_dev=1
enableVhost=0
enable_ffmpeg_log=0
flowThreshold=1024
listen_ip=::
maxStreamWaitMS=15000
mediaServerId=polaris
mergeWriteMS=0
resetWhenRePlay=1
streamNoneReaderDelayMS=20000
unready_frame_cache=100
wait_add_track_ms=3000
wait_audio_track_data_ms=1000
wait_track_ready_ms=10000
[hls]
broadcastRecordTs=0
deleteDelaySec=10
fastRegister=0
fileBufSize=65536
segDelay=0
segDur=2
segKeep=0
segNum=3
segRetain=5
[hook]
alive_interval=10.0
enable=1
on_flow_report=
on_http_access=
on_play=
on_publish=
on_record_mp4=
on_record_ts=
on_rtp_server_timeout=
on_rtsp_auth=
on_rtsp_realm=
on_send_rtp_stopped=
on_server_exited=
on_server_keepalive=
on_server_started=
on_shell_login=
on_stream_changed=
on_stream_none_reader=
on_stream_not_found=
retry=1
retry_delay=3.0
stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4
timeoutSec=30
[http]
allow_cross_domains=1
allow_ip_range=
charSet=utf-8
dirMenu=1
forbidCacheSuffix=
forwarded_ip_header=
keepAliveSecond=30
maxReqSize=40960
notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit(git hash:8ccb4e9/%aI,branch:master,build time:2024-11-07T10:34:19)</center></body></html>
port=6080
rootPath=./www
sendBufSize=65536
sslport=4443
virtualPath=
[multicast]
addrMax=239.255.255.255
addrMin=239.0.0.0
udpTTL=64
[protocol]
add_mute_audio=1
auto_close=0
continue_push_ms=3000
enable_audio=1
enable_fmp4=1
enable_hls=1
enable_hls_fmp4=0
enable_mp4=0
enable_rtmp=1
enable_rtsp=1
enable_ts=1
fmp4_demand=0
hls_demand=0
hls_save_path=./www
modify_stamp=2
mp4_as_player=0
mp4_max_second=3600
mp4_save_path=/home
paced_sender_ms=0
rtmp_demand=0
rtsp_demand=0
ts_demand=0
[record]
appName=record
enableFmp4=0
fastStart=0
fileBufSize=65536
fileRepeat=0
sampleMS=500
[rtc]
datachannel_echo=0
externIP=
maxRtpCacheMS=5000
maxRtpCacheSize=2048
max_bitrate=0
min_bitrate=0
nackIntervalRatio=1.0
nackMaxCount=15
nackMaxMS=3000
nackMaxSize=2048
nackRtpSize=8
port=8000
preferredCodecA=PCMA,PCMU,opus,mpeg4-generic
preferredCodecV=H264,H265,AV1,VP9,VP8
rembBitRate=0
start_bitrate=0
tcpPort=8000
timeoutSec=30
[rtmp]
directProxy=1
enhanced=0
handshakeSecond=15
keepAliveSecond=15
port=10935
sslport=0
[rtp]
audioMtuSize=600
h264_stap_a=1
lowLatency=0
rtpMaxSize=10
videoMtuSize=1400
[rtp_proxy]
dumpDir=
gop_cache=1
h264_pt=98
h265_pt=99
opus_pt=100
port=10000
port_range=30000-30500
ps_pt=96
rtp_g711_dur_ms=100
timeoutSec=15
udp_recv_socket_buffer=4194304
[rtsp]
authBasic=0
directProxy=1
handshakeSecond=15
keepAliveSecond=15
lowLatency=0
port=5540
rtpTransportType=-1
sslport=0
[shell]
maxReqSize=1024
port=0
[srt]
latencyMul=4
pktBufSize=8192
port=9000
timeoutSec=5
; } ---

3
docker/mysql/Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM mysql:8.0.32
ADD ./db/*.sql /docker-entrypoint-initdb.d/

8
docker/mysql/build.sh Executable file
View File

@@ -0,0 +1,8 @@
#/bin/bash
set -e
version=2.7.3
docker build -t polaris-mysql:${version} .
docker tag polaris-mysql:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-mysql:${version}
docker tag polaris-mysql:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-mysql:latest

View File

@@ -0,0 +1,3 @@
use mysql;
grant all privileges on wvp.* to 'ylcx'@'%';
flush privileges;

769
docker/mysql/db/wvp.sql Normal file
View File

@@ -0,0 +1,769 @@
/*建库*/
DROP DATABASE IF EXISTS `wvp`;
CREATE DATABASE `wvp` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
USE `wvp`;
/*建表*/
drop table IF EXISTS wvp_device;
create table IF NOT EXISTS wvp_device
(
id serial primary key,
device_id character varying(50) not null,
name character varying(255),
manufacturer character varying(255),
model character varying(255),
firmware character varying(255),
transport character varying(50),
stream_mode character varying(50),
on_line bool default false,
register_time character varying(50),
keepalive_time character varying(50),
ip character varying(50),
create_time character varying(50),
update_time character varying(50),
port integer,
expires integer,
subscribe_cycle_for_catalog integer DEFAULT 0,
subscribe_cycle_for_mobile_position integer DEFAULT 0,
mobile_position_submission_interval integer DEFAULT 5,
subscribe_cycle_for_alarm integer DEFAULT 0,
host_address character varying(50),
charset character varying(50),
ssrc_check bool default false,
geo_coord_sys character varying(50),
media_server_id character varying(50) default 'auto',
custom_name character varying(255),
sdp_ip character varying(50),
local_ip character varying(50),
password character varying(255),
as_message_channel bool default false,
heart_beat_interval integer,
heart_beat_count integer,
position_capability integer,
broadcast_push_after_ack bool default false,
server_id character varying(50),
constraint uk_device_device unique (device_id)
);
drop table IF EXISTS wvp_device_alarm;
create table IF NOT EXISTS wvp_device_alarm
(
id serial primary key,
device_id character varying(50) not null,
channel_id character varying(50) not null,
alarm_priority character varying(50),
alarm_method character varying(50),
alarm_time character varying(50),
alarm_description character varying(255),
longitude double precision,
latitude double precision,
alarm_type character varying(50),
create_time character varying(50) not null
);
drop table IF EXISTS wvp_device_mobile_position;
create table IF NOT EXISTS wvp_device_mobile_position
(
id serial primary key,
device_id character varying(50) not null,
channel_id character varying(50) not null,
device_name character varying(255),
time character varying(50),
longitude double precision,
latitude double precision,
altitude double precision,
speed double precision,
direction double precision,
report_source character varying(50),
create_time character varying(50)
);
drop table IF EXISTS wvp_device_channel;
create table IF NOT EXISTS wvp_device_channel
(
id serial primary key,
device_id character varying(50),
name character varying(255),
manufacturer character varying(50),
model character varying(50),
owner character varying(50),
civil_code character varying(50),
block character varying(50),
address character varying(50),
parental integer,
parent_id character varying(50),
safety_way integer,
register_way integer,
cert_num character varying(50),
certifiable integer,
err_code integer,
end_time character varying(50),
secrecy integer,
ip_address character varying(50),
port integer,
password character varying(255),
status character varying(50),
longitude double precision,
latitude double precision,
ptz_type integer,
position_type integer,
room_type integer,
use_type integer,
supply_light_type integer,
direction_type integer,
resolution character varying(255),
business_group_id character varying(255),
download_speed character varying(255),
svc_space_support_mod integer,
svc_time_support_mode integer,
create_time character varying(50) not null,
update_time character varying(50) not null,
sub_count integer,
stream_id character varying(255),
has_audio bool default false,
gps_time character varying(50),
stream_identification character varying(50),
channel_type int default 0 not null,
gb_device_id character varying(50),
gb_name character varying(255),
gb_manufacturer character varying(255),
gb_model character varying(255),
gb_owner character varying(255),
gb_civil_code character varying(255),
gb_block character varying(255),
gb_address character varying(255),
gb_parental integer,
gb_parent_id character varying(255),
gb_safety_way integer,
gb_register_way integer,
gb_cert_num character varying(50),
gb_certifiable integer,
gb_err_code integer,
gb_end_time character varying(50),
gb_secrecy integer,
gb_ip_address character varying(50),
gb_port integer,
gb_password character varying(50),
gb_status character varying(50),
gb_longitude double,
gb_latitude double,
gb_business_group_id character varying(50),
gb_ptz_type integer,
gb_position_type integer,
gb_room_type integer,
gb_use_type integer,
gb_supply_light_type integer,
gb_direction_type integer,
gb_resolution character varying(255),
gb_download_speed character varying(255),
gb_svc_space_support_mod integer,
gb_svc_time_support_mode integer,
record_plan_id integer,
data_type integer not null,
data_device_id integer not null,
gps_speed double precision,
gps_altitude double precision,
gps_direction double precision,
index (data_type),
index (data_device_id),
constraint uk_wvp_unique_channel unique (gb_device_id)
);
drop table IF EXISTS wvp_media_server;
create table IF NOT EXISTS wvp_media_server
(
id character varying(255) primary key,
ip character varying(50),
hook_ip character varying(50),
sdp_ip character varying(50),
stream_ip character varying(50),
http_port integer,
http_ssl_port integer,
rtmp_port integer,
rtmp_ssl_port integer,
rtp_proxy_port integer,
rtsp_port integer,
rtsp_ssl_port integer,
flv_port integer,
flv_ssl_port integer,
ws_flv_port integer,
ws_flv_ssl_port integer,
auto_config bool default false,
secret character varying(50),
type character varying(50) default 'zlm',
rtp_enable bool default false,
rtp_port_range character varying(50),
send_rtp_port_range character varying(50),
record_assist_port integer,
default_server bool default false,
create_time character varying(50),
update_time character varying(50),
hook_alive_interval integer,
record_path character varying(255),
record_day integer default 7,
transcode_suffix character varying(255),
server_id character varying(50),
constraint uk_media_server_unique_ip_http_port unique (ip, http_port, server_id)
);
drop table IF EXISTS wvp_platform;
create table IF NOT EXISTS wvp_platform
(
id serial primary key,
enable bool default false,
name character varying(255),
server_gb_id character varying(50),
server_gb_domain character varying(50),
server_ip character varying(50),
server_port integer,
device_gb_id character varying(50),
device_ip character varying(50),
device_port character varying(50),
username character varying(255),
password character varying(50),
expires character varying(50),
keep_timeout character varying(50),
transport character varying(50),
civil_code character varying(50),
manufacturer character varying(255),
model character varying(255),
address character varying(255),
character_set character varying(50),
ptz bool default false,
rtcp bool default false,
status bool default false,
catalog_group integer,
register_way integer,
secrecy integer,
create_time character varying(50),
update_time character varying(50),
as_message_channel bool default false,
catalog_with_platform integer default 1,
catalog_with_group integer default 1,
catalog_with_region integer default 1,
auto_push_channel bool default true,
send_stream_ip character varying(50),
server_id character varying(50),
constraint uk_platform_unique_server_gb_id unique (server_gb_id)
);
drop table IF EXISTS wvp_platform_channel;
create table IF NOT EXISTS wvp_platform_channel
(
id serial primary key,
platform_id integer,
device_channel_id integer,
custom_device_id character varying(50),
custom_name character varying(255),
custom_manufacturer character varying(50),
custom_model character varying(50),
custom_owner character varying(50),
custom_civil_code character varying(50),
custom_block character varying(50),
custom_address character varying(50),
custom_parental integer,
custom_parent_id character varying(50),
custom_safety_way integer,
custom_register_way integer,
custom_cert_num character varying(50),
custom_certifiable integer,
custom_err_code integer,
custom_end_time character varying(50),
custom_secrecy integer,
custom_ip_address character varying(50),
custom_port integer,
custom_password character varying(255),
custom_status character varying(50),
custom_longitude double precision,
custom_latitude double precision,
custom_ptz_type integer,
custom_position_type integer,
custom_room_type integer,
custom_use_type integer,
custom_supply_light_type integer,
custom_direction_type integer,
custom_resolution character varying(255),
custom_business_group_id character varying(255),
custom_download_speed character varying(255),
custom_svc_space_support_mod integer,
custom_svc_time_support_mode integer,
constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, device_channel_id),
constraint uk_platform_gb_channel_device_id unique (custom_device_id)
);
drop table IF EXISTS wvp_platform_group;
create table IF NOT EXISTS wvp_platform_group
(
id serial primary key,
platform_id integer,
group_id integer,
constraint uk_wvp_platform_group_platform_id_group_id unique (platform_id, group_id)
);
drop table IF EXISTS wvp_platform_region;
create table IF NOT EXISTS wvp_platform_region
(
id serial primary key,
platform_id integer,
region_id integer,
constraint uk_wvp_platform_region_platform_id_group_id unique (platform_id, region_id)
);
drop table IF EXISTS wvp_stream_proxy;
create table IF NOT EXISTS wvp_stream_proxy
(
id serial primary key,
type character varying(50),
app character varying(255),
stream character varying(255),
src_url character varying(255),
timeout integer,
ffmpeg_cmd_key character varying(255),
rtsp_type character varying(50),
media_server_id character varying(50),
enable_audio bool default false,
enable_mp4 bool default false,
pulling bool default false,
enable bool default false,
enable_remove_none_reader bool default false,
create_time character varying(50),
name character varying(255),
update_time character varying(50),
stream_key character varying(255),
server_id character varying(50),
enable_disable_none_reader bool default false,
relates_media_server_id character varying(50),
constraint uk_stream_proxy_app_stream unique (app, stream)
);
drop table IF EXISTS wvp_stream_push;
create table IF NOT EXISTS wvp_stream_push
(
id serial primary key,
app character varying(255),
stream character varying(255),
create_time character varying(50),
media_server_id character varying(50),
server_id character varying(50),
push_time character varying(50),
status bool default false,
update_time character varying(50),
pushing bool default false,
self bool default false,
start_offline_push bool default true,
constraint uk_stream_push_app_stream unique (app, stream)
);
drop table IF EXISTS wvp_cloud_record;
create table IF NOT EXISTS wvp_cloud_record
(
id serial primary key,
app character varying(255),
stream character varying(255),
call_id character varying(255),
start_time bigint,
end_time bigint,
media_server_id character varying(50),
server_id character varying(50),
file_name character varying(255),
folder character varying(500),
file_path character varying(500),
collect bool default false,
file_size bigint,
time_len bigint
);
drop table IF EXISTS wvp_user;
create table IF NOT EXISTS wvp_user
(
id serial primary key,
username character varying(255),
password character varying(255),
role_id integer,
create_time character varying(50),
update_time character varying(50),
push_key character varying(50),
constraint uk_user_username unique (username)
);
drop table IF EXISTS wvp_user_role;
create table IF NOT EXISTS wvp_user_role
(
id serial primary key,
name character varying(50),
authority character varying(50),
create_time character varying(50),
update_time character varying(50)
);
drop table IF EXISTS wvp_user_api_key;
create table IF NOT EXISTS wvp_user_api_key
(
id serial primary key,
user_id bigint,
app character varying(255),
api_key text,
expired_at bigint,
remark character varying(255),
enable bool default true,
create_time character varying(50),
update_time character varying(50)
);
/*初始数据*/
INSERT INTO wvp_user
VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 1, '2021-04-13 14:14:57', '2021-04-13 14:14:57',
'3e80d1762a324d5b0ff636e0bd16f1e3');
INSERT INTO wvp_user_role
VALUES (1, 'admin', '0', '2021-04-13 14:14:57', '2021-04-13 14:14:57');
drop table IF EXISTS wvp_common_group;
create table IF NOT EXISTS wvp_common_group
(
id serial primary key,
device_id varchar(50) NOT NULL,
name varchar(255) NOT NULL,
parent_id int,
parent_device_id varchar(50) DEFAULT NULL,
business_group varchar(50) NOT NULL,
create_time varchar(50) NOT NULL,
update_time varchar(50) NOT NULL,
civil_code varchar(50) default null,
constraint uk_common_group_device_platform unique (device_id)
);
drop table IF EXISTS wvp_common_region;
create table IF NOT EXISTS wvp_common_region
(
id serial primary key,
device_id varchar(50) NOT NULL,
name varchar(255) NOT NULL,
parent_id int,
parent_device_id varchar(50) DEFAULT NULL,
create_time varchar(50) NOT NULL,
update_time varchar(50) NOT NULL,
constraint uk_common_region_device_id unique (device_id)
);
drop table IF EXISTS wvp_record_plan;
create table IF NOT EXISTS wvp_record_plan
(
id serial primary key,
snap bool default false,
name varchar(255) NOT NULL,
create_time character varying(50),
update_time character varying(50)
);
drop table IF EXISTS wvp_record_plan_item;
create table IF NOT EXISTS wvp_record_plan_item
(
id serial primary key,
start int,
stop int,
week_day int,
plan_id int,
create_time character varying(50),
update_time character varying(50)
);
/*
* 20240528
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20240528`()
BEGIN
IF NOT EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'transcode_suffix')
THEN
ALTER TABLE wvp_media_server ADD transcode_suffix character varying(255);
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'type')
THEN
alter table wvp_media_server
add type character varying(50) default 'zlm';
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'flv_port')
THEN
alter table wvp_media_server add flv_port integer;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'flv_ssl_port')
THEN
alter table wvp_media_server add flv_ssl_port integer;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'ws_flv_port')
THEN
alter table wvp_media_server add ws_flv_port integer;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'ws_flv_ssl_port')
THEN
alter table wvp_media_server add ws_flv_ssl_port integer;
END IF;
END; //
call wvp_20240528();
DROP PROCEDURE wvp_20240528;
DELIMITER ;
create table IF NOT EXISTS wvp_user_api_key (
id serial primary key ,
user_id bigint,
app character varying(255) ,
api_key text,
expired_at bigint,
remark character varying(255),
enable bool default true,
create_time character varying(50),
update_time character varying(50)
);
/*
* 20241222
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20241222`()
BEGIN
IF EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and INDEX_NAME = 'uk_wvp_device_channel_unique_device_channel')
THEN
alter table wvp_device_channel drop index uk_wvp_device_channel_unique_device_channel;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and INDEX_NAME = 'uk_wvp_unique_stream_push_id')
THEN
alter table wvp_device_channel drop index uk_wvp_unique_stream_push_id;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and INDEX_NAME = 'uk_wvp_unique_stream_proxy_id')
THEN
alter table wvp_device_channel drop index uk_wvp_unique_stream_proxy_id;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'data_type')
THEN
alter table wvp_device_channel add data_type integer not null;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'data_device_id')
THEN
alter table wvp_device_channel add data_device_id integer not null;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'device_db_id')
THEN
update wvp_device_channel wdc INNER JOIN
(SELECT id, device_db_id from wvp_device_channel where device_db_id is not null ) ct on ct.id = wdc.id
set wdc.data_type = 1, wdc.data_device_id = ct.device_db_id where wdc.device_db_id is not null;
alter table wvp_device_channel drop device_db_id;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'stream_push_id')
THEN
update wvp_device_channel wdc INNER JOIN
(SELECT id, stream_push_id from wvp_device_channel where stream_push_id is not null ) ct on ct.id = wdc.id
set wdc.data_type = 2, wdc.data_device_id = ct.stream_push_id where wdc.stream_push_id is not null;
alter table wvp_device_channel drop stream_push_id;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'stream_proxy_id')
THEN
update wvp_device_channel wdc INNER JOIN
(SELECT id, stream_proxy_id from wvp_device_channel where stream_proxy_id is not null ) ct on ct.id = wdc.id
set wdc.data_type = 3, wdc.data_device_id = ct.stream_proxy_id where wdc.stream_proxy_id is not null;
alter table wvp_device_channel drop stream_proxy_id;
END IF;
END; //
call wvp_20241222();
DROP PROCEDURE wvp_20241222;
DELIMITER ;
/*
* 20241231
*/
DELIMITER //
CREATE PROCEDURE `wvp_20241231`()
BEGIN
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_stream_proxy' and column_name = 'relates_media_server_id')
THEN
alter table wvp_stream_proxy add relates_media_server_id character varying(50);
END IF;
END; //
call wvp_20241231();
DROP PROCEDURE wvp_20241231;
DELIMITER ;
/*
* 20250111
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20250111`()
BEGIN
IF EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_cloud_record' and INDEX_NAME = 'uk_stream_push_app_stream_path')
THEN
alter table wvp_cloud_record drop index uk_stream_push_app_stream_path ;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_cloud_record' and column_name = 'folder')
THEN
alter table wvp_cloud_record modify folder varchar(500) null;
END IF;
IF EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_cloud_record' and column_name = 'file_path')
THEN
alter table wvp_cloud_record modify file_path varchar(500) null;
END IF;
END; //
call wvp_20250111();
DROP PROCEDURE wvp_20250111;
DELIMITER ;
/*
* 20250211
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20250211`()
BEGIN
IF EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device' and column_name = 'keepalive_interval_time')
THEN
alter table wvp_device change keepalive_interval_time heart_beat_interval integer after as_message_channel;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device' and column_name = 'heart_beat_count')
THEN
alter table wvp_device add heart_beat_count integer;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device' and column_name = 'position_capability')
THEN
alter table wvp_device add position_capability integer;
END IF;
END; //
call wvp_20250211();
DROP PROCEDURE wvp_20250211;
DELIMITER ;
/**
* 20250312
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20250312`()
BEGIN
DECLARE serverId VARCHAR(32) DEFAULT '你的服务ID';
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device' and column_name = 'server_id')
THEN
alter table wvp_device add server_id character varying(50);
update wvp_device set server_id = serverId;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_media_server' and column_name = 'server_id')
THEN
alter table wvp_media_server add server_id character varying(50);
update wvp_media_server set server_id = serverId;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_stream_proxy' and column_name = 'server_id')
THEN
alter table wvp_stream_proxy add server_id character varying(50);
update wvp_stream_proxy set server_id = serverId;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_cloud_record' and column_name = 'server_id')
THEN
alter table wvp_cloud_record add server_id character varying(50);
update wvp_cloud_record set server_id = serverId;
END IF;
IF not EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_platform' and column_name = 'server_id')
THEN
alter table wvp_platform add server_id character varying(50);
END IF;
END; //
call wvp_20250312();
DROP PROCEDURE wvp_20250312;
DELIMITER ;
/*
* 20250319
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20250319`()
BEGIN
IF NOT EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'gps_speed')
THEN
alter table wvp_device_channel add gps_speed double precision;
END IF;
IF NOT EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'gps_altitude')
THEN
alter table wvp_device_channel add gps_altitude double precision;
END IF;
IF NOT EXISTS (SELECT column_name FROM information_schema.columns
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and column_name = 'gps_direction')
THEN
alter table wvp_device_channel add gps_direction double precision;
END IF;
END; //
call wvp_20250319();
DROP PROCEDURE wvp_20250319;
DELIMITER ;
/*
* 20250402
*/
DELIMITER // -- 重定义分隔符避免分号冲突
CREATE PROCEDURE `wvp_20250402`()
BEGIN
IF NOT EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and INDEX_NAME = 'data_type')
THEN
create index data_type on wvp_device_channel (data_type);
END IF;
IF NOT EXISTS (SELECT column_name FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = (SELECT DATABASE()) and table_name = 'wvp_device_channel' and INDEX_NAME = 'data_device_id')
THEN
create index data_device_id on wvp_device_channel (data_device_id);
END IF;
END; //
call wvp_20250402();
DROP PROCEDURE wvp_20250402;
DELIMITER ;

19
docker/nginx/Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM nginx:alpine
RUN apk add --no-cache bash
ARG TZ=Asia/Shanghai
RUN \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk update && \
apk add tzdata
RUN ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime && \
echo '${TZ}' > /etc/timezone
RUN rm -rf /etc/nginx/conf.d/*
RUN mkdir /opt/dist
COPY ./dist /opt/dist
COPY ./conf/nginx.conf /etc/nginx/conf.d
CMD ["nginx","-g","daemon off;"]

11
docker/nginx/build.sh Executable file
View File

@@ -0,0 +1,11 @@
#/bin/bash
set -e
version=2.7.3
rm ./dist/static/js/config.js
cp ./config.js ./dist/static/js/
docker build -t polaris-nginx:${version} .
docker tag polaris-nginx:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-nginx:${version}
docker tag polaris-nginx:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-nginx:latest

View File

@@ -0,0 +1,55 @@
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8080;
server_name localhost;
location / {
root /opt/dist;
index index.html index.htm;
}
location /record_proxy/{
proxy_set_header Host $http_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;
proxy_pass http://polaris-wvp:18978/;
}
location /api/ {
proxy_set_header Host $http_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;
proxy_pass http://polaris-wvp:18978;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

22
docker/nginx/config.js Normal file
View File

@@ -0,0 +1,22 @@
window.baseUrl = "http://10.10.1.124:18978"
// map组件全局参数, 注释此内容可以关闭地图功能
window.mapParam = {
// 开启/关闭地图功能
enable: true,
// 坐标系 GCJ-02 WGS-84,
coordinateSystem: "GCJ-02",
// 地图瓦片地址
tilesUrl: "http://webrd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8",
// 瓦片大小
tileSize: 256,
// 默认层级
zoom:10,
// 默认地图中心点
center:[116.41020, 39.915119],
// 地图最大层级
maxZoom:18,
// 地图最小层级
minZoom: 3
}

15
docker/push.sh Executable file
View File

@@ -0,0 +1,15 @@
#/bin/bash
set -e
version=2.7.3
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-media:latest
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-mysql:latest
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-redis:latest
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-wvp:latest
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-nginx:latest
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-media:${version}
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-mysql:${version}
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-redis:${version}
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-wvp:${version}
docker push polaris-tian-docker.pkg.coding.net/qt/polaris/ylcx-nginx:${version}

5
docker/redis/Dockerfile Normal file
View File

@@ -0,0 +1,5 @@
FROM redis
RUN mkdir -p /opt/polaris/redis
WORKDIR /opt/polaris/redis
COPY ./conf/redis.conf /opt/polaris/redis/redis.conf

8
docker/redis/build.sh Executable file
View File

@@ -0,0 +1,8 @@
#/bin/bash
set -e
version=2.7.3
docker build -t polaris-redis:${version} .
docker tag polaris-redis:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-redis:${version}
docker tag polaris-redis:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-redis:latest

View File

@@ -0,0 +1,2 @@
#requirepass root
bind 0.0.0.0

View File

@@ -1,2 +0,0 @@
requirepass root
bind 0.0.0.0

View File

@@ -1,81 +1,64 @@
FROM ubuntu:20.04 as build
FROM ubuntu:20.04 AS build
ARG Platfrom=amd64
ARG JDK_NAME
ARG gitUrl="https://gitee.com/pan648540858"
ARG zlmGitUrl="https://gitee.com/xia-chu/ZLMediaKit"
EXPOSE 18978/tcp
EXPOSE 8116/tcp
EXPOSE 8116/udp
EXPOSE 8080/tcp
RUN export DEBIAN_FRONTEND=noninteractive &&\
apt-get update && \
apt-get install -y --no-install-recommends openjdk-11-jre git maven nodejs npm build-essential \
cmake ca-certificates openssl ffmpeg &&\
mkdir -p /opt/wvp/config /opt/wvp/heapdump /opt/wvp/config /opt/assist/config /opt/assist/heapdump /opt/media/www/record
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" \
apt-get install -y --no-install-recommends \
wget \
cmake \
maven \
git \
ca-certificates \
tzdata \
curl \
libpcre3 \
libpcre3-dev \
zlib1g-dev \
openssl \
libssl-dev \
gdb && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
RUN cd /home && \
git clone "${gitUrl}/maven.git" && \
cp maven/settings.xml /usr/share/maven/conf/
# install jdk1.8
RUN mkdir -p /opt/download
WORKDIR /opt/download
RUN if [ "$Platfrom" = "arm64" ]; \
then \
wget https://polaris-tian-generic.pkg.coding.net/qt/autopliot/jdk-8u411-linux-aarch64.tar.gz?version=latest --no-check-certificate -O jdk-8.tar.gz && \
tar -zxvf /opt/download/jdk-8.tar.gz -C /usr/local/ --transform 's/jdk1.8.0_411/java/' && \
rm /opt/download/jdk-8.tar.gz; \
else \
wget https://polaris-tian-generic.pkg.coding.net/qt/autopliot/jdk-8u202-linux-x64.tar.gz?version=latest --no-check-certificate -O jdk-8.tar.gz && \
tar -zxvf /opt/download/jdk-8.tar.gz -C /usr/local/ --transform 's/jdk1.8.0_202/java/' && \
rm /opt/download/jdk-8.tar.gz; \
fi
RUN cd /home && \
git clone "${gitUrl}/wvp-GB28181-pro.git"
RUN cd /home/wvp-GB28181-pro/web_src && \
npm install && \
npm run build
RUN cd /home/wvp-GB28181-pro && \
mvn clean package -Dmaven.test.skip=true && \
cp /home/wvp-GB28181-pro/target/*.jar /opt/wvp/ && \
cp /home/wvp-GB28181-pro/src/main/resources/application-docker.yml /opt/wvp/config/application.yml
ENV JAVA_HOME /usr/local/java/
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH
RUN cd /home && \
git clone "${gitUrl}/wvp-pro-assist.git"
RUN cd /home/wvp-pro-assist && \
git reset --hard 58f1a79136a55a7cd1593c95b56ddadcc2225b61 && \
mvn clean package -Dmaven.test.skip=true && \
cp /home/wvp-pro-assist/target/*.jar /opt/assist/ && \
cp /home/wvp-pro-assist/src/main/resources/application-dev.yml /opt/assist/config/application.yml
RUN java -version && javac -version
RUN cd /home && \
git clone --depth=1 "${zlmGitUrl}"
RUN cd /home/ZLMediaKit && \
git submodule update --init --recursive && \
mkdir -p build release/linux/Release/ &&\
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 && \
rm -rf ../release/linux/Release/config.ini && \
cp -r ../release/linux/Release/* /opt/media
RUN cd /opt/wvp && \
echo '#!/bin/bash' > run.sh && \
echo 'echo ${WVP_IP}' >> run.sh && \
echo 'echo ${WVP_CONFIG}' >> run.sh && \
echo 'cd /opt/assist' >> run.sh && \
echo 'nohup java ${ASSIST_JVM_CONFIG} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/assist/heapdump/ -jar *.jar --spring.config.location=/opt/assist/config/application.yml --userSettings.record=/opt/media/www/record/ --media.record-assist-port=18081 ${ASSIST_CONFIG} &' >> run.sh && \
echo 'nohup /opt/media/MediaServer -d -m 3 &' >> run.sh && \
echo 'cd /opt/wvp' >> run.sh && \
echo 'java ${WVP_JVM_CONFIG} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/wvp/heapdump/ -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 ${WVP_CONFIG}' >> run.sh && \
chmod +x run.sh
FROM ubuntu:20.04
EXPOSE 18080/tcp
EXPOSE 5060/tcp
EXPOSE 5060/udp
EXPOSE 6379/tcp
EXPOSE 18081/tcp
EXPOSE 80/tcp
EXPOSE 1935/tcp
EXPOSE 554/tcp
EXPOSE 554/udp
EXPOSE 30000-30500/tcp
EXPOSE 30000-30500/udp
ENV LC_ALL zh_CN.UTF-8
RUN export DEBIAN_FRONTEND=noninteractive &&\
apt-get update && \
apt-get install -y --no-install-recommends openjdk-11-jre ca-certificates ffmpeg language-pack-zh-hans && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*dic
COPY --from=build /opt /opt
RUN mkdir -p /opt/wvp
WORKDIR /opt/wvp
CMD ["sh", "run.sh"]
COPY ./wvp /opt/wvp
WORKDIR /home
RUN cd /home && \
git clone https://gitee.com/pan648540858/wvp-GB28181-pro.git
RUN cd /home/wvp-GB28181-pro && \
mvn clean package -Dmaven.test.skip=true && \
cp /home/wvp-GB28181-pro/target/*.jar /opt/wvp/wvp.jar
WORKDIR /opt/wvp
ENTRYPOINT ["java", "-Xms512m", "-Xmx1024m", "-XX:+HeapDumpOnOutOfMemoryError", "-XX:HeapDumpPath=/opt/ylcx/", "-jar", "wvp.jar", "--spring.config.location=/opt/ylcx/wvp/application.yml"]

8
docker/wvp/build.sh Executable file
View File

@@ -0,0 +1,8 @@
#/bin/bash
set -e
version=2.7.3
docker build -t polaris-wvp:${version} .
docker tag polaris-wvp:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-wvp:${version}
docker tag polaris-wvp:${version} polaris-tian-docker.pkg.coding.net/qt/polaris/polaris-wvp:latest

View File

@@ -0,0 +1,105 @@
spring:
# 设置接口超时时间
mvc:
async:
request-timeout: 20000
thymeleaf:
cache: false
# [可选]上传文件大小限制
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: 1
# [可选] 访问密码,若你的redis服务器没有设置密码就不需要用密码去连接
password:
# [可选] 超时时间
timeout: 30000
# mysql数据源
datasource:
dynamic:
type: com.zaxxer.hikari.HikariDataSource
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: root
#[可选] 监听的HTTP端口, 网页和接口调用都是这个端口
server:
port: 18978
ssl:
# [可选] 是否开启HTTPS访问
enabled: false
# 作为28181服务器的配置
sip:
# [必须修改] 本机的IP
ip: 127.0.0.1
# [可选]
port: 8116
# [可选]
domain: 3402000000
# [可选]
id: 34020000002000000001
password:
alarm: true
# 默认服务器配置
media:
id: polaris
# [必须修改]内网IP
ip: 127.0.0.1
http-port: 6080
# [可选] 返回流地址时的ip置空使用 media.ip
stream-ip: 127.0.0.1
# [可选] wvp在国标信令中使用的ip此ip为摄像机可以访问到的ip 置空使用 media.ip
sdp-ip: 127.0.0.1
# [可选] Hook IP, 默认使用sip.ip
hook-ip: 127.0.0.1
# [可选] sslport
http-ssl-port: 4443
rtp-proxy-port: 10000
rtmp-port: 10935
rtmp-ssl-port: 41935
rtsp-port: 5540
rtsp-ssl-port: 45540
# [可选]
secret: su6TiedN2rVAmBbIDX0aa0QTiBJLBdcf
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分 点播超时建议使用多端口测试
rtp:
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
enable: false
# [可选]
port-range: 30000,30500
# [可选]
send-port-range: 50502,50506
record-path: /opt/media/record
record-day: 7
record-assist-port: 0
user-settings:
auto-apply-play: true
play-timeout: 30000
wait-track: false
record-push-live: false
record-sip: false
stream-on-demand: true
interface-authentication: false
broadcast-for-platform: TCP-PASSIVE
push-stream-after-ack: true
send-to-platforms-when-id-lost: true
interface-authentication-excludes:
- /api/**
push-authority: false
allowed-origins:
- http://localhost:8080
- http://127.0.0.1:8080
- http://0.0.0.0:8080
logging:
config: classpath:logback-spring.xml

View File

@@ -0,0 +1,106 @@
spring:
# 设置接口超时时间
mvc:
async:
request-timeout: 20000
thymeleaf:
cache: false
# [可选]上传文件大小限制
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
# REDIS数据库配置
redis:
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
host: ${REDIS_HOST:127.0.0.1}
# [必须修改] 端口号
port: ${REDIS_PORT:6379}
# [可选] 数据库 DB
database: 1
# [可选] 访问密码,若你的redis服务器没有设置密码就不需要用密码去连接
password:
# [可选] 超时时间
timeout: 30000
# mysql数据源
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${DATABASE_HOST:127.0.0.1}:${DATABASE_PORT:3306}/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: ${DATABASE_USER:root}
password: ${DATABASE_PASSWORD:root}
#[可选] 监听的HTTP端口, 网页和接口调用都是这个端口
server:
port: 18978
ssl:
# [可选] 是否开启HTTPS访问
enabled: false
# 作为28181服务器的配置
sip:
# [必须修改] 本机的IP
ip: ${SIP_HOST:127.0.0.1}
# [可选]
port: 8116
# [可选]
domain: 3402000000
# [可选]
id: 34020000002000000001
password:
alarm: true
# 默认服务器配置
media:
id: polaris
# [必须修改] ZLM 内网IP与端口
ip: ${ZLM_HOST:127.0.0.1}
http-port: ${ZLM_PORT:6080}
# [可选] 返回流地址时的ip置空使用 media.ip
stream-ip: ${STREAM_HOST:127.0.0.1}
# [可选] wvp在国标信令中使用的ip此ip为摄像机可以访问到的ip 置空使用 media.ip
sdp-ip: ${SIP_HOST:127.0.0.1}
# [可选] Hook IP, 默认使用sip.ip
hook-ip: ${SIP_HOST:127.0.0.1}
# [可选] sslport
http-ssl-port: 4443
rtp-proxy-port: 10000
rtmp-port: 10935
rtmp-ssl-port: 41935
rtsp-port: 5540
rtsp-ssl-port: 45540
# [可选]
secret: ${ZLM_SERCERT}
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分 点播超时建议使用多端口测试
rtp:
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
enable: false
# [可选]
port-range: 30000,30500
# [可选]
send-port-range: 50502,50506
record-path: /opt/media/record
record-day: 7
record-assist-port: 0
user-settings:
auto-apply-play: true
play-timeout: 30000
wait-track: false
record-push-live: false
record-sip: false
stream-on-demand: true
interface-authentication: false
broadcast-for-platform: TCP-PASSIVE
push-stream-after-ack: true
send-to-platforms-when-id-lost: true
interface-authentication-excludes:
- /api/**
push-authority: false
allowed-origins:
- http://localhost:8080
- http://127.0.0.1:8080
- http://0.0.0.0:8080
- ${NGINX_HOST}
logging:
config: classpath:logback-spring.xml

5
docker/wvp/wvp/application.yml Executable file
View File

@@ -0,0 +1,5 @@
spring:
application:
name: wvp
profiles:
active: docker

57
install.sh Normal file
View File

@@ -0,0 +1,57 @@
#! /bin/sh
WORD_DIR=$(cd $(dirname $0); pwd)
SERVICE_NAME="wvp"
# 检查是否为 root 用户
if [ "$(id -u)" -ne 0 ]; then
echo "提示: 建议使用 root 用户执行此脚本,否则可能权限不足!"
read -p "继续?(y/n) " -n 1 -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
echo
fi
# 当前目录直接搜索(不含子目录)
jar_files=(*.jar)
if [ ${#jar_files[@]} -eq 0 ]; then
echo "当前目录无 JAR 文件!"
exit 1
fi
# 遍历结果
for jar in "${jar_files[@]}"; do
echo "找到 JAR 文件: $jar"
done
# 写文件
# 生成 Systemd 服务文件内容
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
cat << EOF | sudo tee "$SERVICE_FILE" > /dev/null
[Unit]
Description=${SERVICE_NAME}
After=syslog.target
[Service]
User=$USER
WorkingDirectory=${WORD_DIR}
ExecStart=java -jar ${jar_files}
SuccessExitStatus=143
Restart=on-failure
RestartSec=10s
Environment=SPRING_PROFILES_ACTIVE=prod
[Install]
WantedBy=multi-user.target
EOF
# 重载 Systemd 并启动服务
sudo systemctl daemon-reload
sudo systemctl enable "$SERVICE_NAME"
sudo systemctl start "$SERVICE_NAME"
# 验证服务状态
echo "服务已安装!执行以下命令查看状态:"
echo "sudo systemctl status $SERVICE_NAME"

73
pom.xml
View File

@@ -6,12 +6,12 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.17</version>
<version>2.7.18</version>
</parent>
<groupId>com.genersoft</groupId>
<artifactId>wvp-pro</artifactId>
<version>2.7.2</version>
<version>2.7.4</version>
<name>web video platform</name>
<description>国标28181视频平台</description>
<packaging>${project.packaging}</packaging>
@@ -107,6 +107,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
@@ -133,6 +139,14 @@
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 数据库监控页面 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.23</version>
</dependency>
<!-- mysql数据库 -->
<dependency>
<groupId>com.mysql</groupId>
@@ -173,7 +187,6 @@
<version>1.4.6</version>
</dependency>
<!--在线文档 -->
<!--在线文档 -->
<dependency>
<groupId>org.springdoc</groupId>
@@ -185,20 +198,6 @@
<artifactId>springdoc-openapi-security</artifactId>
<version>1.6.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
<!--在线文档 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.10</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
@@ -243,12 +242,17 @@
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.17</version>
<version>2.0.57</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension</artifactId>
<version>2.0.17</version>
<version>2.0.57</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension-spring5</artifactId>
<version>2.0.57</version>
</dependency>
<!-- okhttp -->
@@ -338,6 +342,25 @@
<version>32.1.3-jre</version>
</dependency>
<!-- 自动化生成代码工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
<!--LogViewer-->
<!-- <dependency>-->
<!-- <groupId>io.github.sevdokimov.logviewer</groupId>-->
<!-- <artifactId>log-generator</artifactId>-->
<!-- <version>1.0.10</version>-->
<!-- </dependency>-->
<dependency>
<groupId>io.github.sevdokimov.logviewer</groupId>
<artifactId>log-viewer-spring-boot</artifactId>
<version>1.0.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@@ -354,6 +377,7 @@
<version>2.7.2</version>
<configuration>
<includeSystemScope>true</includeSystemScope>
<executable>true</executable>
</configuration>
</plugin>
@@ -364,6 +388,13 @@
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
@@ -393,10 +424,11 @@
<version>3.3.0</version>
<configuration>
<excludes>
<exclude>**/all-application.yml</exclude>
<exclude>**/配置详情.yml</exclude>
<exclude>**/application.yml</exclude>
<exclude>**/application-*.yml</exclude>
<exclude>**/local.jks</exclude>
<exclude>**/install.sh</exclude>
</excludes>
</configuration>
</plugin>
@@ -416,6 +448,7 @@
<includes>
<include>application.yml</include>
<include>application-*.yml</include>
<include>install.sh</include>
</includes>
</resource>
</resources>

122
run.sh Normal file
View File

@@ -0,0 +1,122 @@
#!/bin/bash
# JDK路径
export JAVA_HOME=/usr/local/java/jdk1.8.0_202
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
function log() {
message="[Polaris Log]: $1 "
case "$1" in
*"失败"* | *"错误"* | *"请使用 root 或 sudo 权限运行此脚本"*)
echo -e "${RED}${message}${NC}" 2>&1 | tee -a
;;
*"成功"*)
echo -e "${GREEN}${message}${NC}" 2>&1 | tee -a
;;
*"忽略"* | *"跳过"*)
echo -e "${YELLOW}${message}${NC}" 2>&1 | tee -a
;;
*)
echo -e "${BLUE}${message}${NC}" 2>&1 | tee -a
;;
esac
}
echo
cat <<EOF
██████╗ ██████╗ ██╗ █████╗ ██████╗ ██╗███████╗
██╔══██╗██╔═══██╗██║ ██╔══██╗██╔══██╗██║██╔════╝
██████╔╝██║ ██║██║ ███████║██████╔╝██║███████╗
██╔═══╝ ██║ ██║██║ ██╔══██║██╔══██╗██║╚════██║
██║ ╚██████╔╝███████╗██║ ██║██║ ██║██║███████║
╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝
EOF
# WVP-pro defines
AppName=wvp-pro-2.7.18-11211115.jar
AppHome="/root/polaris/wvp/"
# JVM参数
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx2048m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=1024m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
function start() {
log "======================= 开启流媒体服务 ======================="
log "AppHome: $AppHome"
cd $AppHome
log "AppName: $AppName"
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
if [x"$PID" != x""]; then
log "$AppName is running..."
else
nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
fi
log "流媒体服务开启成功"
}
function stop() {
log "======================= 停止流媒体服务 ======================="
PID=""
query() {
PID=$(ps -ef | grep java | grep $AppName | grep -v grep | awk '{print $2}')
}
query
if [ x"$PID" != x"" ]; then
log "进程PID: $PID"
kill -TERM $PID
log "$AppName (pid:$PID) exiting..."
while [ x"$PID" != x"" ]; do
sleep 1
query
done
log "成功:$AppName exited."
else
log "忽略:进程不存在"
fi
}
function status() {
log "======================= 运行状态 ======================="
log ""
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
if [ $PID != 0 ]; then
log "进程PID: $PID"
log "$AppName is running..."
else
log "$AppName is not running..."
fi
log ""
log "========================================================"
}
function restart() {
stop
sleep 3
start
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
*) ;;
esac

View File

@@ -1,9 +1,9 @@
package com.genersoft.iot.vmp;
import com.genersoft.iot.vmp.jt1078.util.ClassUtil;
import com.genersoft.iot.vmp.utils.GitUtil;
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -26,19 +26,23 @@ import java.util.Collections;
@SpringBootApplication
@EnableScheduling
@EnableCaching
@Slf4j
public class VManageBootstrap extends SpringBootServletInitializer {
private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);
private static String[] args;
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
VManageBootstrap.args = args;
VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args);
GitUtil gitUtil1 = SpringBeanFactory.getBean("gitUtil");
logger.info("构建版本: {}", gitUtil1.getBuildVersion());
logger.info("构建时间: {}", gitUtil1.getBuildDate());
logger.info("GIT最后提交时间 {}", gitUtil1.getCommitTime());
ClassUtil.context = VManageBootstrap.context;
GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil");
if (gitUtil == null) {
log.info("获取版本信息失败");
}else {
log.info("构建版本: {}", gitUtil.getBuildVersion());
log.info("构建时间: {}", gitUtil.getBuildDate());
log.info("GIT信息 分支: {}, ID: {}, 时间: {}", gitUtil.getBranch(), gitUtil.getCommitIdShort(), gitUtil.getCommitTime());
}
}
// 项目重启
public static void restart() {
@@ -60,6 +64,5 @@ public class VManageBootstrap extends SpringBootServletInitializer {
);
SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
sessionCookieConfig.setHttpOnly(true);
}
}

View File

@@ -1,198 +0,0 @@
package com.genersoft.iot.vmp.common;
/**
* 为API重命名, 方便向数据库记录数据的时候展示
* @author lin
*/
public class ApiSaveConstant {
public static String getVal(String key) {
String[] keyItemArray = key.split("/");
if (keyItemArray.length <= 1 || !"api".equals(keyItemArray[1])) {
return null;
}
if (keyItemArray.length >= 4) {
switch (keyItemArray[2]) {
case "alarm":
if ("delete".equals(keyItemArray[3])) {
return "删除报警";
}
break;
case "device":
switch (keyItemArray[3]) {
case "config":
if (keyItemArray.length >= 5 && "basicParam".equals(keyItemArray[4])) {
return "[设备配置] 基本配置设置命令";
}
break;
case "control":
switch (keyItemArray[4]) {
case "teleboot":
return "[设备控制] 远程启动";
case "record":
return "[设备控制] 录像控制";
case "guard":
return "[设备控制] 布防/撤防命令";
case "reset_alarm":
return "[设备控制] 报警复位";
case "i_frame":
return "[设备控制] 强制关键帧";
case "home_position":
return "[设备控制] 看守位控制";
default:
return "";
}
case "query":
if (keyItemArray.length <= 5) {
return null;
}
switch (keyItemArray[4]) {
case "devices":
if (keyItemArray.length < 7) {
return null;
}
switch (keyItemArray[6]) {
case "sync":
return "[设备查询] 同步设备通道";
case "delete":
return "[设备查询] 移除设备";
default:
return "";
}
case "channel":
return "[设备查询] 更新通道信息";
case "transport":
return "[设备查询] 修改数据流传输模式";
default:
return "";
}
default:
return "";
}
break;
case "gbStream":
switch (keyItemArray[3]) {
case "del":
return "移除通道与国标的关联";
case "add":
return "添加通道与国标的关联";
default:
return "";
}
case "media":
break;
case "position":
if ("subscribe".equals(keyItemArray[3])) {
return "订阅位置信息";
}
break;
case "platform":
switch (keyItemArray[3]) {
case "save":
return "添加上级平台";
case "delete":
return "移除上级平台";
case "update_channel_for_gb":
return "向上级平台添加国标通道";
case "del_channel_for_gb":
return "从上级平台移除国标通道";
default:
return "";
}
case "platform_gb_stream":
break;
case "play":
switch (keyItemArray[3]) {
case "start":
return "开始点播";
case "stop":
return "停止点播";
case "convert":
return "转码";
case "convertStop":
return "结束转码";
case "broadcast":
return "语音广播";
default:
return "";
}
case "download":
switch (keyItemArray[3]) {
case "start":
return "开始历史媒体下载";
case "stop":
return "停止历史媒体下载";
default:
return "";
}
case "playback":
switch (keyItemArray[3]) {
case "start":
return "开始视频回放";
case "stop":
return "停止视频回放";
default:
return "";
}
case "ptz":
switch (keyItemArray[3]) {
case "control":
return "云台控制";
case "front_end_command":
return "通用前端控制命令";
default:
return "";
}
case "gb_record":
break;
case "onvif":
break;
case "server":
if ("restart".equals(keyItemArray[3])) {
return "重启流媒体服务";
}
break;
case "proxy":
switch (keyItemArray[3]) {
case "save":
return "保存代理";
case "del":
return "移除代理";
case "start":
return "启用代理";
case "stop":
return "停用代理";
default:
return "";
}
case "push":
switch (keyItemArray[3]) {
case "save_to_gb":
return "将推流添加到国标";
case "remove_form_gb":
return "将推流移出到国标";
default:
return "";
}
case "user":
switch (keyItemArray[3]) {
case "login":
return "登录";
case "changePassword":
return "修改密码";
case "add":
return "添加用户";
case "delete":
return "删除用户";
default:
return "";
}
default:
return "";
}
}
return null;
}
}

View File

@@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.common;
import org.springframework.util.ObjectUtils;
public class CivilCodePo {
private String code;
@@ -12,7 +14,9 @@ public class CivilCodePo {
CivilCodePo civilCodePo = new CivilCodePo();
civilCodePo.setCode(infoArray[0]);
civilCodePo.setName(infoArray[1]);
civilCodePo.setParentCode(infoArray[2]);
if (!ObjectUtils.isEmpty(infoArray[2])) {
civilCodePo.setParentCode(infoArray[2]);
}
return civilCodePo;
}

View File

@@ -1,191 +0,0 @@
package com.genersoft.iot.vmp.common;
import io.swagger.v3.oas.annotations.media.Schema;
public class CommonGbChannel {
/**
* 国标字段:归属
*/
@Schema(description = "归属")
private String owner;
/**
* 国标字段:行政区划
*/
@Schema(description = "行政区划")
private String civilCode;
/**
* 国标字段:安装地址
*/
@Schema(description = "安装地址")
private String address;
/**
* 国标字段:经度
*/
@Schema(description = "经度")
private Double longitude;
/**
* 国标字段:纬度
*/
@Schema(description = "纬度")
private Double latitude;
/**
* 国标字段:摄像机类型:
* 1-球机;
* 2-半球;
* 3-固定枪机;
* 4-遥控枪机
*/
@Schema(description = "摄像机类型")
private Integer ptzType;
/**
* 国标字段:摄像机位置类型扩展。
* 1-省际检查站、
* 2-党政机关、
* 3-车站码头、
* 4-中心广场、
* 5-体育场馆、
* 6-商业中心、
* 7-宗教场所、
* 8-校园周边、
* 9-治安复杂区域、
* 10-交通干线
*/
@Schema(description = "摄像机位置类型扩展")
private Integer positionType;
/**
* 国标字段:安装位置室外、室内属性
* 1-室外、
* 2-室内
*/
@Schema(description = "安装位置室外、室内属性")
private Integer roomType;
/**
* 国标字段:用途
* 1-治安、
* 2-交通、
* 3-重点、
*/
@Schema(description = "用途")
private Integer useType;
/**
* 国标字段:补光属性
* 1-无补光、
* 2-红外补光、
* 3-白光补光
*/
@Schema(description = "补光属性")
private Integer supplyLightType;
/**
* 摄像机监视方位属性。
* 1-东、
* 2-西、
* 3-南、
* 4-北、
* 5-东南、
* 6-东北、
* 7-西南、
* 8-西北
*
*/
@Schema(description = "方位")
private Integer directionType;
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getCivilCode() {
return civilCode;
}
public void setCivilCode(String civilCode) {
this.civilCode = civilCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Integer getPtzType() {
return ptzType;
}
public void setPtzType(Integer ptzType) {
this.ptzType = ptzType;
}
public Integer getPositionType() {
return positionType;
}
public void setPositionType(Integer positionType) {
this.positionType = positionType;
}
public Integer getRoomType() {
return roomType;
}
public void setRoomType(Integer roomType) {
this.roomType = roomType;
}
public Integer getUseType() {
return useType;
}
public void setUseType(Integer useType) {
this.useType = useType;
}
public Integer getSupplyLightType() {
return supplyLightType;
}
public void setSupplyLightType(Integer supplyLightType) {
this.supplyLightType = supplyLightType;
}
public Integer getDirectionType() {
return directionType;
}
public void setDirectionType(Integer directionType) {
this.directionType = directionType;
}
}

View File

@@ -0,0 +1,7 @@
package com.genersoft.iot.vmp.common;
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
public interface DeviceStatusCallback {
public void run(String deviceId, SipTransactionInfo transactionInfo);
}

View File

@@ -1,5 +0,0 @@
package com.genersoft.iot.vmp.common;
public interface GeneralCallback<T>{
void run(int code, String msg, T data);
}

Some files were not shown because too many files have changed in this diff Show More