ZLMediaKit+wvp-GB28181-pro,搭建28181协议视频平台

article/2025/9/19 11:36:43

ZLMediaKit+wvp-GB28181-pro,搭建28181协议视频平台

一,简介

ZLMediaKit:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求

一个基于C++11的高性能运营级流媒体服务框架,项目地址:ZLMediaKit

特点:

  • 基于C++11开发,避免使用裸指针,代码稳定可靠,性能优越。
  • 支持多种协议(RTSP/RTMP/HLS/HTTP-FLV/WebSocket-FLV/GB28181/HTTP-TS/WebSocket-TS/HTTP-fMP4/WebSocket-fMP4/MP4/WebRTC),支持协议互转。
  • 使用多路复用/多线程/异步网络IO模式开发,并发性能优越,支持海量客户端连接。
  • 代码经过长期大量的稳定性、性能测试,已经在线上商用验证已久。
  • 支持linux、macos、ios、android、windows全平台。
  • 支持画面秒开、极低延时(500毫秒内,最低可达100毫秒)。
  • 提供完善的标准C API,可以作SDK用,或供其他语言调用。
  • 提供完整的MediaServer服务器,可以免开发直接部署为商用服务器。
  • 提供完善的restful api以及web hook,支持丰富的业务逻辑。
  • 打通了视频监控协议栈与直播协议栈,对RTSP/RTMP支持都很完善。
  • 全面支持H265/H264/AAC/G711/OPUS。
  • 功能完善,支持集群、按需转协议、按需推拉流、先播后推、断连续推等功能。
  • 极致性能,单机10W级别播放器,100Gb/s级别io带宽能力。
  • 极致体验,独家特性
  • 谁在使用zlmediakit?
  • 全面支持ipv6网络

项目定位:

  • 移动嵌入式跨平台流媒体解决方案。
  • 商用级流媒体服务器。
  • 网络编程二次开发SDK。

在这里插入图片描述

  • RTSP[S]

    • RTSP[S] 服务器,支持RTMP/MP4/HLS转RTSP[S],支持亚马逊echo show这样的设备
    • RTSP[S] 播放器,支持RTSP代理,支持生成静音音频
    • RTSP[S] 推流客户端与服务器
    • 支持 rtp over udp rtp over tcp rtp over http rtp组播 四种RTP传输方式
    • 服务器/客户端完整支持Basic/Digest方式的登录鉴权,全异步可配置化的鉴权接口
    • 支持H265编码
    • 服务器支持RTSP推流(包括rtp over udp rtp over tcp方式)
    • 支持H264/H265/AAC/G711/OPUS编码,其他编码能转发但不能转协议
  • RTMP[S]

    • RTMP[S] 播放服务器,支持RTSP/MP4/HLS转RTMP
    • RTMP[S] 发布服务器,支持录制发布流
    • RTMP[S] 播放器,支持RTMP代理,支持生成静音音频
    • RTMP[S] 推流客户端
    • 支持http[s]-flv直播
    • 支持websocket-flv直播
    • 支持H264/H265/AAC/G711/OPUS编码,其他编码能转发但不能转协议
    • 支持RTMP-H265
    • 支持RTMP-OPUS
  • HLS

    • 支持HLS文件生成,自带HTTP文件服务器
    • 通过cookie追踪技术,可以模拟HLS播放为长连接,可以实现HLS按需拉流、播放统计等业务
    • 支持HLS播发器,支持拉流HLS转rtsp/rtmp/mp4
    • 支持H264/H265/AAC/G711/OPUS编码
  • TS

    • 支持http[s]-ts直播
    • 支持ws[s]-ts直播
    • 支持H264/H265/AAC/G711/OPUS编码
  • fMP4

    • 支持http[s]-fmp4直播
    • 支持ws[s]-fmp4直播
    • 支持H264/H265/AAC/G711/OPUS编码
  • HTTP[S]与WebSocket

    • 服务器支持目录索引生成,文件下载,表单提交请求
    • 客户端提供文件下载器(支持断点续传),接口请求器,文件上传器
    • 完整HTTP API服务器,可以作为web后台开发框架
    • 支持跨域访问
    • 支持http客户端、服务器cookie
    • 支持WebSocket服务器和客户端
    • 支持http文件访问鉴权
  • GB28181与RTP推流

    • 支持UDP/TCP RTP(PS/TS/ES)推流服务器,可以转换成RTSP/RTMP/HLS等协议
    • 支持RTSP/RTMP/HLS等协议转rtp推流客户端,支持TCP/UDP模式,提供相应restful api,支持主动被动方式。
    • 支持H264/H265/AAC/G711/OPUS编码
    • 支持海康ehome推流
    • 支持GB28181主动拉流模式
  • MP4点播与录制

    • 支持录制为FLV/HLS/MP4
    • RTSP/RTMP/HTTP-FLV/WS-FLV支持MP4文件点播,支持seek
    • 支持H264/H265/AAC/G711/OPUS编码
  • WebRTC

    • 支持WebRTC推流,支持转其他协议
    • 支持WebRTC播放,支持其他协议转WebRTC
    • 支持双向echo test
    • 支持simulcast推流
    • 支持上下行rtx/nack丢包重传
    • 支持单端口、多线程、客户端网络连接迁移(开源界唯一)
    • 支持TWCC rtcp动态调整码率
    • 支持remb/pli/sr/rr rtcp
    • 支持rtp扩展解析
    • 支持GOP缓冲,webrtc播放秒开
    • 支持datachannel
  • SRT支持

  • 其他

    • 支持丰富的restful api以及web hook事件
    • 支持简单的telnet调试
    • 支持配置文件热加载
    • 支持流量统计、推拉流鉴权等事件
    • 支持虚拟主机,可以隔离不同域名
    • 支持按需拉流,无人观看自动关断拉流
    • 支持先播放后推流,提高及时推流画面打开率
    • 提供c api sdk
    • 支持FFmpeg拉流代理任意格式的流
    • 支持http api生成并返回实时截图
    • 支持按需解复用、转协议,当有人观看时才开启转协议,降低cpu占用率
    • 支持溯源模式的集群部署,溯源方式支持rtsp/rtmp/hls/http-ts, 边沿站支持hls, 源站支持多个(采用round robin方式溯源)
    • rtsp/rtmp/webrtc推流异常断开后,可以在超时时间内重连推流,播放器无感知

