commit 038c93708650f5b2c0dc68d6ac2101816a1e1ad9 Author: jiumikeji <929832497@qq.com> Date: Tue Apr 22 19:46:44 2025 +0800 jiumi diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000..a104248 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,37 @@ +--- +name: "[ BUG ] " +about: 关于wvp的bug,与zlm有关的建议直接在zlm的issue中提问 +title: 'BUG' +labels: 'wvp的bug' +assignees: '' + +--- + +**环境信息:** + + - 1. 部署方式 wvp-pro docker / zlm(docker) + 编译wvp-pro/ wvp-prp + zlm都是编译部署/ + - 2. 部署环境 windows / ubuntu/ centos ... + - 3. 端口开放情况 + - 4. 是否是公网部署 + - 5. 是否使用https + - 6. 接入设备/平台品牌 + - 7. 你做过哪些尝试 + - 8. 代码更新时间 + - 9. 是否是4G设备接入 + +**描述错误** +描述下您遇到的问题 + +**如何复现** +有明确复现步骤的问题会很容易被解决 + +**截图** + +**抓包文件** + +**日志** +``` +日志内容放这里, 文件的话请直接上传 +``` + + diff --git a/.github/ISSUE_TEMPLATE/new.md b/.github/ISSUE_TEMPLATE/new.md new file mode 100644 index 0000000..7961421 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new.md @@ -0,0 +1,13 @@ +--- +name: "[ 新功能 ]" +about: 新功能 +title: '希望wVP实现的新功能,此功能应与你的具体业务无关' +labels: '' +assignees: '' + +--- + +**项目的详细需求** + +**这样的实现什么作用** + diff --git a/.github/ISSUE_TEMPLATE/solve.md b/.github/ISSUE_TEMPLATE/solve.md new file mode 100644 index 0000000..473dbd1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/solve.md @@ -0,0 +1,31 @@ +--- +name: "[ 技术咨询 ] " +about: 对于使用中遇到问题 +title: '技术咨询' +labels: '技术咨询' +assignees: '' + +--- + +**环境信息:** + + - 1. 部署方式 wvp-pro docker / zlm(docker) + 编译wvp-pro/ wvp-prp + zlm都是编译部署/ + - 2. 部署环境 windows / ubuntu/ centos ... + - 3. 端口开放情况 + - 4. 是否是公网部署 + - 5. 是否使用https + - 6. 方便的话提供下使用的设备品牌或平台 + - 7. 你做过哪些尝试 + - 8. 代码更新时间(旧版本请更新最新版本代码测试) + + +**内容描述:** + +**截图** + +**抓包文件** + +**日志** +``` +日志内容放这里, 文件的话请直接上传 +``` diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..776ebe1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Compiled class file +*.class + +# Log file +*.log +logs/* +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ +src/main/resources/application-*.yml +# Package Files # +#*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar +*.iml +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +/.idea/* +/target/* +/.idea/ +/target/ + +/src/main/resources/static/ +certificates diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..94f5d68 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "be.teletask.onvif-java"] + path = be.teletask.onvif-java + url = https://gitee.com/pan648540858/be.teletask.onvif-java.git diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..57cc8e5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 swwhaha + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5afd26d --- /dev/null +++ b/README.md @@ -0,0 +1,149 @@ + +# 开箱即用的28181协议视频平台 + +[](https://travis-ci.org/xia-chu/ZLMediaKit) +[](https://github.com/xia-chu/ZLMediaKit/blob/master/LICENSE) +[](https://en.cppreference.com/) +[](https://github.com/xia-chu/ZLMediaKit) +[](https://github.com/xia-chu/ZLMediaKit/pulls) + + +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) 进行修改. + +# 应用场景: +支持浏览器无插件播放摄像头视频。 +支持国标设备(摄像机、平台、NVR等)设备接入 +支持非国标(onvif, rtsp, rtmp,直播设备等等)设备接入,充分利旧。 +支持国标级联。多平台级联。跨网视频预览。 +支持跨网网闸平台互联。 + + +# 文档 +wvp使用文档 [https://doc.wvp-pro.cn](https://doc.wvp-pro.cn) +ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZLMediaKit/ZLMediaKit) + +# 付费社群 +[](https://t.zsxq.com/0d8VAD3Dm) +> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接自行推出,星球会直接退款给大家。 +> 星球还提供了基于主线master分支的打包, 会随时更新。 + +# gitee同步仓库 +https://gitee.com/pan648540858/wvp-GB28181-pro.git + +# 截图 + + + + + + + + +# 功能特性 +- [X] 集成web界面 +- [X] 兼容性良好 +- [X] 跨平台服务,一次编译多端部署, 可以同时用于x86和arm架构 +- [X] 接入设备 + - [X] 视频预览 + - [X] 支持主码流子码流切换 + - [X] 无限制接入路数,能接入多少设备只取决于你的服务器性能 + - [X] 云台控制,控制设备转向,拉近,拉远 + - [X] 预置位查询,使用与设置 + - [X] 查询NVR/IPC上的录像与播放,支持指定时间播放与下载 + - [X] 无人观看自动断流,节省流量 + - [X] 视频设备信息同步 + - [X] 离在线监控 + - [X] 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址 + - [X] 支持通过一个流地址直接观看摄像头,无需登录以及调用任何接口 + - [X] 支持UDP和TCP两种国标信令传输模式 + - [X] 支持UDP和TCP两种国标流传输模式 + - [X] 支持检索,通道筛选 + - [X] 支持通道子目录查询 + - [X] 支持过滤音频,防止杂音影响观看 + - [X] 支持国标网络校时 + - [X] 支持播放H264和H265 + - [X] 报警信息处理,支持向前端推送报警信息 + - [X] 语音对讲 + - [X] 支持业务分组和行政区划树自定义展示以及级联推送 + - [X] 支持订阅与通知方法 + - [X] 移动位置订阅 + - [X] 移动位置通知处理 + - [X] 报警事件订阅 + - [X] 报警事件通知处理 + - [X] 设备目录订阅 + - [X] 设备目录通知处理 + - [X] 移动位置查询和显示 + - [X] 支持手动添加设备和给设备设置单独的密码 +- [X] 支持平台对接接入 +- [X] 支持国标级联 + - [X] 国标通道向上级联 + - [X] WEB添加上级平台 + - [X] 注册 + - [X] 心跳保活 + - [X] 通道选择 + - [X] 支持通道编号自定义, 支持每个平台使用不同的通道编号 + - [X] 通道推送 + - [X] 点播 + - [X] 云台控制 + - [X] 平台状态查询 + - [X] 平台信息查询 + - [X] 平台远程启动 + - [X] 每个级联平台可自定义的虚拟目录 + - [X] 目录订阅与通知 + - [X] 录像查看与播放 + - [X] GPS订阅与通知(直播推流) + - [X] 语音对讲 + - [X] 支持同时级联到多个上级平台 +- [X] 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题; +- [X] 支持流媒体节点集群,负载均衡。 +- [X] 支持启用udp多端口模式, 提高udp模式下媒体传输性能; +- [X] 支持公网部署; +- [X] 支持wvp与zlm分开部署,提升平台并发能力 +- [X] 支持拉流RTSP/RTMP,分发为各种流格式,或者推送到其他国标平台 +- [X] 支持推流RTSP/RTMP,分发为各种流格式,或者推送到其他国标平台 +- [X] 支持推流鉴权 +- [X] 支持接口鉴权 +- [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载 +- [X] 支持打包可执行jar和war +- [X] 支持跨域请求,支持前后端分离部署 +- [X] 支持Mysql,Postgresql,金仓等数据库 +- [X] 支持录制计划, 根据设定的时间对通道进行录制. 暂不支持将录制的内容转发到国标上级 +- [X] 支持Onvif, 目前付费提供, 永久免费试用包在知识星球获取 +- [X] 支持国标28181-2022协议, 目前付费提供, 永久免费试用包在知识星球获取 +- [X] 支持国标信令集群 + + +# 非开源的内容 +- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。试用安装包以及使用教程: [知识星球](https://t.zsxq.com/10WAnH2MP),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。 +- [X] 支持部标1078+808协议,支持点播,云台控制,录像回放,位置上报,自动点播。 +- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,试用安装包: [知识星球](https://t.zsxq.com/UJ6V3),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。 + + +# 授权协议 +本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 + +# 技术支持 + +[知识星球](https://t.zsxq.com/0d8VAD3Dm)专栏列表:, +- [使用入门系列一:WVP-PRO能做什么](https://t.zsxq.com/0dLguVoSp) + +有偿技术支持,请发送邮件到648540858@qq.com + +# 致谢 +感谢作者[夏楚](https://github.com/xia-chu) 提供这么棒的开源流媒体服务框架,并在开发过程中给予支持与帮助。 +感谢作者[dexter langhuihui](https://github.com/langhuihui) 开源这么好用的WEB播放器。 +感谢作者[Kyle](https://gitee.com/kkkkk5G) 开源了好用的前端页面 +感谢各位大佬的赞助以及对项目的指正与帮助。包括但不限于代码贡献、问题反馈、资金捐赠等各种方式的支持!以下排名不分先后: +[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开发与调试: + + diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100644 index 0000000..0f3c4c9 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +###################################################### +# Copyright 2019 Pham Ngoc Hoai +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Repo: https://github.com/tyrion9/spring-boot-startup-script +# +######### PARAM ###################################### + +JAVA_OPT=-Xmx1024m +JARFILE=`ls -1r *.jar 2>/dev/null | head -n 1` +PID_FILE=pid.file +RUNNING=N +PWD=`pwd` + +######### DO NOT MODIFY ######## + +if [ -f $PID_FILE ]; then + PID=`cat $PID_FILE` + if [ ! -z "$PID" ] && kill -0 $PID 2>/dev/null; then + RUNNING=Y + fi +fi + +start() +{ + if [ $RUNNING == "Y" ]; then + echo "Application already started" + else + if [ -z "$JARFILE" ] + then + echo "ERROR: jar file not found" + else + nohup java $JAVA_OPT -Djava.security.egd=file:/dev/./urandom -jar $PWD/$JARFILE > nohup.out 2>&1 & + echo $! > $PID_FILE + echo "Application $JARFILE starting..." + tail -f nohup.out + fi + fi +} + +stop() +{ + if [ $RUNNING == "Y" ]; then + kill -9 $PID + rm -f $PID_FILE + echo "Application stopped" + else + echo "Application not running" + fi +} + +restart() +{ + stop + start +} + +case "$1" in + + 'start') + start + ;; + + 'stop') + stop + ;; + + 'restart') + restart + ;; + + *) + echo "Usage: $0 { start | stop | restart }" + exit 1 + ;; +esac +exit 0 + diff --git a/buildPackage.sh b/buildPackage.sh new file mode 100644 index 0000000..913a0d8 --- /dev/null +++ b/buildPackage.sh @@ -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 + diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..c5c4006 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,112 @@ +# 介绍 + +> 开箱即用的28181协议视频平台 + +# 概述 + +- 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以及平台。 +- 支持将国标设备级联到其他国标平台,也支持将不支持国标的设备的图像或者直播推送到其他国标平台 +- 前端完善,自带完整前端页面,无需二次开发可直接部署使用。 +- 完全开源,且使用MIT许可协议。保留版权的情况下可以用于商业项目。 +- 支持多流媒体节点负载均衡。 + +# 付费社群 + +[](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] 语音喊话 + +# 社区 + +代码目前托管在GitHub和Gitee,Gitee目前作为加速仓库使用,不接受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) \ No newline at end of file diff --git a/doc/_content/ability/_media/cascade1.png b/doc/_content/ability/_media/cascade1.png new file mode 100644 index 0000000..9ba8280 Binary files /dev/null and b/doc/_content/ability/_media/cascade1.png differ diff --git a/doc/_content/ability/_media/cascade2.png b/doc/_content/ability/_media/cascade2.png new file mode 100644 index 0000000..4dd62cf Binary files /dev/null and b/doc/_content/ability/_media/cascade2.png differ diff --git a/doc/_content/ability/_media/cascade3.png b/doc/_content/ability/_media/cascade3.png new file mode 100644 index 0000000..f95f5d5 Binary files /dev/null and b/doc/_content/ability/_media/cascade3.png differ diff --git a/doc/_content/ability/_media/cascade4.png b/doc/_content/ability/_media/cascade4.png new file mode 100644 index 0000000..9db85b5 Binary files /dev/null and b/doc/_content/ability/_media/cascade4.png differ diff --git a/doc/_content/ability/_media/img.png b/doc/_content/ability/_media/img.png new file mode 100644 index 0000000..6a0c550 Binary files /dev/null and b/doc/_content/ability/_media/img.png differ diff --git a/doc/_content/ability/_media/img_1.png b/doc/_content/ability/_media/img_1.png new file mode 100644 index 0000000..31995c3 Binary files /dev/null and b/doc/_content/ability/_media/img_1.png differ diff --git a/doc/_content/ability/_media/img_10.png b/doc/_content/ability/_media/img_10.png new file mode 100644 index 0000000..030502d Binary files /dev/null and b/doc/_content/ability/_media/img_10.png differ diff --git a/doc/_content/ability/_media/img_11.png b/doc/_content/ability/_media/img_11.png new file mode 100644 index 0000000..cb0f3d5 Binary files /dev/null and b/doc/_content/ability/_media/img_11.png differ diff --git a/doc/_content/ability/_media/img_12.png b/doc/_content/ability/_media/img_12.png new file mode 100644 index 0000000..d6fe877 Binary files /dev/null and b/doc/_content/ability/_media/img_12.png differ diff --git a/doc/_content/ability/_media/img_13.png b/doc/_content/ability/_media/img_13.png new file mode 100644 index 0000000..6be1128 Binary files /dev/null and b/doc/_content/ability/_media/img_13.png differ diff --git a/doc/_content/ability/_media/img_14.png b/doc/_content/ability/_media/img_14.png new file mode 100644 index 0000000..2471204 Binary files /dev/null and b/doc/_content/ability/_media/img_14.png differ diff --git a/doc/_content/ability/_media/img_15.png b/doc/_content/ability/_media/img_15.png new file mode 100644 index 0000000..f167811 Binary files /dev/null and b/doc/_content/ability/_media/img_15.png differ diff --git a/doc/_content/ability/_media/img_16.png b/doc/_content/ability/_media/img_16.png new file mode 100644 index 0000000..5a27be0 Binary files /dev/null and b/doc/_content/ability/_media/img_16.png differ diff --git a/doc/_content/ability/_media/img_17.png b/doc/_content/ability/_media/img_17.png new file mode 100644 index 0000000..483d522 Binary files /dev/null and b/doc/_content/ability/_media/img_17.png differ diff --git a/doc/_content/ability/_media/img_18.png b/doc/_content/ability/_media/img_18.png new file mode 100644 index 0000000..3b33b21 Binary files /dev/null and b/doc/_content/ability/_media/img_18.png differ diff --git a/doc/_content/ability/_media/img_19.png b/doc/_content/ability/_media/img_19.png new file mode 100644 index 0000000..5cf2d42 Binary files /dev/null and b/doc/_content/ability/_media/img_19.png differ diff --git a/doc/_content/ability/_media/img_2.png b/doc/_content/ability/_media/img_2.png new file mode 100644 index 0000000..f9f2f55 Binary files /dev/null and b/doc/_content/ability/_media/img_2.png differ diff --git a/doc/_content/ability/_media/img_20.png b/doc/_content/ability/_media/img_20.png new file mode 100644 index 0000000..387eb69 Binary files /dev/null and b/doc/_content/ability/_media/img_20.png differ diff --git a/doc/_content/ability/_media/img_21.png b/doc/_content/ability/_media/img_21.png new file mode 100644 index 0000000..19c7762 Binary files /dev/null and b/doc/_content/ability/_media/img_21.png differ diff --git a/doc/_content/ability/_media/img_22.png b/doc/_content/ability/_media/img_22.png new file mode 100644 index 0000000..f6aa8c4 Binary files /dev/null and b/doc/_content/ability/_media/img_22.png differ diff --git a/doc/_content/ability/_media/img_23.png b/doc/_content/ability/_media/img_23.png new file mode 100644 index 0000000..91be357 Binary files /dev/null and b/doc/_content/ability/_media/img_23.png differ diff --git a/doc/_content/ability/_media/img_24.png b/doc/_content/ability/_media/img_24.png new file mode 100644 index 0000000..e522481 Binary files /dev/null and b/doc/_content/ability/_media/img_24.png differ diff --git a/doc/_content/ability/_media/img_25.png b/doc/_content/ability/_media/img_25.png new file mode 100644 index 0000000..35900bd Binary files /dev/null and b/doc/_content/ability/_media/img_25.png differ diff --git a/doc/_content/ability/_media/img_3.png b/doc/_content/ability/_media/img_3.png new file mode 100644 index 0000000..efe688c Binary files /dev/null and b/doc/_content/ability/_media/img_3.png differ diff --git a/doc/_content/ability/_media/img_4.png b/doc/_content/ability/_media/img_4.png new file mode 100644 index 0000000..f548cec Binary files /dev/null and b/doc/_content/ability/_media/img_4.png differ diff --git a/doc/_content/ability/_media/img_5.png b/doc/_content/ability/_media/img_5.png new file mode 100644 index 0000000..6959c78 Binary files /dev/null and b/doc/_content/ability/_media/img_5.png differ diff --git a/doc/_content/ability/_media/img_6.png b/doc/_content/ability/_media/img_6.png new file mode 100644 index 0000000..04c42bc Binary files /dev/null and b/doc/_content/ability/_media/img_6.png differ diff --git a/doc/_content/ability/_media/img_7.png b/doc/_content/ability/_media/img_7.png new file mode 100644 index 0000000..1a8edbf Binary files /dev/null and b/doc/_content/ability/_media/img_7.png differ diff --git a/doc/_content/ability/_media/img_8.png b/doc/_content/ability/_media/img_8.png new file mode 100644 index 0000000..02fa66f Binary files /dev/null and b/doc/_content/ability/_media/img_8.png differ diff --git a/doc/_content/ability/_media/img_9.png b/doc/_content/ability/_media/img_9.png new file mode 100644 index 0000000..708e901 Binary files /dev/null and b/doc/_content/ability/_media/img_9.png differ diff --git a/doc/_content/ability/auto_play.md b/doc/_content/ability/auto_play.md new file mode 100644 index 0000000..2ce3012 --- /dev/null +++ b/doc/_content/ability/auto_play.md @@ -0,0 +1,3 @@ + + +# 自动点播 diff --git a/doc/_content/ability/cascade.md b/doc/_content/ability/cascade.md new file mode 100644 index 0000000..0766a7a --- /dev/null +++ b/doc/_content/ability/cascade.md @@ -0,0 +1,56 @@ + + +# 国标级联的使用 + +国标28181不同平台之间支持两种连接方式,平级和上下级,WVP目前支持向上级级联。 + +## 1 接入平台 + +### 1.1 wvp-pro + +#### 1.1.1 wvp-pro管理页面点击添加 + + + +#### 1.1.2 填入wvp-pro上级平台信息 + + + + +#### 1.1.3 编辑wvp-pro上级设备信息,开启订阅 + + + +### 1.2 大华平台 + +### 1.3 海康平台 + +### 1.4 liveGBS + +#### 1.4.1. wvp-pro管理页面点击添加 + + + +#### 1.4.2. 填入liveGBS平台信息 + + + + +#### 1.4.3. 编辑liveGBS设备信息,开启目录订阅 + + + +#### 1.4.4. 编辑liveGBS设备信息,开启GPS订阅 + + + +## 2 添加目录与通道 + +1. 级联平台添加目录信息 +  +2. 为目录添加通道 +  +3. 设置默认流目录 + 如果需要后续自动生成的流信息都在某一个节点下,可以在对应节点右键设置为默认 +  + diff --git a/doc/_content/ability/cascade2.md b/doc/_content/ability/cascade2.md new file mode 100644 index 0000000..00f4fcb --- /dev/null +++ b/doc/_content/ability/cascade2.md @@ -0,0 +1,71 @@ + + +# 国标级联的使用 + +国标28181不同平台之间支持两种连接方式,平级和上下级,WVP目前支持向上级级联。 + +## 添加上级平台 + +在国标级联页面点击“添加”按钮,以推送到上级WVP为例子,参看[接入设备](./_content/ability/device.md) + + +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:更新; + - 推送平台信息 + 勾选此项,上级收到的通道信息中会多出一个平台信息的通道.内容在平台的编辑中修改; + - 推送分组信息 + 勾选此项,如果你共享的通道分配了具体的业务分组以及虚拟组织,那么上级收到的通道中会包括业务分组以及虚拟组织节点信息; + - 推送行政区划 + 勾选此项,如果你共享的通道分配了具体的行政区划,那么上级收到的通道中会包括行政区划信息; + +国标级联列表出现了级联的这个平台;同时状态显示为在线,如果状态为离线那么可能是你的服务信息配置有误或者网络不通。 +订阅信息列有三个图标,表示上级开启订阅,从左到右依次是:报警订阅,目录订阅,移动位置订阅。 + +## 通道共享 + +点击你要推送的平台的“通道共享”按钮。 + + +1. 添加状态选择"未共享"可以将具体的通道共享给上级; +2. 添加状态选择"已共享"可以看到已经共享的通道,并且支持为这个通道在这个平台设备专门的名称和编号; +3. 点击"按设备添加"可以将某个国标设备下的所有通道共享给上级; +4. 点击"按设备移除"可以将某个国标设备下的所有通道取消共享给上级; +5. 点击"全部添加"可以将所有通道共享给上级; +6. 点击"全部移除"可以将所有通道共享给上级; + +## 推送通道 + +WVP会将所有通道信息按照目录订阅消息通知形式,发送ADD事件给上级. \ No newline at end of file diff --git a/doc/_content/ability/channel.md b/doc/_content/ability/channel.md new file mode 100644 index 0000000..adfe0ee --- /dev/null +++ b/doc/_content/ability/channel.md @@ -0,0 +1,22 @@ +# 通道管理 + +通道管理为了对已经分配国标编号的通道进行统一的行政区划和业务分组管理,国标中对于组织结构有两种表示方式,一种是按照行政区划,一种是业务分组+虚拟组织的方式. +行政区划结构固定,比如: 北京/市辖区/昌平区, 通道可以挂载道何一级行政区划下. 业务分组比较灵活, 可以按照自己的随意取名, +但是通道只能放在业务分组下的虚拟组织里,不能放在业务分组下. + +## 行政区划 + +左侧树结构为行政区划结构, 通过数据鼠标右键可以操作,包括: 刷新节点,新建节点,编辑节点,删除节点,添加设备( +可以将某个国标设备下的通道全部添加道某一个节点下),移除设备(可以将某个国标设备下的通道全部从这个节点移除) +右侧伪通道列表, 对于非国标接入的设备只有配置了国标编号后才可以在这里进行操作, 添加状态选择"未添加"可以进行添加操作,选择" +已添加"进行移除操作 + + +## 业务分组 + +左侧树结构为业务分组结构, 通过数据鼠标右键可以操作,包括: 刷新节点,新建节点,编辑节点,删除节点,添加设备( +可以将某个国标设备下的通道全部添加道某一个节点下),移除设备(可以将某个国标设备下的通道全部从这个节点移除) +业务分组下不能挂载设备,所以没有选择该节点的单选框. +右侧伪通道列表, 对于非国标接入的设备只有配置了国标编号后才可以在这里进行操作, 添加状态选择"未添加"可以进行添加操作,选择" +已添加"进行移除操作 + \ No newline at end of file diff --git a/doc/_content/ability/cloud_record.md b/doc/_content/ability/cloud_record.md new file mode 100644 index 0000000..716a614 --- /dev/null +++ b/doc/_content/ability/cloud_record.md @@ -0,0 +1,13 @@ + + +# 云端录像 + + +云端录像是对录制在zlm服务下的录像文件的管理,录像的文件路径默认在ZLM/www/record下。 + +- 国标设备是否录像: 可以再WVP的配置中user-settings.record-sip设置为true那么每次点播以及录像回放都会录像; +- 推流设备是否录像: 可以再WVP的配置中user-settings.record-push-live设置为true; +- 拉流代理的是否录像: 在添加和编辑拉流代理时可以指定, 每次点播都会进行录像 +- 录像文件存储路径配置: 可以修改media.record-path来修改录像路径,但是如果有旧的录像文件,请不要迁移,因为数据库记录了每一个录像的绝对路径,一旦修改会造成找到文件,无法定时移除以及播放 +- 录像保存时间: 可以修改media.record-day来修改录像保存时间,单位是天; + diff --git a/doc/_content/ability/continuous_broadcast.md b/doc/_content/ability/continuous_broadcast.md new file mode 100644 index 0000000..06708e7 --- /dev/null +++ b/doc/_content/ability/continuous_broadcast.md @@ -0,0 +1,104 @@ +# 语音对讲 + +## 流程和原理 + +语音对讲在国标28181-2016中分为broadcast(广播)和talk(对讲)两种模式,broadcast模式是从服务端把音频传送到设备端,是单向的, +需要结合点播视频来实现双向对讲,talk模式支持双向,不过wvp只处理了和broadcast一样的把音频传递设备,这样两种模式可以使用一样的逻辑处理即可。 +不同的设备对于两种模式的支持不同且通常差异很大,不同的设备对同一个设备的支持也有一些不同,所以语音对讲中的兼容和适配也是问题最多的。talk模式因为在国标28181-2022中已经移除,所以这里不再讨论它了。 + +### 1. broadcast模式流程 + +```plantuml +@startuml +"WVP-PRO" -> "设备": 语音广播通知 +"WVP-PRO" <-- "设备": 200OK +"WVP-PRO" <- "设备": 语音广播应答 +"WVP-PRO" --> "设备": 200OK +"WVP-PRO" <- "设备": Invite +"WVP-PRO" --> "设备": 200OK(携带SDP消息体) +"WVP-PRO" <-- "设备": ACK +"ZLMediaKit" -> "设备": 向设备发送语音流 +@enduml +``` + +与点播的流程不同的是,这里的invite消息是由设备发送给wvp的,wvp按照invite协商的方式给设备推送语音流,所有对讲的使用那种方式(UDP/TCP被动/TCP主动)传输语音流由设备决定 + +## 使用条件与限制 + +因为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 +"WVP-PRO" <- "ZLMediaKit": 通知收到语音对讲推流,携带设备和通道信息 +"WVP-PRO" -> "设备": 开始语音对讲 +"WVP-PRO" <-- "设备": 语音对讲建立成功,携带收流端口 +"WVP-PRO" -> "ZLMediaKit": 通知zlm将流推送到设备收流端口 +"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` \ No newline at end of file diff --git a/doc/_content/ability/continuous_recording.md b/doc/_content/ability/continuous_recording.md new file mode 100644 index 0000000..78c1ae5 --- /dev/null +++ b/doc/_content/ability/continuous_recording.md @@ -0,0 +1,16 @@ + + +# 7*24不间断录像 + +目前如果要实现不间断录像如果只是关闭无人观看停止推流是不够的,设备可能经历断网,重启,都会导致录像的中断,目前给大家提供一种可用的临时方案。 + +**原理:** wvp支持使用流地址自动点播,即你拿到一个流地址直接去播放,即使设备处于未点播状态,wvp会自动帮你点播;ZLM +的拉流代理成功后会无限重试,只要流一恢复就可以拉起来,基于这两个原理。 +**方案如下:** + +1. wvp的配置中user-settings->auto-apply-play设置为团true,开启自动点播; +2. 点击你要录像的通道,点击播放页面左下角的“更多地址”,点击rtsp,此时复制了rtsp地址到剪贴板; +3. 在拉流代理中添加一路流,地址填写你复制的地址,启用成功即可。 + **前提:** +1. wvp使用多端口收流,不然你无法得到一个固定的流地址,也就无法实现自动点播。 + diff --git a/doc/_content/ability/device.md b/doc/_content/ability/device.md new file mode 100644 index 0000000..87dd350 --- /dev/null +++ b/doc/_content/ability/device.md @@ -0,0 +1,72 @@ + + +# 接入设备 + +## 国标28181设备 + +设备接入主要是需要在设备上配置28181上级也就是WVP-PRO的信息,只有信息一致的情况才可以注册成功。设备注册成功后打开WVP-> +国标设备,可以看到新增加的设备;[设备使用](./_content/ability/device_use.md), +主要有以下字段需要配置: + +- sip->port + 28181服务监听的端口 + +- sip->domain + domain宜采用ID统一编码的前十位编码。 + +- sip->id + 28181服务ID + +- sip->password + 28181服务密码 + +- 配置信息在如下位置 + + +*** + +### 1. 大华摄像头 + + + +### 2. 大华NVR + + + +### 3. 宇视科技 + + + +### 3. 艾科威视摄像头 + + + +### 4. 水星摄像头 + + + +### 5. 海康摄像头 + + + +## 直播推流设备 + +这里以obs推流为例,很多无人机也是一样的,设置下推流地址就可以接入了 + +1. 从wvp获取推流地址, 选择节点管理菜单,查看要推流的节点; +  +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) diff --git a/doc/_content/ability/device_use.md b/doc/_content/ability/device_use.md new file mode 100644 index 0000000..6cb54dc --- /dev/null +++ b/doc/_content/ability/device_use.md @@ -0,0 +1,62 @@ + + +# 国标设备 + +### 更新设备通道 + +点击列表末尾的“刷新”按钮,可以看到一个圆形进度条,等进度结束提示成功后即可更新完成,如果通道数量有变化你可以看点击左上角的 +即可看到通道数量的变化;如果通道数量仍未0,那么可能时对方尚未推送通道给你。 + +### 查看设备通道 + +点击列表末尾的“通道”按钮, + +### 编辑设备 + +点击列表末尾的“编辑”按钮,即可在打开的弹窗中对设备功能进行修改 + +- 设备名称 + 如何未能从设备里读取到设备名称或者需要自己重命名,那么可以修改此选项。 +- 密码 + 支持为设备配置独立的密码. +- 收流IP + 如果你需要设备从指定的网络地址接入视频流,那么可以配置此IP,设备将会发流到这个IP,比如多网卡接入的服务器.或者存在网络映射的情况. +- 流媒体ID + 固定设备使用的流媒体ID,默认根据负载自动分配. +- 字符集 + 修改读取设备数据时使用的字符集,默认为GB2312,但是GB2312收录的汉字不全,所以有时候回遇到乱码,可以修改为UTF-8来解决。 +- 目录订阅 + 填写订阅周期即可对设备开启目录订阅,设备如果支持目录订阅那么设备在通道信息发生变化时就会通知WVP哪些通道发生了那些变化,包括通道增加/删除/更新/上线/下线/视频丢失/故障。0为取消订阅。 + 一般NVR和平台对接可以开启此选项,直接接摄像机开启此选项意义不大。 +- 移动位置订阅 + 对设备开启移动位置订阅,设备如果支持目录订阅那么设备位置发生变化时会通知到WVP,一般执法记录仪可以开启此选项,对固定位置的设备意义不大。 +- SSRC校验 + 为了解决部分设备出现的串流问题,可以打开此选项。ZLM会严格按照给定的ssrc处理视频流。部分设备流信息不标准,开启可能导致无法点播。 +- 作为消息通道 + wvp支持通过报警消息给下级WVP互相推送消息,消息内容由redis消息发送给wvp,wvp编辑成报警消息发送给下级 +- 收到ACK后发流 + 语音对讲策略: 不同的设备对于语音对讲的收流时机要求不一,勾选后会在收到设备发送的ack后再开始发流,不勾选则在回复200OK后开始发流,目前已知大华设备不勾选,海康需要勾选. + +### 删除设备 + +可以删除WVP中的设备信息,如果设备28181配置未更改,那么设备在下一次注册后仍然会注册上来。 + +### 点播视频 + +进入通道列表后,点击列表末尾的“播放”按钮,稍等即可弹出播放页面 + +### 设备录像 + +进入通道列表后,点击列表末尾的“设备录像”按钮,也可以在播放页面点击录像查询进入录像查看页面,选择要查看的日期即可对录像进行播放和下载。 + +### 云台控制 + +可以对支持云台功能的设备进行上下左右的转动以及拉近拉远的操作。 + +### 获取视频的播放器地址 + +视频点播成功后在实时视频页面,点击“更多地址”可以看到所有的播放地址,地址是否可以播放与你是否完整编译启用zlm功能有关,更与网络有关。 + +### 语音对讲 + +[语音对讲](_content/ability/continuous_broadcast.md) \ No newline at end of file diff --git a/doc/_content/ability/gis.md b/doc/_content/ability/gis.md new file mode 100644 index 0000000..5932df9 --- /dev/null +++ b/doc/_content/ability/gis.md @@ -0,0 +1,43 @@ + + +# 电子地图 + +WVP提供了简单的电子地图用于设备的定位以及移动设备的轨迹信息,电子地图基于开源的地图引擎openlayers开发。 + +### 查看设备定位 + +1. 可以在设备列表点击“定位”按钮,自动跳转到电子地图页面; +2. 在电子地图页面在设备上右键点击“定位”获取设备/平台下的所有通道位置。 +3. 单击通道信息可以定位到具体的通道 + +### 查询设备轨迹 + +查询轨迹需要提前配置save-position-history选项开启轨迹信息的保存,目前WVP此处未支持分库分表,对于大数据量的轨迹信息无法胜任,有需求请自行二次开发或者定制开发。 +在电子地图页面在设备上右键点击“查询轨迹”获取设备轨迹信息。 + +PS: 目前的底图仅用用作演示和学习,商用情况请自行购买授权使用。 + +### 更换底图以及底图配置 + +目前WVP支持使用了更换底图,配置文件在web_src/static/js/config.js,请修改后重新编译前端文件。 + +```javascript +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 +} +``` diff --git a/doc/_content/ability/node_manager.md b/doc/_content/ability/node_manager.md new file mode 100644 index 0000000..ec39a6b --- /dev/null +++ b/doc/_content/ability/node_manager.md @@ -0,0 +1,20 @@ + + +# 节点管理 + + + +WVP支持单个WVP多个ZLM的方案来扩展WVP的视频并发能力,并发点播是因为带宽和性能的原因,单个ZLM节点能支持的路数有限,所以WVP增加了ZLM集群来扩展并发并且保证ZLM的高可用。 + +## 默认节点 + +WVP中为了保证功能的完整性,ZLM节点至少要有一个默认节点,这个节点不是在管理页面添加的,而是在WVP的配置文件中配置的,这个节点不可在页面删除。每次启动会自动从配置文件中读取配置写入数据库备用。 + +## 新增节点 + +启动你要添加的zlm节点,然后点击“添加节点”按钮输入zlm的ip, +http端口,SECRET。点击测试测试完成则开始对节点进行详细的设置,如果你的zlm是使用docker启动的,可能存在zlm使用的端口与宿主机端口不一致的情况,需要在这里一一配置。 + +## wvp使用多个节点的原理 + +wvp会把连接的节点统一记录在redis中,并记录zlm的负载情况,当新的请求到来时,会取出负载最低的那个zlm进行使用。以此保证节点负载均衡。 diff --git a/doc/_content/ability/online_doc.md b/doc/_content/ability/online_doc.md new file mode 100644 index 0000000..50d5070 --- /dev/null +++ b/doc/_content/ability/online_doc.md @@ -0,0 +1,3 @@ + + +# 在线文档 diff --git a/doc/_content/ability/proxy.md b/doc/_content/ability/proxy.md new file mode 100644 index 0000000..7080442 --- /dev/null +++ b/doc/_content/ability/proxy.md @@ -0,0 +1,32 @@ + + +# 拉流代理 + +不是所有的摄像机都支持国标或者推流的,但是这些设备可以得到一个视频播放地址,通常为rtsp协议, +以大华为例: + +```text +rtsp://{user}:{passwd}@{ipc_ip}:{rtsp_port}/cam/realmonitor?channel=1&subtype=0 +``` + +可以得到这样一个流地址,可以直接用vlc进行播放,此时我们可以通过拉流代理功能将这个设备推送给其他国标平台了。 +流程如下: + +```plantuml +@startuml +"摄像机" <- "ZLMediaKit": 1. 流去流信息到ZLM +"ZLMediaKit" -> "WVP-PRO": 2. 收到hook通知得到流信息 +"上级国标平台" -> "WVP-PRO": 3. 点播这路视频 +"WVP-PRO" -> "ZLMediaKit": 4. 通知推流到上级国标平台 +@enduml +``` + +## 添加代理 + +拉流代理支持两种方式: + +1. ZLM中直接代理流,支持RTSP/RTMP,不支持转码; +2. 借助ffmpeg完成拉转,可以通过修改ffmpeg拉转参数完成转码。 + 点击页面的“添加代理”,添加信息后保存即可,如果你需要共享推流信息到其他国标平台,那么你需要编辑/国标通道配置,配置国标编码. + +`PS: ffmpeg默认模板不需修改,需要修改`参数自行去ZLM配置文件中添加一个即可。 diff --git a/doc/_content/ability/push.md b/doc/_content/ability/push.md new file mode 100644 index 0000000..cc568b3 --- /dev/null +++ b/doc/_content/ability/push.md @@ -0,0 +1,55 @@ + + +# 推流列表 + +## 功能说明 + +WVP支持三种图像输入方式,直播,[拉流代理](_content/ability/proxy.md),[国标](_content/ability/device.md),直播设备接入流程如下 + +```plantuml +@startuml +"直播设备" -> "ZLMediaKit": 1. 发起推流 +"ZLMediaKit" -> "WVP-PRO": 2. 收到hook通知得到流信息 +"上级国标平台" -> "WVP-PRO": 3. 点播这路视频 +"WVP-PRO" -> "ZLMediaKit": 4. 通知推流到上级国标平台 +@enduml +``` + +1. 默认情况下WVP收到推流信息后,列表中出现这条推流信息,如果你需要共享推流信息到其他国标平台,那么你需要编辑/国标通道配置,配置国标编码. +2. WVP也支持推流前导入大量通道直接推送给上级,点击“下载模板”按钮,根据示例修改模板后,点击“通道导入”按钮导入通道数据. + +## 推拉流鉴权规则 + +为了保护服务器的WVP默认开启推流鉴权(目前不支持关闭此功能) + +### 推流规则 + +推流时需要携带推流鉴权的签名sign,sign=md5(pushKey),pushKey来自用户表,每个用户会有一个不同的pushKey. +例如app=test,stream=live,pushKey=1000,ip=192.168.1.4, port=10554 那么推流地址为: + +``` +rtsp://192.168.1.4:10554/test/live?sign=a9b7ba70783b617e9998dc4dd82eb3c5 +``` + +支持推流时自定义播放鉴权Id,参数名为callId,此时sign=md5(callId_pushKey) +例如app=test,stream=live,pushKey=1000,callId=12345678, ip=192.168.1.4, port=10554 那么推流地址为: + +``` +rtsp://192.168.1.4:10554/test/live?callId=12345678&sign=c8e6e01dde2d60c66dcea8d2498ffef1 +``` + +### 播放规则 + +默认情况播放不需要鉴权,但是如果推流时携带了callId,那么播放时必须携带callId +例如app=test,stream=live,无callId, ip=192.168.1.4, port=10554 那么播放地址为: + +``` +rtsp://192.168.1.4:10554/test/live +``` + +例如app=test,stream=live,callId=12345678, ip=192.168.1.4, port=10554 那么播放地址为: + +``` +rtsp://192.168.1.4:10554/test/live?callId=12345678 +``` + diff --git a/doc/_content/ability/user.md b/doc/_content/ability/user.md new file mode 100644 index 0000000..776fe6b --- /dev/null +++ b/doc/_content/ability/user.md @@ -0,0 +1,3 @@ + + +# 用户管理 diff --git a/doc/_content/about_doc.md b/doc/_content/about_doc.md new file mode 100644 index 0000000..02e3613 --- /dev/null +++ b/doc/_content/about_doc.md @@ -0,0 +1,7 @@ + + +# 关于本文档 + +本文档开源在gitee上,[https://gitee.com/pan648540858/wvp-pro-doc.git](https://gitee.com/pan648540858/wvp-pro-doc.git) +,如果文档出现任何错误或者不易理解的语句,请大家提ISSUE帮助我及时更正。欢迎大家提交PR一起维护这份文档,让更多的人可以使用到这个开源的视频平台。 + diff --git a/doc/_content/broadcast.md b/doc/_content/broadcast.md new file mode 100644 index 0000000..355e761 --- /dev/null +++ b/doc/_content/broadcast.md @@ -0,0 +1,29 @@ +# 原理图 + +## 使用ffmpeg测试语音对讲原理 + +```plantuml +@startuml +"FFMPEG" -> "ZLMediaKit": 推流到zlm +"WVP-PRO" <- "ZLMediaKit": 通知收到语音对讲推流,携带设备和通道信息 +"WVP-PRO" -> "设备": 开始语音对讲 +"WVP-PRO" <-- "设备": 语音对讲建立成功,携带收流端口 +"WVP-PRO" -> "ZLMediaKit": 通知zlm将流推送到设备收流端口 +"ZLMediaKit" -> "设备": 向设备推流 +@enduml +``` + +## 使用网页测试语音对讲原理 + +```plantuml +@startuml +"前端页面" -> "WVP-PRO": 请求推流地址 +"前端页面" <-- "WVP-PRO": 返回推流地址 +"前端页面" -> "ZLMediaKit": 使用webrtc推流到zlm,以下过程相同 +"WVP-PRO" <- "ZLMediaKit": 通知收到语音对讲推流,携带设备和通道信息 +"WVP-PRO" -> "设备": 开始语音对讲 +"WVP-PRO" <-- "设备": 语音对讲建立成功,携带收流端口 +"WVP-PRO" -> "ZLMediaKit": 通知zlm将流推送到设备收流端口 +"ZLMediaKit" -> "设备": 向设备推流 +@enduml +``` \ No newline at end of file diff --git a/doc/_content/disclaimers.md b/doc/_content/disclaimers.md new file mode 100644 index 0000000..b0b2e64 --- /dev/null +++ b/doc/_content/disclaimers.md @@ -0,0 +1,5 @@ +# 免责声明 + +WVP-PRO自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 +但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 +在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议 \ No newline at end of file diff --git a/doc/_content/introduction/_media/img.png b/doc/_content/introduction/_media/img.png new file mode 100644 index 0000000..48f8d8e Binary files /dev/null and b/doc/_content/introduction/_media/img.png differ diff --git a/doc/_content/introduction/_media/img_1.png b/doc/_content/introduction/_media/img_1.png new file mode 100644 index 0000000..b4a62af Binary files /dev/null and b/doc/_content/introduction/_media/img_1.png differ diff --git a/doc/_content/introduction/_media/img_2.png b/doc/_content/introduction/_media/img_2.png new file mode 100644 index 0000000..a5961d6 Binary files /dev/null and b/doc/_content/introduction/_media/img_2.png differ diff --git a/doc/_content/introduction/compile.md b/doc/_content/introduction/compile.md new file mode 100644 index 0000000..038eb31 --- /dev/null +++ b/doc/_content/introduction/compile.md @@ -0,0 +1,124 @@ + + +# 编译 + +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的媒体部分的实现,以及各种视频流格式的分发支持 | 是 | + +## 2 安装依赖 + +| 依赖 | 版本 | 用途 | 开发环境需要 | 生产环境需要 | +|--------|-------|-------------|--------|--------| +| 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功能。截取一下关键步骤: + +```bash +# 国内用户推荐从同步镜像网站gitee下载 +git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit +cd ZLMediaKit +# 千万不要忘记执行这句命令 +git submodule update --init +``` + +## 5 编译WVP-PRO + +### 5.1 可以通过git克隆,也可以在项目下载点击下载 + + + +从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/ +npm --registry=https://registry.npmmirror.com install +npm run build +``` + +编译如果报错, 一般都是网络问题, 导致的依赖包下载失败 +编译完成后在src/main/resources下出现static目录 +**编译完成一般是这个样子,中间没有报红的错误信息** + + +### 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-VERSION.jar` 和 `wvp-pro-VERSION.war` 文件。 +接下来[配置服务](./_content/introduction/config.md) + + + + + + + + diff --git a/doc/_content/introduction/config.md b/doc/_content/introduction/config.md new file mode 100644 index 0000000..ea4c7c7 --- /dev/null +++ b/doc/_content/introduction/config.md @@ -0,0 +1,172 @@ + + +# 配置 + +对于首次测试或者新手同学,我建议在局域网测试,并且关闭服务器与客户机的防火墙测试。建议部署在linux进行测试。 + +```plantuml +@startuml +"WVP-PRO" -> "ZLMediaKit": RESTful 接口 +"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,部分配置项是可选,你不需要全部配置在配置文件中, +完全的配置说明可以参看"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支持多种数据库,包括Mysql,Postgresql,金仓等,配置任选一种即可。 + +### 2.1 数据库配置 + +#### 2.1.1 初始化数据库 + +首先使用创建数据库,然后使用sql/初始化.sql初始化数据库,如果是从旧版升级上来的,使用升级sql更新。 + +#### 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 +``` + +#### 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 + +pagehelper: + helper-dialect: postgresql +``` + +#### 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 + +pagehelper: + helper-dialect: postgresql +``` + +### 2.2 Redis数据库配置 + +配置wvp中的redis连接信息,建议wvp自己单独使用一个db。 + +### 2.3 配置服务启动端口(可直接使用默认配置) + +```yaml +# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + 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 +``` + +### 2.5 配置ZLMediaKit连接信息 + +```yaml +#zlm 默认服务器配置 +media: + id: zlmediakit-local + # [必须修改] zlm服务器的内网IP + ip: 172.19.128.50 + # [可选] 有公网IP就配置公网IP, 不可用域名 + wan_ip: + # [必须修改] zlm服务器的http.port + http-port: 9092 + # [可选] zlm服务器访问WVP所使用的IP, 默认使用127.0.0.1,zlm和wvp没有部署在同一台服务器时必须配置 + hook-ip: 172.19.128.50 + # [必选选] zlm服务器的hook.admin_params=secret + secret: TWSYFgYJOQWB4ftgeYut8DW4wbs7pQnj + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,35000 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 40000,40300 # 端口范围 +``` + +### 2.4 策略配置 + +```yaml +# [根据业务需求配置] +user-settings: + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # 推流直播是否录制 + record-push-live: true + # 国标是否录制 + record-sip: true + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true +``` + +更多完整的配置信息参考"src/main/resources/配置详情.yml"文件,需要那个配置项,复制到正在使用的配置文件中对应的文件即可。 + +如果配置信息无误,你可以启动zlm,再启动wvp来测试了,启动成功的话,你可以在wvp的日志下看到zlm已连接的提示。 +接下来[部署到服务器](./_content/introduction/deployment.md), 如果你只是本地运行直接在本地运行即可。 diff --git a/doc/_content/introduction/deployment.md b/doc/_content/introduction/deployment.md new file mode 100644 index 0000000..755c429 --- /dev/null +++ b/doc/_content/introduction/deployment.md @@ -0,0 +1,63 @@ + + +# 部署 + +**请仔细阅读以下内容** + +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 | 多端口开放 | + +3. 测试环境部署建议所有服务部署在一台主机,关闭防火墙,减少因网络出现问题的可能; +4. 生产环境按需开放端口,但是建议修改默认端口,尤其是5060端口,易受到攻击; +5. zlm使用docker部署的情况,请使用host模式,或者端口映射一致,比如映射5060,应将外部端口也映射为5060端口; +6. zlm与wvp会保持高频率的通信,所以不要去将wvp与zlm分属在两个网络,比如wvp在内网,zlm却在公网的情况。 +7. 启动服务,以linux为例 + **启动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) + +### 默认账号和密码 + +部署完毕后,可以通过访问 ip加端口的方式访问 WVP ,WVP的默认登录账号和密码均为 admin。 + + + diff --git a/doc/_content/qa/_media/img.png b/doc/_content/qa/_media/img.png new file mode 100644 index 0000000..d6c29d7 Binary files /dev/null and b/doc/_content/qa/_media/img.png differ diff --git a/doc/_content/qa/_media/img_1.png b/doc/_content/qa/_media/img_1.png new file mode 100644 index 0000000..5b74d95 Binary files /dev/null and b/doc/_content/qa/_media/img_1.png differ diff --git a/doc/_content/qa/_media/img_2.png b/doc/_content/qa/_media/img_2.png new file mode 100644 index 0000000..4aaa7fe Binary files /dev/null and b/doc/_content/qa/_media/img_2.png differ diff --git a/doc/_content/qa/_media/img_3.png b/doc/_content/qa/_media/img_3.png new file mode 100644 index 0000000..27f8a96 Binary files /dev/null and b/doc/_content/qa/_media/img_3.png differ diff --git a/doc/_content/qa/_media/img_4.png b/doc/_content/qa/_media/img_4.png new file mode 100644 index 0000000..aa3b88e Binary files /dev/null and b/doc/_content/qa/_media/img_4.png differ diff --git a/doc/_content/qa/_media/img_5.png b/doc/_content/qa/_media/img_5.png new file mode 100644 index 0000000..76e6faf Binary files /dev/null and b/doc/_content/qa/_media/img_5.png differ diff --git a/doc/_content/qa/bug.md b/doc/_content/qa/bug.md new file mode 100644 index 0000000..55e4caf --- /dev/null +++ b/doc/_content/qa/bug.md @@ -0,0 +1,18 @@ + + +# 反馈bug + +代码是在不断的完善的,不断修改会修复旧的问题也有可能引入新的问题,所以遇到BUG是很正常的一件事。所以遇到问题不要烦燥,咱们就事论事就好了。 + +## 如何反馈 + +1. 在知识星球提问。 +2. 更新代码,很可能你遇到问题别人已经更早的遇到了,或者是作者自己发现了,已经解决了,所以你可以更新代码再次进行测试; +3. 可以在github提ISSUE,我几乎每天都会去看issue,你的问题我会尽快给予答复; + +> 有偿支持可以给我发邮件, 648540858@qq.com + +## 社群 + +[](https://t.zsxq.com/0d8VAD3Dm) +> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 \ No newline at end of file diff --git a/doc/_content/qa/development.md b/doc/_content/qa/development.md new file mode 100644 index 0000000..ec9df9e --- /dev/null +++ b/doc/_content/qa/development.md @@ -0,0 +1,21 @@ + + +# 参与到开发中来 + +非常欢迎有兴趣的小伙伴一起来维护这个项目 + +## 与开发有关的信息 + +- 开发语言:后端java + 前端vue; +- jdk版本: 1.8; +- 作者自用开发ide: jetbrains intellij idea; +- nodejs/npm版本:v10.19.0/6.14.4; +- 后端使用Spring boot框架开发; +- 项目大量使用了异步操作; +- 跟代码学流程需要参考28181文档,只看代码你会很懵的; +- 必须学会[抓包](_content/skill/tcpdump.md),这是必须的 + +## 提交代码 + +大家可以通过fork项目的方式提交自己的代码,然后提交PR,我来合并到主线。提交代码的过程中我们需要遵循“**阿里编码规约** +”,现有代码也有很多代码没有做到,但是我们在朝这个方向努力。 \ No newline at end of file diff --git a/doc/_content/qa/img.png b/doc/_content/qa/img.png new file mode 100644 index 0000000..d6c29d7 Binary files /dev/null and b/doc/_content/qa/img.png differ diff --git a/doc/_content/qa/play_error.md b/doc/_content/qa/play_error.md new file mode 100644 index 0000000..a474399 --- /dev/null +++ b/doc/_content/qa/play_error.md @@ -0,0 +1,74 @@ + + +# 点播错误 + +排查点播错误你首先要清楚[点播的基本流程](_content/theory/play.md),一般的流程如下: + +```plantuml +@startuml +"WEB用户" -> "WVP-PRO": 1. 发起点播请求 +"设备" <- "WVP-PRO": 2. Invite(携带SDP消息体) +"设备" --> "WVP-PRO": 3. 200OK(携带SDP消息体) +"设备" <-- "WVP-PRO": 4. Ack +"设备" -> "ZLMediaKit": 5. 发送实时流 +"WVP-PRO" <- "ZLMediaKit": 6. 流改变事件 +"WEB用户" <-- "WVP-PRO": 7. 回复流播放地址(携带流地址) +"WVP-PRO" <- "ZLMediaKit": 8. 无人观看事件 +"设备" <- "WVP-PRO": 9 Bye消息 +"设备" --> "WVP-PRO": 10 200OK +@enduml +``` + +针对几种常见的错误,我们来分析一下,也方便大家对号入座解决常见的问题 + +## 点播收到错误码 + +这个错误一般表现为点击"播放"按钮后很快得到一个错误。 + +1. **400错误码** + 出现400错误玛时一般是这样的流程是这样的 + +```plantuml +@startuml +"WEB用户" -> "WVP-PRO": 1. 发起点播请求 +"设备" <- "WVP-PRO": 2. Invite(携带SDP消息体) +"设备" --> "WVP-PRO": 3. 400错误 +@enduml +``` + +此时通常是设备认为WVP发送了错误的消息给它,它认为消息不全或者错误所以直接返回400错误,此时我们需要[抓包](_content/skill/tcpdump.md) +来分析是否缺失了内容,也可以直接联系对方询问为什么返回了400。 +WVP不能保证兼容所有的设备,有些实现不规范的设备可能在对接时就会出现上述问题,你可以联系作者帮忙对接。 + +2. **500错误码** + 500或者大于500小于600的错误码一般多是设备内部出了问题,解决方式有两个,第一种直接联系设备/平台客服寻求解决;第二种,如果你有确定可以对接这个设备的平台那么可以把对接这个平台的抓包和对接wvp的抓包同时发送给我,我来尝试解决。 + +## 点播超时 + +点播超时的情况大致分为两种:点播超时和收流超时 + +1. **点播超时** + 点播超时错误一般为信令的超时,比如长时间为收到对方的回复,可能出现在流程中 “3. 200OK(携带SDP消息体) + ”这个位置,即我们发送点播消息,但是设备没有回复,可能的原因: + +> 1. 设备内部错误,未能回复消息 +> 2. 网络原因消息未到到达设备 + +大部分时候是原因2,所以遇到这个错误我们首先要排查我们我的网路,如果你是公网部署,那么也可能时心跳周期太长,导致的路由NAT失效,WVP的消息无法通道原来的IP端口号发送给设备。 + +2. **收流超时** + 收流超时可能发生在流程中的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日志是否有流注册; +- 抓包查看流的信息,看看流是否正常发送,甚至可以导出发送原始流,用vlc播放,看看是否可以播放。 diff --git a/doc/_content/qa/regiser_error.md b/doc/_content/qa/regiser_error.md new file mode 100644 index 0000000..7d4e96c --- /dev/null +++ b/doc/_content/qa/regiser_error.md @@ -0,0 +1,10 @@ + + +# 设备注册不上来的解决办法 + +一般的原因有两个 + +1. 信息填写错误,比如密码错误; +2. 网络不通导致注册消息无法发送到WVP; + +遇到问题首先仔细校验填写信息,例如海康可能需要勾选鉴权才可以输入密码。网络问题请自行测试。 \ No newline at end of file diff --git a/doc/_content/qa/start_error.md b/doc/_content/qa/start_error.md new file mode 100644 index 0000000..3e5749d --- /dev/null +++ b/doc/_content/qa/start_error.md @@ -0,0 +1,26 @@ + + +# 启动时报错 + +启动时的报错大部分时候是因为你的配置有问题,比如mysql没连接上,redis没连接上,18080/15060端口占用了,这些都会导致启动是报错,修改配置配置之后都可以解决; +下面我整理的一些常见的错误,大家可以先对号入座的简单排查下。 +> **常见错误** + + +**错误原因:** redis配置错误,可能原因: redis未启动/ip错误/端口错误/网络不通 +--- + +**错误原因:** redis配置错误,可能原因: 密码错误 +--- + +**错误原因:** mysql配置错误,可能原因: mysql未启动/ip错误/端口错误/网络不通 +--- + +**错误原因:** mysql配置错误,可能原因: 用户名/密码错误 +--- + +**错误原因:** SIP配置错误,可能原因: SIP端口被占用 +--- + +**错误原因:** WVP Tomcat端口配置错误,可能原因: server.port端口被占用 +--- \ No newline at end of file diff --git a/doc/_content/skill/_media/img.png b/doc/_content/skill/_media/img.png new file mode 100644 index 0000000..a9bc95f Binary files /dev/null and b/doc/_content/skill/_media/img.png differ diff --git a/doc/_content/skill/_media/img_1.png b/doc/_content/skill/_media/img_1.png new file mode 100644 index 0000000..e08e4e1 Binary files /dev/null and b/doc/_content/skill/_media/img_1.png differ diff --git a/doc/_content/skill/_media/img_2.png b/doc/_content/skill/_media/img_2.png new file mode 100644 index 0000000..2af0ecc Binary files /dev/null and b/doc/_content/skill/_media/img_2.png differ diff --git a/doc/_content/skill/tcpdump.md b/doc/_content/skill/tcpdump.md new file mode 100644 index 0000000..fa0ee88 --- /dev/null +++ b/doc/_content/skill/tcpdump.md @@ -0,0 +1,94 @@ + + +# 抓包 + +如果说对于网络编程,有什么工具是必会的,我觉得抓包肯定是其中之一了。作为GB/T +28181调试过程中最重要的手段,我觉得如果你真对他有兴趣,或者系统遇到问题可以最快的得到解决,那么抓包你就一定要学会了。 + +## 抓包工具的选择 + +### 1. Wireshark + +在具备图形界面的系统上,比如windows,linux发行版ubuntu,opensuse等,我一般直接使用Wireshark直接进行抓包,也方便进行内容的查看。 + +### 2. Tcpdump + +在使用命令行的系统,比如linux服务器,我一般使用Tcpdump进行抓包,无需额外安装,系统一般自带,抓包的到的文件,可以使用Wireshark打开,在图形界面下方便查看内容。 + +## 工具安装 + +Wireshark的安装很简单,根据提示一步步点击就好了,在linux需要解决权限的问题,如果和我一样使用图形界面的linux发行版的话,可以参看如下步骤; +windows的小伙伴直接略过即可 + +```shell +# 1. 添加wireshark用户组 +sudo groupadd wireshark +# 2. 将dumpcap更改为wireshark用户组 +sudo chgrp wireshark /usr/bin/dumpcap +# 3. 让wireshark用户组有root权限使用dumpcap +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` +详细的过滤规则可以自行百度,我可以提供一些常用的给大家参考 + +**只过滤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点击红色的停止即可,需要保存文件可以点击 +`文件->导出特定分组`导出过滤后的数据,也可以直接`文件->另存为`保存未过滤的数据。 + +### 使用tcpdump + +对于服务器抓包,为了得到足够完整的数据,我一般会要求直接抓取网卡数据而不过滤,如下: +抓取网卡首先需要获取网卡名,在linux我一般使用`ip addr`获取网卡信息,如下所示: + + +```shell +sudo tcpdump -i wlp3s0 -w demo.pcap +``` + + +命令行会停留在这个位置,此时可以进行操作,比如点播,录像回放等,操作完成回到命令行使用`Ctrl+C` +结束命令行,在当前目录下得到demo.pcap,将这个文件下载到图形界面操作系统里,即可使用Wireshark查看了 +更多的操作可以参考: [https://www.cnblogs.com/jiujuan/p/9017495.html](https://www.cnblogs.com/jiujuan/p/9017495.html) diff --git a/doc/_content/theory/_media/img.png b/doc/_content/theory/_media/img.png new file mode 100644 index 0000000..ecf62e9 Binary files /dev/null and b/doc/_content/theory/_media/img.png differ diff --git a/doc/_content/theory/_media/img_1.png b/doc/_content/theory/_media/img_1.png new file mode 100644 index 0000000..2dc8cc8 Binary files /dev/null and b/doc/_content/theory/_media/img_1.png differ diff --git a/doc/_content/theory/_media/img_2.png b/doc/_content/theory/_media/img_2.png new file mode 100644 index 0000000..7e2ddde Binary files /dev/null and b/doc/_content/theory/_media/img_2.png differ diff --git a/doc/_content/theory/_media/img_3.png b/doc/_content/theory/_media/img_3.png new file mode 100644 index 0000000..5fc5ef4 Binary files /dev/null and b/doc/_content/theory/_media/img_3.png differ diff --git a/doc/_content/theory/_media/img_4.png b/doc/_content/theory/_media/img_4.png new file mode 100644 index 0000000..d5df7ce Binary files /dev/null and b/doc/_content/theory/_media/img_4.png differ diff --git a/doc/_content/theory/_media/img_5.png b/doc/_content/theory/_media/img_5.png new file mode 100644 index 0000000..47daffc Binary files /dev/null and b/doc/_content/theory/_media/img_5.png differ diff --git a/doc/_content/theory/_media/img_6.png b/doc/_content/theory/_media/img_6.png new file mode 100644 index 0000000..6c67ef4 Binary files /dev/null and b/doc/_content/theory/_media/img_6.png differ diff --git a/doc/_content/theory/_media/img_7.png b/doc/_content/theory/_media/img_7.png new file mode 100644 index 0000000..fc204aa Binary files /dev/null and b/doc/_content/theory/_media/img_7.png differ diff --git a/doc/_content/theory/_media/img_8.png b/doc/_content/theory/_media/img_8.png new file mode 100644 index 0000000..9b43641 Binary files /dev/null and b/doc/_content/theory/_media/img_8.png differ diff --git a/doc/_content/theory/_media/img_9.png b/doc/_content/theory/_media/img_9.png new file mode 100644 index 0000000..c3aa1ff Binary files /dev/null and b/doc/_content/theory/_media/img_9.png differ diff --git a/doc/_content/theory/broadcast_cascade.md b/doc/_content/theory/broadcast_cascade.md new file mode 100644 index 0000000..1770b11 --- /dev/null +++ b/doc/_content/theory/broadcast_cascade.md @@ -0,0 +1,47 @@ + + +# 点播流程 + +> 以下为WVP-PRO级联语音喊话流程。 + +```plantuml +@startuml +"上级平台" -> "下级平台": 1. 发起语音喊话请求 +"上级平台" <-- "下级平台": 2. 200OK +"上级平台" <- "下级平台": 3. 回复Result OK +"上级平台" --> "下级平台": 4. 200OK + +"下级平台" -> "设备": 5. 发起语音喊话请求 +"下级平台" <-- "设备": 6. 200OK +"下级平台" <- "设备": 7. 回复Result OK +"下级平台" --> "设备": 8. 200OK + +"下级平台" <- "设备": 9. invite(broadcast) +"下级平台" --> "设备": 10. 100 trying +"下级平台" --> "设备": 11. 200OK SDP +"下级平台" <-- "设备": 12. ack + +"上级平台" <- "下级平台": 13. invite(broadcast) +"上级平台" --> "下级平台": 14. 100 trying +"上级平台" --> "下级平台": 15. 200OK SDP +"上级平台" <-- "下级平台": 16. ack + +"上级平台" -> "下级平台": 17. 推送RTP +"下级平台" -> "设备": 18. 推送RTP + +@enduml +``` + +## 注册流程描述如下: + +1. 用户从网页或调用接口发起点播请求; +2. WVP-PRO向摄像机发送Invite消息,消息头域中携带 Subject字段,表明点播的视频源ID、发送方媒体流序列号、ZLMediaKit接收流使用的IP、端口号、 + 接收端媒体流序列号等参数,SDP消息体中 s字段为“Play”代表实时点播,y字段描述SSRC值,f字段描述媒体参数。 +3. 摄像机向WVP-PRO回复200OK,消息体中描述了媒体流发送者发送媒体流的IP、端口、媒体格式、SSRC字段等内容。 +4. WVP-PRO向设备回复Ack, 会话建立成功。 +5. 设备向ZLMediaKit发送实时流。 +6. ZLMediaKit向WVP-PRO发送流改变事件。 +7. WVP-PRO向WEB用户回复播放地址。 +8. ZLMediaKit向WVP发送流无人观看事件。 +9. WVP-PRO向设备回复Bye, 结束会话。 +10. 设备回复200OK,会话结束成功。 diff --git a/doc/_content/theory/code.md b/doc/_content/theory/code.md new file mode 100644 index 0000000..2d9a9be --- /dev/null +++ b/doc/_content/theory/code.md @@ -0,0 +1,29 @@ + + +# 统一编码规则 + +## D.1 编码规则 A + +> 编码规则 A 由中心编码(8位)、行业编码(2位)、类型编码(3位)和序号(7位)四个码段共20位十 +> 进制数字字符构成,即系统编码 =中心编码 + 行业编码 + 类型编码 + 序号。 +> 编码规则 A 的详细说明见表 D.1。其中,中心编码指用户或设备所归属的监控中心的编码,按照监控中心所在地的行政区划代码确定, +> 当不是基层单位时空余位为0。行政区划代码采用 GB/T2260— 2007规定的行政区划代码表示。行业编码是指用户或设备所归属的行业,行业编码对照表见 +> D.3。 +> 类型编码指定了设备或用户的具体类型,其中的前端设备包含公安系统和非公安系统的前端设备,终端用 +> 户包含公安系统和非公安系统的终端用户。 + + + + +## D.2 编码规则 B + +> 编码规则 B由中心编码(8位)、行业编码(2位)、序号(4位)和类型编码(2位)四个码段构成,即系 +> 统编码 =中心编码 + 行业编码 +序号+类型编码。编码规则 B的详细说明见表 D.2。 + + + +## D.3 行业编码对照表 + +> 行业编码对照表见表 D.3。 + + \ No newline at end of file diff --git a/doc/_content/theory/img.png b/doc/_content/theory/img.png new file mode 100644 index 0000000..9b43641 Binary files /dev/null and b/doc/_content/theory/img.png differ diff --git a/doc/_content/theory/play.md b/doc/_content/theory/play.md new file mode 100644 index 0000000..5fb75c0 --- /dev/null +++ b/doc/_content/theory/play.md @@ -0,0 +1,34 @@ + + +# 点播流程 + +> 以下为WVP-PRO点播流程。点播成功前的任何一个环节出现问题都可能出现点播超时,这也是排查点播超时的依据。 + +```plantuml +@startuml +"WEB用户" -> "WVP-PRO": 1. 发起点播请求 +"设备" <- "WVP-PRO": 2. Invite(携带SDP消息体) +"设备" --> "WVP-PRO": 3. 200OK(携带SDP消息体) +"设备" <-- "WVP-PRO": 4. Ack +"设备" -> "ZLMediaKit": 5. 发送实时流 +"WVP-PRO" <- "ZLMediaKit": 6. 流改变事件 +"WEB用户" <-- "WVP-PRO": 7. 回复流播放地址(携带流地址) +"WVP-PRO" <- "ZLMediaKit": 8. 无人观看事件 +"设备" <- "WVP-PRO": 9 Bye消息 +"设备" --> "WVP-PRO": 10 200OK +@enduml +``` + +## 注册流程描述如下: + +1. 用户从网页或调用接口发起点播请求; +2. WVP-PRO向摄像机发送Invite消息,消息头域中携带 Subject字段,表明点播的视频源ID、发送方媒体流序列号、ZLMediaKit接收流使用的IP、端口号、 + 接收端媒体流序列号等参数,SDP消息体中 s字段为“Play”代表实时点播,y字段描述SSRC值,f字段描述媒体参数。 +3. 摄像机向WVP-PRO回复200OK,消息体中描述了媒体流发送者发送媒体流的IP、端口、媒体格式、SSRC字段等内容。 +4. WVP-PRO向设备回复Ack, 会话建立成功。 +5. 设备向ZLMediaKit发送实时流。 +6. ZLMediaKit向WVP-PRO发送流改变事件。 +7. WVP-PRO向WEB用户回复播放地址。 +8. ZLMediaKit向WVP发送流无人观看事件。 +9. WVP-PRO向设备回复Bye, 结束会话。 +10. 设备回复200OK,会话结束成功。 diff --git a/doc/_content/theory/register.md b/doc/_content/theory/register.md new file mode 100644 index 0000000..2bc839a --- /dev/null +++ b/doc/_content/theory/register.md @@ -0,0 +1,21 @@ + + +# 注册流程 + +WVP-PRO目前仅支持国标中描述的基本注册流程,也是最常用的, +> 基本注册即采用IETFRFC3261规定的基于数字摘要的挑战应答式安全技术进行注册. + +```plantuml +@startuml +"设备" -> "WVP-PRO": 1. Register +"设备" <-- "WVP-PRO": 2. 401 Unauthorized +"设备" -> "WVP-PRO": 3. Register +"设备" <-- "WVP-PRO": 4. 200 OK +@enduml +``` + +> 注册流程描述如下: +> 1. 摄像机向WVP-PRO服务器发送 Register请求; +> 2. WVP-PRO向摄像机发送响应401,并在响应的消息头 WWW_Authenticate字段中给出适合摄像机的认证体制和参数; +> 3. 摄像机重新向WVP-PRO发送 Register请求,在请求的 Authorization字段给出信任书, 包含认证信息; +> 4. WVP-PRO对请求进行验证,如果检查出 摄像机身份合法,向摄像机发送成功响应 200OK,如果身份不合法则发送拒绝服务应答。 diff --git a/doc/_coverpage.md b/doc/_coverpage.md new file mode 100644 index 0000000..4f76958 --- /dev/null +++ b/doc/_coverpage.md @@ -0,0 +1,17 @@ + + + +# WVP-PRO 2.0 + +> 开箱即用的28181协议视频平台。 + +- 基于GB/T28181-2016标准信令实现,兼容GB/T28181-2011。 +- 自带完整前端页面,开箱即用。 +- 完全开源,且使用MIT许可协议。可以在保留版权信息的基础上商用。 + +[GitHub](https://github.com/648540858/wvp-GB28181-pro) +[Gitee](https://gitee.com/pan648540858/wvp-GB28181-pro) + + + +[//]: # ([comment]: <> ()) diff --git a/doc/_media/1372762149.jpg b/doc/_media/1372762149.jpg new file mode 100644 index 0000000..471ec07 Binary files /dev/null and b/doc/_media/1372762149.jpg differ diff --git a/doc/_media/2.png b/doc/_media/2.png new file mode 100644 index 0000000..28d74b2 Binary files /dev/null and b/doc/_media/2.png differ diff --git a/doc/_media/3-1.png b/doc/_media/3-1.png new file mode 100644 index 0000000..0e62c36 Binary files /dev/null and b/doc/_media/3-1.png differ diff --git a/doc/_media/3-2.png b/doc/_media/3-2.png new file mode 100644 index 0000000..c75cef9 Binary files /dev/null and b/doc/_media/3-2.png differ diff --git a/doc/_media/3-3.png b/doc/_media/3-3.png new file mode 100644 index 0000000..3943a52 Binary files /dev/null and b/doc/_media/3-3.png differ diff --git a/doc/_media/3.png b/doc/_media/3.png new file mode 100644 index 0000000..913d294 Binary files /dev/null and b/doc/_media/3.png differ diff --git a/doc/_media/903207146.jpg b/doc/_media/903207146.jpg new file mode 100644 index 0000000..0bbc7e6 Binary files /dev/null and b/doc/_media/903207146.jpg differ diff --git a/doc/_media/favicon.ico b/doc/_media/favicon.ico new file mode 100644 index 0000000..bc5f8e6 Binary files /dev/null and b/doc/_media/favicon.ico differ diff --git a/doc/_media/index.png b/doc/_media/index.png new file mode 100644 index 0000000..46fe99b Binary files /dev/null and b/doc/_media/index.png differ diff --git a/doc/_media/log.jpg b/doc/_media/log.jpg new file mode 100644 index 0000000..18c57d0 Binary files /dev/null and b/doc/_media/log.jpg differ diff --git a/doc/_media/logo-mini.png b/doc/_media/logo-mini.png new file mode 100644 index 0000000..cc8078d Binary files /dev/null and b/doc/_media/logo-mini.png differ diff --git a/doc/_media/logo.jpg b/doc/_media/logo.jpg new file mode 100644 index 0000000..bcc9fb6 Binary files /dev/null and b/doc/_media/logo.jpg differ diff --git a/doc/_media/logo.png b/doc/_media/logo.png new file mode 100644 index 0000000..c5da2d4 Binary files /dev/null and b/doc/_media/logo.png differ diff --git a/doc/_media/shequ.png b/doc/_media/shequ.png new file mode 100644 index 0000000..c5aec98 Binary files /dev/null and b/doc/_media/shequ.png differ diff --git a/doc/_media/weixin.jpg b/doc/_media/weixin.jpg new file mode 100644 index 0000000..eda1260 Binary files /dev/null and b/doc/_media/weixin.jpg differ diff --git a/doc/_media/zhifubao.jpg b/doc/_media/zhifubao.jpg new file mode 100644 index 0000000..973996b Binary files /dev/null and b/doc/_media/zhifubao.jpg differ diff --git a/doc/_navbar.md b/doc/_navbar.md new file mode 100644 index 0000000..22ac93a --- /dev/null +++ b/doc/_navbar.md @@ -0,0 +1 @@ + diff --git a/doc/_sidebar.md b/doc/_sidebar.md new file mode 100644 index 0000000..d1f500c --- /dev/null +++ b/doc/_sidebar.md @@ -0,0 +1,32 @@ + + +* **编译与部署** + * [编译](_content/introduction/compile.md) + * [配置](_content/introduction/config.md) + * [部署](_content/introduction/deployment.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_manger.md) + * [通道管理](_content/ability/channel.md) + * [国标级联](_content/ability/cascade2.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) + +* **常见问答** + - [如何反馈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) diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..a8c1d7d --- /dev/null +++ b/doc/index.html @@ -0,0 +1,59 @@ + + +
+ +8?o(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0}function m(t,e,n,a){p(t),a&&(o(t,n),o(t,~n)),N.arraySet(t.pending_buf,t.window,e,n,t.pending),t.pending+=n}function b(t,e,n,a){var r=2*e,i=2*n;return t[r] "+e+">>8^i[255&(t^e[o])];return-1^t}var r=function(){for(var t,e=[],n=0;n<256;n++){t=n;for(var a=0;a<8;a++)t=1&t?3988292384^t>>>1:t>>>1;e[n]=t}return e}();e.exports=a},{}],10:[function(t,e,n){"use strict";function a(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}e.exports=a},{}],11:[function(t,e,n){"use strict";e.exports=function(t,e){var n,a,r,i,s,o,l,h,d,f,u,c,_,g,p,m,b,w,v,k,y,x,z,B,C;n=t.state,a=t.next_in,B=t.input,r=a+(t.avail_in-5),i=t.next_out,C=t.output,s=i-(e-t.avail_out),o=i+(t.avail_out-257),l=n.dmax,h=n.wsize,d=n.whave,f=n.wnext,u=n.window,c=n.hold,_=n.bits,g=n.lencode,p=n.distcode,m=(1<852||2===t&&Z>592)return 1;g=N&p,h[g]=A<<24|S<<16|m-d|0}}return 0!==N&&(h[m+N]=x-E<<24|64<<16|0),u.bits=A,0}},{"../utils/common":5}],14:[function(t,e,n){"use strict";e.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],15:[function(t,e,n){"use strict";function a(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}e.exports=a},{}]},{},[3])(3)})}]);
\ No newline at end of file
diff --git a/doc/lib/js/docsify@4.js b/doc/lib/js/docsify@4.js
new file mode 100644
index 0000000..76fc755
--- /dev/null
+++ b/doc/lib/js/docsify@4.js
@@ -0,0 +1 @@
+!function(){function c(i){var o=Object.create(null);return function(e){var n=f(e)?e:JSON.stringify(e);return o[n]||(o[n]=i(e))}}var a=c(function(e){return e.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()})}),u=Object.prototype.hasOwnProperty,m=Object.assign||function(e){for(var n=arguments,i=1;i'+(i?e:gn(e,!0))+"\n":"
\n"},e.prototype.blockquote=function(e){return""+(i?e:gn(e,!0))+"\n"+e+"
\n"},e.prototype.html=function(e){return e},e.prototype.heading=function(e,n,i,o){return this.options.headerIds?"
\n":"
\n"},e.prototype.list=function(e,n,i){var o=n?"ol":"ul";return"<"+o+(n&&1!==i?' start="'+i+'"':"")+">\n"+e+""+o+">\n"},e.prototype.listitem=function(e){return"\n\n"+e+"\n"+(n=n&&""+n+"")+"
\n"},e.prototype.tablerow=function(e){return"\n"+e+" \n"},e.prototype.tablecell=function(e,n){var i=n.header?"th":"td";return(n.align?"<"+i+' align="'+n.align+'">':"<"+i+">")+e+""+i+">\n"},e.prototype.strong=function(e){return""+e+""},e.prototype.em=function(e){return""+e+""},e.prototype.codespan=function(e){return""+e+""},e.prototype.br=function(){return this.options.xhtml?"
":"
"},e.prototype.del=function(e){return""+e+""},e.prototype.link=function(e,n,i){if(null===(e=dn(this.options.sanitize,this.options.baseUrl,e)))return i;e='"+i+""},e.prototype.image=function(e,n,i){if(null===(e=dn(this.options.sanitize,this.options.baseUrl,e)))return i;i='":">"},e.prototype.text=function(e){return e},e}(),ln=function(){function e(){}return e.prototype.strong=function(e){return e},e.prototype.em=function(e){return e},e.prototype.codespan=function(e){return e},e.prototype.del=function(e){return e},e.prototype.html=function(e){return e},e.prototype.text=function(e){return e},e.prototype.link=function(e,n,i){return""+i},e.prototype.image=function(e,n,i){return""+i},e.prototype.br=function(){return""},e}(),vn=function(){function e(){this.seen={}}return e.prototype.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},e.prototype.getNextSafeSlug=function(e,n){var i=e,o=0;if(this.seen.hasOwnProperty(i))for(o=this.seen[e];i=e+"-"+ ++o,this.seen.hasOwnProperty(i););return n||(this.seen[e]=o,this.seen[i]=0),i},e.prototype.slug=function(e,n){void 0===n&&(n={});e=this.serialize(e);return this.getNextSafeSlug(e,n.dryrun)},e}(),hn=we.defaults,_n=Ie,mn=function(){function i(e){this.options=e||hn,this.options.renderer=this.options.renderer||new sn,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new ln,this.slugger=new vn}return i.parse=function(e,n){return new i(n).parse(e)},i.parseInline=function(e,n){return new i(n).parseInline(e)},i.prototype.parse=function(e,n){void 0===n&&(n=!0);for(var i,o,t,a,r,c,u,f,p,d,g,s,l,v,h,_="",m=e.length,b=0;b
"+wn(e.message+"",!0)+"";throw e}}xn.options=xn.setOptions=function(e){return bn(xn.defaults,e),yn(xn.defaults),xn},xn.getDefaults=Me,xn.defaults=we,xn.use=function(a){var n,e=bn({},a);if(a.renderer){var i,r=xn.defaults.renderer||new sn;for(i in a.renderer)!function(o){var t=r[o];r[o]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var i=a.renderer[o].apply(r,e);return i=!1===i?t.apply(r,e):i}}(i);e.renderer=r}if(a.tokenizer){var t,c=xn.defaults.tokenizer||new nn;for(t in a.tokenizer)!function(){var o=c[t];c[t]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var i=a.tokenizer[t].apply(c,e);return i=!1===i?o.apply(c,e):i}}();e.tokenizer=c}a.walkTokens&&(n=xn.defaults.walkTokens,e.walkTokens=function(e){a.walkTokens(e),n&&n(e)}),xn.setOptions(e)},xn.walkTokens=function(e,n){for(var i=0,o=e;i
"+wn(e.message+"",!0)+"";throw e}},xn.Parser=mn,xn.parser=mn.parse,xn.Renderer=sn,xn.TextRenderer=ln,xn.Lexer=fn,xn.lexer=fn.lex,xn.Tokenizer=nn,xn.Slugger=vn;var Sn=xn.parse=xn;function An(e,i){if(void 0===i&&(i=''),!e||!e.length)return"";var o="";return e.forEach(function(e){var n=e.title.replace(/(<([^>]+)>)/g,"");o+='
'+n.slice(5).trim()+"
"}function zn(e,o){var t=[],a={};return e.forEach(function(e){var n=e.level||1,i=n-1;o
':i;var i,o}).replace(/__colon__/g,":")}function On(e){var o={};return{str:e=(e=void 0===e?"":e)&&e.replace(/^('|")/,"").replace(/('|")$/,"").replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g,function(e,n,i){return-1===n.indexOf(":")?(o[n]=i&&i.replace(/"/g,"")||!0,""):e}).trim(),config:o}}function Ln(e){return(e=void 0===e?"":e).replace(/(<\/?a.*?>)/gi,"")}var qn,Pn=be(function(e){var u,f,p,d,n,g=function(u){var i=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,e={},T={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof C?new C(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=r.reach);m+=_.value.length,_=_.next){var b=_.value;if(i.length>n.length)return;if(!(b instanceof C)){var k,w=1;if(l){if(!(k=R(h,m,n,s))||k.index>=n.length)break;var y=k.index,x=k.index+k[0].length,S=m;for(S+=_.value.length;S<=y;)_=_.next,S+=_.value.length;if(S-=_.value.length,m=S,_.value instanceof C)continue;for(var A=_;A!==i.tail&&(S'+Pn.highlight(e.replace(/@DOCSIFY_QM@/g,"`"),i,n)+""},t.link=(i=(n={renderer:e,router:a,linkTarget:n,linkRel:i,compilerClass:g}).renderer,c=n.router,u=n.linkTarget,n.linkRel,f=n.compilerClass,i.link=function(e,n,i){var o=[],t=On(n=void 0===n?"":n),a=t.str,t=t.config;return u=t.target||u,r="_blank"===u?f.config.externalLinkRel||"noopener":"",n=a,T(e)||f._matchNotCompileLink(e)||t.ignore?(T(e)||"./"!==e.slice(0,2)||(e=document.URL.replace(/\/(?!.*\/).*/,"/").replace("#/./","")+e),o.push(0===e.indexOf("mailto:")?"":'target="'+u+'"'),o.push(0!==e.indexOf("mailto:")&&""!==r?' rel="'+r+'"':"")):(e===f.config.homepage&&(e="README"),e=c.toURL(e,null,c.getCurrentPath())),t.crossorgin&&"_self"===u&&"history"===f.config.routerMode&&-1===f.config.crossOriginLinks.indexOf(e)&&f.config.crossOriginLinks.push(e),t.disabled&&(o.push("disabled"),e="javascript:void(0)"),t.class&&o.push('class="'+t.class+'"'),t.id&&o.push('id="'+t.id+'"'),n&&o.push('title="'+n+'"'),'"+i+""}),t.paragraph={renderer:e}.renderer.paragraph=function(e){e=/^!>/.test(e)?$n("tip",e):/^\?>/.test(e)?$n("warn",e):""+e+"
";return e},t.image=(o=(i={renderer:e,contentBase:o,router:a}).renderer,p=i.contentBase,d=i.router,o.image=function(e,n,i){var o=e,t=[],a=On(n),r=a.str,a=a.config;return n=r,a["no-zoom"]&&t.push("data-no-zoom"),n&&t.push('title="'+n+'"'),a.size&&(n=(r=a.size.split("x"))[0],(r=r[1])?t.push('width="'+n+'" height="'+r+'"'):t.push('width="'+n+'"')),a.class&&t.push('class="'+a.class+'"'),a.id&&t.push('id="'+a.id+'"'),T(e)||(o=q(p,R(d.getCurrentPath()),e)),0"+e.content+"
\n\n"}),t.classList.add("show"),a.classList.add("show"),t.innerHTML=r||''+c+"
",s.hideOtherSidebarContent&&(i&&i.classList.add("hide"),n&&n.classList.add("hide"))}function l(e){s=e}function h(e,n){var t,a,i=n.router.parse().query.s;l(e),Docsify.dom.style("\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0.6em 7px;\n font-size: inherit;\n border: 1px solid transparent;\n}\n\n.search input:focus {\n box-shadow: 0 0 5px var(--theme-color, #42b983);\n border: 1px solid var(--theme-color, #42b983);\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n\n.search input::-ms-clear {\n display: none;\n height: 0;\n width: 0;\n}\n\n.search .clear-button {\n cursor: pointer;\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n display: none;\n}"),function(e){void 0===e&&(e="");var n=Docsify.dom.create("div",'