wvp-GB28181-pro: 开箱即用的28181协议视频平台

WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康、大华、宇视等品牌的IPC、NVR接入。支持国标级联,支持将不带国标功能的摄像机/直播流/直播推流转发到其他国标平台。

项目地址:wvp-GB28181-pro

使用文档:使用文档

应用场景:

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

基础特性:

  1. 视频预览;
  2. 云台控制(方向、缩放控制);
  3. 视频设备信息同步;
  4. 离在线监控;
  5. 录像查询与回放(基于NVR\DVR,暂不支持快进、seek操作);
  6. 无人观看自动断流;
  7. 支持UDP和TCP两种国标信令传输模式;
  8. 集成web界面, 不需要单独部署前端服务, 直接利用wvp内置文件服务部署, 随wvp一起部署;
  9. 支持平台接入, 针对大平台大量设备的情况进行优化;
  10. 支持检索,通道筛选;
  11. 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题;
  12. 支持启用udp多端口模式, 提高udp模式下媒体传输性能;
  13. 支持通道是否含有音频的设置;
  14. 支持通道子目录查询;
  15. 支持udp/tcp国标流传输模式;
  16. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址
  17. 支持国标网络校时
  18. 支持公网部署, 支持wvp与zlm分开部署
  19. 支持播放h265, g.711格式的流(需要将closeWaitRTPInfo设为false)
  20. 报警信息处理,支持向前端推送报警信息

新特性:

  1. 集成web界面, 不需要单独部署前端服务, 直接利用wvp内置文件服务部署, 随wvp一起部署;
  2. 支持平台接入, 针对大平台大量设备的情况进行优化;
  3. 支持检索,通道筛选;
  4. 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题;
  5. 支持启用udp多端口模式, 提高udp模式下媒体传输性能;
  6. 支持通道是否含有音频的设置;
  7. 支持通道子目录查询;
  8. 支持udp/tcp国标流传输模式;
  9. 支持直接输出RTSP、RTMP、HTTP-FLV、Websocket-FLV、HLS多种协议流地址
  10. 支持国标网络校时
  11. 支持公网部署, 支持wvp与zlm分开部署
  12. 支持播放h265, g.711格式的流
  13. 支持固定流地址和自动点播,同时支持未点播时直接播放流地址,代码自动发起点播. ( 查看WIKI)
  14. 报警信息处理,支持向前端推送报警信息
  15. 支持订阅与通知方法
  • 移动位置订阅
  • 移动位置通知处理
  • 报警事件订阅
  • 报警事件通知处理
  • 设备目录订阅
  • 设备目录通知处理
  • 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储

支持特性:

国标通道向上级联

  • WEB添加上级平台

  • 注册

  • 心跳保活

  • 通道选择

  • 通道推送

  • 点播

  • 云台控制

  • 平台状态查询

  • 平台信息查询

  • 平台远程启动

  • 每个级联平台可自定义的虚拟目录

  • 目录订阅与通知

  • 录像查看与播放

  • GPS订阅与通知(直播推流)

  • 添加RTSP视频

  • 添加接口鉴权

  • 添加RTMP视频

  • 云端录像(需要部署单独服务配合使用)

  • 多流媒体节点,自动选择负载最低的节点使用。

  • WEB端支持播放H264与H265,音频支持G.711A/G.711U/AAC,覆盖国标常用编码格式。

  • 支持电子地图。

  • 支持接入WGS84和GCJ02两种坐标系。

二,部署

我这里的部署方式是分开独立部署,你也可以根据 wvp-GB28181-pro项目下,docker目录下面的dockerFile,一起部署。

建议去github,去查看该文件,因为gitee上面该文件已经很久没更新了。我这里打不开github就不截图了。

在这里插入图片描述

ZLMediaKit 部署

这里采用docker部署,因为需要c++环境以及一些依赖,这里建议docker直接部署。对于docker不了解的,可以查看我之前的docker系列博客,这里就不再多撰述了

docker系列地址:docker

启动容器成功,你需要将容器内的:/opt/media/conf/config.ini 拷贝出来,到你绑定的目录

#拉取镜像
docker pull zlmediakit/zlmediakit:master#此镜像为github持续集成自动编译推送,跟代码(master分支)保持最新状态
docker run -d -p 1935:1935 -p 18180:80 -p 8554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp -p 30000-30500:30000-30500 -p 30000-30500:30000-30500/udp --name zlmediakit  --restart=always --env MODE=standalone -e TZ="Asia/Shanghai"  -v /home/docker/zlmediakit/media/conf:/opt/media/conf 12bb9d80c9a2 /bin/bash -c 'MediaServer /opt/media/conf/config.ini'
  • -d:后台运行

  • -p:绑定端口

  • -name: 容器名称

  • –restart : 自启

  • –env : 环境变量

  • -e TZ:时区

  • -v:绑定文件

  • -c : 指定文件启动

知识点:config.ini 文件,66行 mediaServerId 服务器id 是 wvp-pro 需要的,这里很重要

在这里插入图片描述

知识点:需要将你的防火墙把 ZLMediaKit 的端口全部开放,阿里云或者其他云的服务器记得把安全组的端口也放开,注意上面端口有UDP,TCP

  • linux查看开放端口列表:

     [root@localhost local]# firewall-cmd --list-ports
    
  • linux开放指定端口:

    [root@localhost local]#  firewall-cmd --zone=public --add-port=9000/tcp --permanent#关闭指定端口
    [root@localhost local]#  firewall-cmd --zone=public --remove-port=80/tcp --permanent
    
  • linux重启防火墙:

    [root@localhost local]#  firewall-cmd --reload
    

启动成功:访问localhost:18180

如下界面,即为部署成功

在这里插入图片描述

部署wvp-GB28181-pro

clone地址:https://gitee.com/pan648540858/wvp-GB28181-pro.git,将项目clone到本地

这里强烈建议去github,去clone wvp 代码,因为 gitee 上面的代码很久没有做更新了,有很多bug,我这边是自己把bug解决了,希望你在部署的时候,去 github上面去拉取在最新代码,少走一些弯路

将项目里面的mysql.sql里面的文件,创建数据库

在这里插入图片描述

修改 ProxyServletConfig.class,这里主要是将serverPort,zlmProxy,recordProxy提取出来做配置化

package com.genersoft.iot.vmp.conf;import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.service.IMediaServerService;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.mitre.dsmiley.httpproxy.ProxyServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.ConnectException;/*** @author lin*/
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@Configuration
public class ProxyServletConfig {private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class);@Autowiredprivate IMediaServerService mediaServerService;@Value("${server.port}")private int serverPort;@Value("${zlm.zlmproxy}")private String zlmProxy;@Value("${zlm.recordproxy}")private String recordProxy;@Beanpublic ServletRegistrationBean zlmServletRegistrationBean(){ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZlmProxyServlet(),"/zlm/*");servletRegistrationBean.setName("zlm_Proxy");servletRegistrationBean.addInitParameter("targetUri", zlmProxy);servletRegistrationBean.addUrlMappings();if (logger.isDebugEnabled()) {servletRegistrationBean.addInitParameter("log", "true");}return servletRegistrationBean;}class ZlmProxyServlet extends ProxyServlet{@Overrideprotected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());if (mediaInfo != null) {if (!ObjectUtils.isEmpty(queryStr)) {queryStr += "&secret=" + mediaInfo.getSecret();}else {queryStr = "secret=" + mediaInfo.getSecret();}}return queryStr;}/*** 异常处理*/@Overrideprotected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResonse, Exception e){try {super.handleRequestException(proxyRequest, proxyResonse, e);} catch (ServletException servletException) {logger.error("zlm 代理失败: ", e);} catch (IOException ioException) {if (ioException instanceof ConnectException) {logger.error("zlm 连接失败");} else if (ioException instanceof ClientAbortException) {logger.error("zlm: 用户已中断连接,代理终止");} else {logger.error("zlm 代理失败: ", e);}} catch (RuntimeException exception){logger.error("zlm 代理失败: ", e);}}/*** 对于为按照格式请求的可以直接返回404*/@Overrideprotected String getTargetUri(HttpServletRequest servletRequest) {String requestURI = servletRequest.getRequestURI();MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);String uri = null;if (mediaInfo != null) {
//                String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());}else {uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已, 其他的也可以}return uri;}/*** 动态替换请求目标*/@Overrideprotected HttpHost getTargetHost(HttpServletRequest servletRequest) {String requestURI = servletRequest.getRequestURI();MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);HttpHost host;if (mediaInfo != null) {host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort());}else {host = new HttpHost("127.0.0.1", serverPort);}return host;}/*** 根据uri获取流媒体信息*/MediaServerItem getMediaInfoByUri(String uri){String[] split = uri.split("/");String mediaServerId = split[2];if ("default".equalsIgnoreCase(mediaServerId)) {return mediaServerService.getDefaultMediaServer();}else {return mediaServerService.getOne(mediaServerId);}}/*** 去掉url中的标志信息*/@Overrideprotected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {String requestURI = servletRequest.getRequestURI();MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);String url = super.rewriteUrlFromRequest(servletRequest);if (mediaInfo == null) {logger.error("[ZLM服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI);return  url;}if (!ObjectUtils.isEmpty(mediaInfo.getId())) {url = url.replace(mediaInfo.getId() + "/", "");}return url.replace("default/", "");}}@Beanpublic ServletRegistrationBean recordServletRegistrationBean(){ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new RecordProxyServlet(),"/record_proxy/*");servletRegistrationBean.setName("record_proxy");servletRegistrationBean.addInitParameter("targetUri", recordProxy);servletRegistrationBean.addUrlMappings();if (logger.isDebugEnabled()) {servletRegistrationBean.addInitParameter("log", "true");}return servletRegistrationBean;}class RecordProxyServlet extends ProxyServlet{@Overrideprotected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());String remoteHost = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());if (mediaInfo != null) {if (!ObjectUtils.isEmpty(queryStr)) {queryStr += "&remoteHost=" + remoteHost;}else {queryStr = "remoteHost=" + remoteHost;}}return queryStr;}/*** 异常处理*/@Overrideprotected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResponse, Exception e){try {super.handleRequestException(proxyRequest, proxyResponse, e);} catch (ServletException servletException) {logger.error("录像服务 代理失败: ", e);} catch (IOException ioException) {if (ioException instanceof ConnectException) {logger.error("录像服务 连接失败");} else if (ioException instanceof ClientAbortException) {logger.error("录像服务:用户已中断连接,代理终止");} else {logger.error("录像服务 代理失败: ", e);}} catch (RuntimeException exception){logger.error("录像服务 代理失败: ", e);}}/*** 对于为按照格式请求的可以直接返回404*/@Overrideprotected String getTargetUri(HttpServletRequest servletRequest) {String requestURI = servletRequest.getRequestURI();MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);String uri = null;if (mediaInfo != null) {
//                String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getRecordAssistPort());}else {uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已, 其他的也可以}return uri;}/*** 动态替换请求目标*/@Overrideprotected HttpHost getTargetHost(HttpServletRequest servletRequest) {String requestURI = servletRequest.getRequestURI();MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);HttpHost host;if (mediaInfo != null) {host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort());}else {host = new HttpHost("127.0.0.1", serverPort);}return host;}/*** 根据uri获取流媒体信息*/MediaServerItem getMediaInfoByUri(String uri){String[] split = uri.split("/");String mediaServerId = split[2];if ("default".equalsIgnoreCase(mediaServerId)) {return mediaServerService.getDefaultMediaServer();}else {return mediaServerService.getOne(mediaServerId);}}/*** 去掉url中的标志信息*/@Overrideprotected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {String requestURI = servletRequest.getRequestURI();MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);String url = super.rewriteUrlFromRequest(servletRequest);if (mediaInfo == null) {logger.error("[录像服务访问代理],错误:处理url信息时未找到流媒体信息=>{}", requestURI);return  url;}if (!ObjectUtils.isEmpty(mediaInfo.getId())) {url = url.replace(mediaInfo.getId() + "/", "");}return url.replace("default/", "");}}}

application.yml

spring:# [可选]上传文件大小限制servlet:multipart:max-file-size: 10MBmax-request-size: 100MB# REDIS数据库配置redis:# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1host: 127.0.0.1# [必须修改] 端口号port: 6379# [可选] 数据库 DBdatabase: 8# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接password:# [可选] 超时时间timeout: 10000# mysql数据源datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/wvp_db?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=trueusername: rootpassword: 123456druid:initialSize: 10                       # 连接池初始化连接数maxActive: 200                        # 连接池最大连接数minIdle: 5                            # 连接池最小空闲连接数maxWait: 60000                        # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。keepAlive: true                       # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。validationQuery: select 1             # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。testWhileIdle: true                   # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。testOnBorrow: false                   # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。testOnReturn: false                   # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。poolPreparedStatements: false         # 是否開啟PSCache,並且指定每個連線上PSCache的大小timeBetweenEvictionRunsMillis: 60000  # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒minEvictableIdleTimeMillis: 300000    # 配置一個連線在池中最小生存的時間,單位是毫秒filters: stat,slf4j             # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4juseGlobalDataSourceStat: true         # 合并多个DruidDataSource的监控数据# 通过connectProperties属性来打开mergeSql功能;慢SQL记录connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000#stat-view-servlet.url-pattern: /admin/druid/*#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
server:port: 18080# 作为28181服务器的配置
sip:# [必须修改] 本机的IPip: 192.168.2.138# [可选] 28181服务监听的端口port: 5060# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)# 后两位为行业编码,定义参照附录D.3# 3701020049标识山东济南历下区 信息行业接入# [可选]domain: 4401020049# [可选]id: 44010200492000000001# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验password: admin123#zlm 默认服务器配置
media:id: PX5YGOUtvK56qhTq# [必须修改] zlm服务器的内网IPip: 内网IP# [必须修改] zlm服务器的http.porthttp-port: 8180# [可选] zlm服务器的hook.admin_params=secretsecret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试rtp:# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输enable: true# [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功port-range: 30000,30500 # 端口范围# [可选] 国标级联在此范围内选择端口发送媒体流,send-port-range: 30000,30500 # 端口范围# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用record-assist-port: 0
# [可选] 日志配置, 一般不需要改
logging:config: classpath:logback-spring-local.xmlzlm:zlmproxy: http://公网ip:6080recordproxy: http://公网ip:18081

使用maven 打包为jar

mvn install

部署到服务器即可

部署前端

在这里插入图片描述

web_src 打开到该目录下面,

#拉取依赖
npm install#打包
npm run build

后面使用,nginx代理部署,将前端文件里面的 index.js 后端地址,改为你的服务地址即可

访问页面

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三,配置摄像头

这里以海康为例,访问海康控制,以ip访问

在高级配置,配置,平台接入方式改为28181,其他配置对应之前的wvp-pro,application.yml, 服务器地址写你的服务器地址即可,记得开放端口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LtUrNvG3-1665241458042)(C:\Users\wuchao\AppData\Roaming\Typora\typora-user-images\image-20221008230124188.png)]

四:总结

不断去发现问题,去解决问题,你才有进步,多点细心和耐心。


http://chatgpt.dhexx.cn/article/vwjTO4HM.shtml

相关文章

java gb28181网关_视频网关GB28181协议转换解决方案

原标题:视频网关GB28181协议转换解决方案 应用需求及问题: 四川某一所学校,校园内装置有上百个摄像头,学校监控系统是RTSP协议,现在需求要把校园的监控系统视频画面接入到公安系统里, 可公安系统只支持GB-T…

GB28181协议--校时

1、简介 根据《GB/T 28181 —2016》7.10、9.10的要求,GB28181设备网络校时功能描述如下: 联网系统内的IP 网络服务器设备宜支持 NTP(见IETF RFC2030) 协议的网络统一校时服务。 网络校时设备分为时钟源和客户端, 支持客户/服务器的工作模式; 时钟源应支…

GB28181协议常见几种信令流程(一)

在监控系统中,常见的摄像机设备互联协议有国际标准的ONVIF、国标的GB28181和各厂商的私有连接协议,本章从GB28181-2016中摘抄整理常见信令流程,如28181的会话/媒体通道、SIP基本注册/注销流程、客户端主动发起视频点播流程、设备控制流程等。…

国标GB28181协议客户端开发(一)整体流程和技术选型

国标GB28181协议客户端开发(一)整体流程和技术选型 本系列文章将介绍国标GB28181协议设备端的开发过程。本文旨在探讨整体设计和技术选型方面的考虑,为开发人员提供指导和参考。文章将从设备端开发的整体架构、信令交互流程以及关键技术选型等…

java gb28181网关_国标GB28181协议对接网关

国标GB28181网关概述 国标GB28181《安全防范视频监控联网系统信息传输、交换、控制技术要求》最新版为2016年版,较2011年版更加完善,其是基于SIP协议的视频联网框架标准。因其核心应用于公安视频联网,在平安城市、雪亮工程超大规模视频监控联…

GB28181协议之录像回放

目录 一、概述 二、录像文件播放 2.1 基本要求 2.2 命令流程 2.3 抓包示例 2.3.1 Invite请求[SIP服务器---->设备] 2.3.2 Invite应答[设备---->SIP服务器] 2.3.3 ACK[SIP服务器---->设备] 2.3.4 Bye结束回放 2.3.5 Bye应答 2.3.6 播放速度控制 2.3.6 控制…

GB28181协议之实时视频

目录 一、概述 二、实时视频 2.1基本要求 2.2命令流程 2.3抓包示例 2.3.1 Invite请求[SIP服务器----->设备] 2.3.2 Invite应答[设备---->SIP服务器] 2.3.3 ACK[SIP服务器----->设备] 2.3.4 Bye 2.3.5 Bye应答 三、国标平台介绍 一、概述 近年来,国…

GB28181协议--实时视音频点播(预览)

1、基本要求 根据《GB/T 28181 —2016》第9章关于实时视音频点播的描述,其内容如下: 实时视音频点播的SIP 消息应通过本域或其他域的SIP 服务器进行路由、 转发, 目标设备的实时视音频流宜通过本域内的媒体服务器进行转发。实时视音频点播采用SIP 协议…

GB28181协议--心跳

1、心跳介绍: 根据《GBT 28181-2016 公共安全视频监控联网系统信息传输、交换、控制技术要求》9.6.1状态信息报送章节描述。 当源设备(包括网关、SIP 设备、SIP 客户端或联网系统) 发现工作异常时, 应立即向本 SIP 监控域的SIP服务器发送状态信息; 无异常时, 应定…

国标28181: 视频国标28181协议

国标的由来 GB28181国标解决平台与平台对接问题 比如A平台大连交警系统需要看B平台上海交警系统的视频。需要对接过来,实现调度视频。这时候需要知道他们取流的协议,各家厂商都自定义了一套协议,就很麻烦,因此国家就制定了GB28…

【C/C++】isalpha、islower、isupper、isalnum、isblank、isspace函数cctype / ctype.h头文件

isalpha、islower、isupper、isalnum、isblank、isspace这些函数都在<cctype>&#xff08;即C语言中的<ctype.h>&#xff09;的头文件里面&#xff0c;下图是它们所表示的范围&#xff1a; 总的来说就是&#xff1a; isalpha &#xff08;字母&#xff0c;包括大写…

细微之处见真章之StringUtils的isBlank函数细节解读

一、背景 技术群里有一个老铁分享了一段 commons-lang 的 StringUtils 工具类的代码&#xff1a; public static boolean isBlank(final CharSequence cs) {int strLen;if (cs null || (strLen cs.length()) 0) {return true;}for (int i 0; i < strLen; i) {if (Char…

字符串判空,isBlank 和 isEmpty 到底选那个?

字符串的判空&#xff0c;日常开发是经常要做的一种校验&#xff0c;common-lang包帮我们做了一些字符串判空的封装 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId> </dependency> 并对外提…

sbrk() 函数是干什么的?

brk和sbrk主要的工作是实现虚拟内存到内存的映射. 在GNU C中,内存分配是这样的: 每个进程可访问的虚拟内存空间为3G&#xff0c;但在程序编译时&#xff0c;不可能也没必要为程序分配这么大的空间&#xff0c;只分配并不大的数据段空间&#xff0c;程序中动态分配的空间就是从这…

ORACLE如何修改默认端口号

oracle在安装的的时候&#xff0c;除了可以默认端口号&#xff0c;也可以填入自定义的端口号。但是项目上会出现这样的情况&#xff0c;项目在进展时期&#xff0c;需要对数据库安全升级&#xff0c;首先要修改数据库的默认端口号。那如何来设置oracle的默认端口号&#xff0c;…

Oracle如何更改端口号

Oracle默认端口号为8080&#xff0c;因为Tomcat端口默认也是8080所以需要把Oracle端口更改一下&#xff0c;不建议更改Tomcat端口号 运行cmd命令行操作 查看Oracle版本&#xff1a; 链接Oracle数据库&#xff1a; conn system/root as sysdba&#xff0c;system/root用户名和…

Oracle 19c中默认端口

Oracle官网https://docs.oracle.com/en/database/oracle/oracle-database/19/rilin/port-numbers-and-protocols-of-oracle-components.html#GUID-D168F70C-BECE-4F9A-B616-D9103A35F1FFhttps://www.cndba.cn/hbhe0316/article/87226https://www.cndba.cn/hbhe0316/article/872…

oracle 数据库改端口

Oracle 11g修改默认端口1521为其他值 1、修改listener.ora 打开文件D:\app\Administrator\product\11.2.0\dbhome_1\NETWORK\ADMIN\listener.ora&#xff0c;修改PORT 后的数值&#xff0c;如下图 修改listener.ora文件 2、重启TNSListener服务 在Windows服务中重启OracleOr…

如何查看oracle的服务端口号

查看 oracle服务端口的步骤&#xff1a; 按住WinR键&#xff0c;弹出DOS命令窗口。 输入cmd命令&#xff0c;点击确定。 弹出的DOS窗口中&#xff0c;i输入 lsnrctl status 命令&#xff0c;并点击Enter键。 找到窗口中&#xff0c;以下文字‘监听端点概要 (DESCRIPTION…

JUC是什么?

JUC表示什么 JUC是java.util.concurrent包的缩写&#xff0c;其包结构如下。 JUC框架结构 JUC是包的简称&#xff0c;JUC可能也是Java核心里最难的一块儿&#xff0c;JUC指的是Java的并发工具包&#xff0c;里边提供了各种各样的控制同步和线程通信的工具类。学习JUC之前&a…