diff --git a/README.md b/README.md index 08a058cf2..6f2621deb 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZL # 付费社群 [![社群](doc/_media/shequ.png "shequ")](https://t.zsxq.com/0d8VAD3Dm) -> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。 +> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接自行推出,星球会直接退款给大家。 +> 星球还提供了基于主线master分支的打包, 会随时更新。 # gitee同步仓库 https://gitee.com/pan648540858/wvp-GB28181-pro.git @@ -109,9 +110,11 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git - [X] 支持Mysql,Postgresql,金仓等数据库 - [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取) + + # 非开源的内容 -- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。在[知识星球](https://t.zsxq.com/10WAnH2MP)放了试用安装包以及使用教程,没有使用时间限制,需要源码可以星球私信我或者邮箱联系。 -- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,需要源码和测试可以在星球私信联系或者发邮件给我 +- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。试用安装包以及使用教程: [知识星球](https://t.zsxq.com/10WAnH2MP),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。 +- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,试用安装包: [知识星球](https://t.zsxq.com/UJ6V3),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。 # 授权协议 diff --git a/buildPackage.sh b/buildPackage.sh new file mode 100755 index 000000000..913a0d851 --- /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/pom.xml b/pom.xml index 53bf517fd..67e0b1a2c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.17 + 2.7.18 com.genersoft diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java index 2c37a1de5..25407ed4a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/CatalogData.java @@ -1,14 +1,10 @@ package com.genersoft.iot.vmp.gb28181.bean; import lombok.Data; -import org.jetbrains.annotations.NotNull; import java.time.Instant; import java.util.HashSet; -import java.util.List; import java.util.Set; -import java.util.concurrent.Delayed; -import java.util.concurrent.TimeUnit; /** * @author lin @@ -19,7 +15,7 @@ public class CatalogData { * 命令序列号 */ private int sn; - private int total; + private Integer total; private Instant time; private Device device; private String errorMsg; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Preset.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Preset.java new file mode 100755 index 000000000..0bb8eec39 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/Preset.java @@ -0,0 +1,12 @@ +package com.genersoft.iot.vmp.gb28181.bean; + + +import lombok.Data; + +@Data +public class Preset { + + private String presetId; + + private String presetName; +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/PresetQuerySipReq.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/PresetQuerySipReq.java deleted file mode 100755 index d1971a2e2..000000000 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/PresetQuerySipReq.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.genersoft.iot.vmp.gb28181.bean; - - -/** - * @author chenjialing - */ -public class PresetQuerySipReq { - - private String presetId; - - private String presetName; - - public String getPresetId() { - return presetId; - } - - public void setPresetId(String presetId) { - this.presetId = presetId; - } - - public String getPresetName() { - return presetName; - } - - public void setPresetName(String presetName) { - this.presetName = presetName; - } -} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java index 988c2d441..0fc612ac5 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpInfo.java @@ -175,15 +175,18 @@ public class SendRtpInfo { return sendRtpItem; } - public static SendRtpInfo getInstance(Integer localPort, MediaServer mediaServer, String ip, int port, String ssrc, - String deviceId, String platformId, Integer channelId, boolean isTcp, boolean rtcp, + public static SendRtpInfo getInstance(Integer localPort, MediaServer mediaServer, String ip, Integer port, String ssrc, + String deviceId, String platformId, Integer channelId, Boolean isTcp, Boolean rtcp, String serverId) { if (localPort == 0) { return null; } SendRtpInfo sendRtpItem = new SendRtpInfo(); sendRtpItem.setIp(ip); - sendRtpItem.setPort(port); + if(port != null) { + sendRtpItem.setPort(port); + } + sendRtpItem.setSsrc(ssrc); if (deviceId != null) { sendRtpItem.setTargetId(deviceId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SyncStatus.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SyncStatus.java index 373b971cc..074a7a126 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SyncStatus.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SyncStatus.java @@ -1,51 +1,31 @@ package com.genersoft.iot.vmp.gb28181.bean; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.Instant; /** * 摄像机同步状态 * @author lin */ +@Data @Schema(description = "摄像机同步状态") public class SyncStatus { + @Schema(description = "总数") - private int total; + private Integer total; + @Schema(description = "当前更新多少") - private int current; + private Integer current; + @Schema(description = "错误描述") private String errorMsg; + @Schema(description = "是否同步中") - private boolean syncIng; + private Boolean syncIng; - public int getTotal() { - return total; - } + @Schema(description = "时间") + private Instant time; - public void setTotal(int total) { - this.total = total; - } - - public int getCurrent() { - return current; - } - - public void setCurrent(int current) { - this.current = current; - } - - public String getErrorMsg() { - return errorMsg; - } - - public void setErrorMsg(String errorMsg) { - this.errorMsg = errorMsg; - } - - public boolean isSyncIng() { - return syncIng; - } - - public void setSyncIng(boolean syncIng) { - this.syncIng = syncIng; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java index 2c09df4bc..44d11b0ba 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java @@ -28,7 +28,10 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; +import javax.servlet.http.HttpServletRequest; import javax.sip.message.Response; +import java.net.MalformedURLException; +import java.net.URL; import java.util.List; @@ -200,35 +203,44 @@ public class CommonChannelController { @Operation(summary = "播放通道", security = @SecurityRequirement(name = JwtUtils.HEADER)) @GetMapping("/play") - public DeferredResult> deleteChannelToGroupByGbDevice(Integer channelId){ + public DeferredResult> deleteChannelToGroupByGbDevice(HttpServletRequest request, Integer channelId){ Assert.notNull(channelId,"参数异常"); CommonGBChannel channel = channelService.getOne(channelId); Assert.notNull(channel, "通道不存在"); DeferredResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - ErrorCallback callback = (code, msg, data) -> { + ErrorCallback callback = (code, msg, streamInfo) -> { if (code == InviteErrorCode.SUCCESS.getCode()) { - result.setResult(WVPResult.success(new StreamContent(data))); + WVPResult wvpResult = WVPResult.success(); + if (streamInfo != null) { + if (userSetting.getUseSourceIpAsStreamIp()) { + streamInfo=streamInfo.clone();//深拷贝 + String host; + try { + URL url=new URL(request.getRequestURL().toString()); + host=url.getHost(); + } catch (MalformedURLException e) { + host=request.getLocalAddr(); + } + streamInfo.channgeStreamIp(host); + } + if (!ObjectUtils.isEmpty(streamInfo.getMediaServer().getTranscodeSuffix()) + && !"null".equalsIgnoreCase(streamInfo.getMediaServer().getTranscodeSuffix())) { + streamInfo.setStream(streamInfo.getStream() + "_" + streamInfo.getMediaServer().getTranscodeSuffix()); + } + wvpResult.setData(new StreamContent(streamInfo)); + }else { + wvpResult.setCode(code); + wvpResult.setMsg(msg); + } + + result.setResult(wvpResult); }else { result.setResult(WVPResult.fail(code, msg)); } }; - - if (channel.getGbDeviceDbId() != null) { - // 国标通道 - channelPlayService.playGbDeviceChannel(channel, callback); - } else if (channel.getStreamProxyId() != null) { - // 拉流代理 - channelPlayService.playProxy(channel, callback); - } else if (channel.getStreamPushId() != null) { - // 推流 - channelPlayService.playPush(channel, null, null, callback); - } else { - // 通道数据异常 - log.error("[点播通用通道] 通道数据异常,无法识别通道来源: {}({})", channel.getGbName(), channel.getGbDeviceId()); - throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error"); - } + channelPlayService.play(channel, null, callback); return result; } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java index f6febd83a..a63a3867a 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java @@ -144,9 +144,21 @@ public class DeviceQuery { Device device = deviceService.getDeviceByDeviceId(deviceId); boolean status = deviceService.isSyncRunning(deviceId); // 已存在则返回进度 - if (status) { + if (deviceService.isSyncRunning(deviceId)) { SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId); - return WVPResult.success(channelSyncStatus); + WVPResult wvpResult = new WVPResult(); + if (channelSyncStatus.getErrorMsg() != null) { + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg(channelSyncStatus.getErrorMsg()); + }else if (channelSyncStatus.getTotal() == null || channelSyncStatus.getTotal() == 0){ + wvpResult.setCode(ErrorCode.SUCCESS.getCode()); + wvpResult.setMsg("等待通道信息..."); + }else { + wvpResult.setCode(ErrorCode.SUCCESS.getCode()); + wvpResult.setMsg(ErrorCode.SUCCESS.getMsg()); + wvpResult.setData(channelSyncStatus); + } + return wvpResult; } deviceService.sync(device); @@ -414,15 +426,18 @@ public class DeviceQuery { SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId); WVPResult wvpResult = new WVPResult<>(); if (channelSyncStatus == null) { - wvpResult.setCode(-1); - wvpResult.setMsg("同步尚未开始"); + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg("同步不存在"); + }else if (channelSyncStatus.getErrorMsg() != null) { + wvpResult.setCode(ErrorCode.ERROR100.getCode()); + wvpResult.setMsg(channelSyncStatus.getErrorMsg()); + }else if (channelSyncStatus.getTotal() == null || channelSyncStatus.getTotal() == 0){ + wvpResult.setCode(ErrorCode.SUCCESS.getCode()); + wvpResult.setMsg("等待通道信息..."); }else { wvpResult.setCode(ErrorCode.SUCCESS.getCode()); wvpResult.setMsg(ErrorCode.SUCCESS.getMsg()); wvpResult.setData(channelSyncStatus); - if (channelSyncStatus.getErrorMsg() != null) { - wvpResult.setMsg(channelSyncStatus.getErrorMsg()); - } } return wvpResult; } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/MediaController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/MediaController.java index 545302956..2de6bdd4a 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/MediaController.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/MediaController.java @@ -18,16 +18,13 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; @Tag(name = "媒体流相关") -@Controller +@RestController @Slf4j @RequestMapping(value = "/api/media") public class MediaController { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PtzController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PtzController.java index d2773918a..8749ef48b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PtzController.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/PtzController.java @@ -24,10 +24,10 @@ import javax.sip.SipException; import java.text.ParseException; import java.util.UUID; -@Tag(name = "云台控制") +@Tag(name = "前端设备控制") @Slf4j @RestController -@RequestMapping("/api/ptz") +@RequestMapping("/api/front-end") public class PtzController { @Autowired @@ -39,30 +39,67 @@ public class PtzController { @Autowired private DeferredResultHolder resultHolder; - /*** - * 云台控制 - * @param deviceId 设备id - * @param channelId 通道id - * @param command 控制指令 - * @param horizonSpeed 水平移动速度 - * @param verticalSpeed 垂直移动速度 - * @param zoomSpeed 缩放速度 - */ + @Operation(summary = "通用前端控制命令(参考国标文档A.3.1指令格式)", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cmdCode", description = "指令码(对应国标文档指令格式中的字节4)", required = true) + @Parameter(name = "parameter1", description = "数据一(对应国标文档指令格式中的字节5, 范围0-255)", required = true) + @Parameter(name = "parameter2", description = "数据二(对应国标文档指令格式中的字节6, 范围0-255)", required = true) + @Parameter(name = "combindCode2", description = "组合码二(对应国标文档指令格式中的字节7, 范围0-16)", required = true) + @GetMapping("/common/{deviceId}/{channelId}") + public void frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,Integer cmdCode, Integer parameter1, Integer parameter2, Integer combindCode2){ + + if (log.isDebugEnabled()) { + log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,cmdCode:%d parameter1:%d parameter2:%d",deviceId, channelId, cmdCode, parameter1, parameter2)); + } + Device device = deviceService.getDeviceByDeviceId(deviceId); + + if (parameter1 == null || parameter1 < 0 || parameter1 > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter1 为 1-255的数字"); + } + if (parameter2 == null || parameter2 < 0 || parameter2 > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter1 为 1-255的数字"); + } + if (combindCode2 == null || combindCode2 < 0 || combindCode2 > 16) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter1 为 1-255的数字"); + } + try { + cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2); + } catch (SipException | InvalidArgumentException | ParseException e) { + log.error("[命令发送失败] 前端控制: {}", e.getMessage()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); + } + } @Operation(summary = "云台控制", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "deviceId", description = "设备国标编号", required = true) @Parameter(name = "channelId", description = "通道国标编号", required = true) @Parameter(name = "command", description = "控制指令,允许值: left, right, up, down, upleft, upright, downleft, downright, zoomin, zoomout, stop", required = true) - @Parameter(name = "horizonSpeed", description = "水平速度", required = true) - @Parameter(name = "verticalSpeed", description = "垂直速度", required = true) - @Parameter(name = "zoomSpeed", description = "缩放速度", required = true) - @PostMapping("/control/{deviceId}/{channelId}") - public void ptz(@PathVariable String deviceId,@PathVariable String channelId, String command, int horizonSpeed, int verticalSpeed, int zoomSpeed){ + @Parameter(name = "horizonSpeed", description = "水平速度(0-255)", required = true) + @Parameter(name = "verticalSpeed", description = "垂直速度(0-255)", required = true) + @Parameter(name = "zoomSpeed", description = "缩放速度(0-16)", required = true) + @GetMapping("/ptz/{deviceId}/{channelId}") + public void ptz(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer horizonSpeed, Integer verticalSpeed, Integer zoomSpeed){ if (log.isDebugEnabled()) { log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,command:%s ,horizonSpeed:%d ,verticalSpeed:%d ,zoomSpeed:%d",deviceId, channelId, command, horizonSpeed, verticalSpeed, zoomSpeed)); } - Device device = deviceService.getDeviceByDeviceId(deviceId); + if (horizonSpeed == null) { + horizonSpeed = 100; + }else if (horizonSpeed < 0 || horizonSpeed > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "horizonSpeed 为 1-255的数字"); + } + if (verticalSpeed == null) { + verticalSpeed = 100; + }else if (verticalSpeed < 0 || verticalSpeed > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "verticalSpeed 为 1-255的数字"); + } + if (zoomSpeed == null) { + zoomSpeed = 16; + }else if (zoomSpeed < 0 || zoomSpeed > 16) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "zoomSpeed 为 1-255的数字"); + } + int cmdCode = 0; switch (command){ case "left": @@ -103,44 +140,79 @@ public class PtzController { default: break; } - try { - cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed); - } catch (SipException | InvalidArgumentException | ParseException e) { - log.error("[命令发送失败] 云台控制: {}", e.getMessage()); - throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); - } + frontEndCommand(deviceId, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed); } - @Operation(summary = "通用前端控制命令", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Operation(summary = "光圈控制", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "deviceId", description = "设备国标编号", required = true) @Parameter(name = "channelId", description = "通道国标编号", required = true) - @Parameter(name = "cmdCode", description = "指令码", required = true) - @Parameter(name = "parameter1", description = "数据一", required = true) - @Parameter(name = "parameter2", description = "数据二", required = true) - @Parameter(name = "combindCode2", description = "组合码二", required = true) - @PostMapping("/front_end_command/{deviceId}/{channelId}") - public void frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int parameter1, int parameter2, int combindCode2){ + @Parameter(name = "command", description = "控制指令,允许值: in, out, stop", required = true) + @Parameter(name = "speed", description = "光圈速度(0-255)", required = true) + @GetMapping("/fi/iris/{deviceId}/{channelId}") + public void iris(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer speed){ if (log.isDebugEnabled()) { - log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,cmdCode:%d parameter1:%d parameter2:%d",deviceId, channelId, cmdCode, parameter1, parameter2)); + log.debug("设备光圈控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,speed:{} ",deviceId, channelId, command, speed); } - Device device = deviceService.getDeviceByDeviceId(deviceId); - try { - cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2); - } catch (SipException | InvalidArgumentException | ParseException e) { - log.error("[命令发送失败] 前端控制: {}", e.getMessage()); - throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); + int cmdCode = 0x40; + switch (command){ + case "in": + cmdCode = 0x44; + break; + case "out": + cmdCode = 0x48; + break; + case "stop": + speed = 0; + break; + default: + break; } + frontEndCommand(deviceId, channelId, cmdCode, 0, speed, 0); } + @Operation(summary = "聚焦控制", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "command", description = "控制指令,允许值: near, far, stop", required = true) + @Parameter(name = "speed", description = "聚焦速度(0-255)", required = true) + @GetMapping("/fi/focus/{deviceId}/{channelId}") + public void focus(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer speed){ - @Operation(summary = "预置位查询", security = @SecurityRequirement(name = JwtUtils.HEADER)) + if (log.isDebugEnabled()) { + log.debug("设备聚焦控制 API调用,deviceId:{} ,channelId:{} ,command:{} ,speed:{} ",deviceId, channelId, command, speed); + } + + if (speed == null) { + speed = 100; + }else if (speed < 0 || speed > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "verticalSpeed 为 1-255的数字"); + } + + int cmdCode = 0x40; + switch (command){ + case "near": + cmdCode = 0x42; + break; + case "far": + cmdCode = 0x41; + break; + case "stop": + speed = 0; + break; + default: + break; + } + frontEndCommand(deviceId, channelId, cmdCode, speed, 0, 0); + } + + @Operation(summary = "查询预置位", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "deviceId", description = "设备国标编号", required = true) @Parameter(name = "channelId", description = "通道国标编号", required = true) @GetMapping("/preset/query/{deviceId}/{channelId}") - public DeferredResult presetQueryApi(@PathVariable String deviceId, @PathVariable String channelId) { + public DeferredResult queryPreset(@PathVariable String deviceId, @PathVariable String channelId) { if (log.isDebugEnabled()) { log.debug("设备预置位查询API调用"); } @@ -175,4 +247,248 @@ public class PtzController { } return result; } + + @Operation(summary = "预置位指令-设置预置位", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "presetId", description = "预置位编号(1-255)", required = true) + @GetMapping("/preset/add/{deviceId}/{channelId}") + public void addPreset(@PathVariable String deviceId, @PathVariable String channelId, Integer presetId) { + if (presetId == null || presetId < 1 || presetId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "预置位编号必须为1-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x81, 1, presetId, 0); + } + + @Operation(summary = "预置位指令-调用预置位", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "presetId", description = "预置位编号(1-255)", required = true) + @GetMapping("/preset/call/{deviceId}/{channelId}") + public void callPreset(@PathVariable String deviceId, @PathVariable String channelId, Integer presetId) { + if (presetId == null || presetId < 1 || presetId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "预置位编号必须为1-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x82, 1, presetId, 0); + } + + @Operation(summary = "预置位指令-删除预置位", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "presetId", description = "预置位编号(1-255)", required = true) + @GetMapping("/preset/delete/{deviceId}/{channelId}") + public void deletePreset(@PathVariable String deviceId, @PathVariable String channelId, Integer presetId) { + if (presetId == null || presetId < 1 || presetId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "预置位编号必须为1-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x83, 1, presetId, 0); + } + + @Operation(summary = "巡航指令-加入巡航点", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cruiseId", description = "巡航组号(0-255)", required = true) + @Parameter(name = "presetId", description = "预置位编号(1-255)", required = true) + @GetMapping("/cruise/point/add/{deviceId}/{channelId}") + public void addCruisePoint(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer presetId) { + if (presetId == null || cruiseId == null || presetId < 1 || presetId > 255 || cruiseId < 0 || cruiseId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "编号必须为1-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x84, cruiseId, presetId, 0); + } + + @Operation(summary = "巡航指令-删除一个巡航点", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cruiseId", description = "巡航组号(1-255)", required = true) + @Parameter(name = "presetId", description = "预置位编号(0-255, 为0时删除整个巡航)", required = true) + @GetMapping("/cruise/point/delete/{deviceId}/{channelId}") + public void deleteCruisePoint(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer presetId) { + if (presetId == null || presetId < 0 || presetId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "预置位编号必须为0-255之间的数字, 为0时删除整个巡航"); + } + if (cruiseId == null || cruiseId < 0 || cruiseId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x85, cruiseId, presetId, 0); + } + + @Operation(summary = "巡航指令-设置巡航速度", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cruiseId", description = "巡航组号(0-255)", required = true) + @Parameter(name = "speed", description = "巡航速度(1-4095)", required = true) + @GetMapping("/cruise/speed/{deviceId}/{channelId}") + public void setCruiseSpeed(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer speed) { + if (cruiseId == null || cruiseId < 0 || cruiseId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航组号必须为0-255之间的数字"); + } + if (speed == null || speed < 1 || speed > 4095) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航速度必须为1-4095之间的数字"); + } + int parameter2 = speed & 0xFF; + int combindCode2 = speed >> 8; + frontEndCommand(deviceId, channelId, 0x86, cruiseId, parameter2, combindCode2); + } + + @Operation(summary = "巡航指令-设置巡航停留时间", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cruiseId", description = "巡航组号", required = true) + @Parameter(name = "time", description = "巡航停留时间(1-4095)", required = true) + @GetMapping("/cruise/time/{deviceId}/{channelId}") + public void setCruiseTime(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId, Integer time) { + if (cruiseId == null || cruiseId < 0 || cruiseId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航组号必须为0-255之间的数字"); + } + if (time == null || time < 1 || time > 4095) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航停留时间必须为1-4095之间的数字"); + } + int parameter2 = time & 0xFF; + int combindCode2 = time >> 8; + frontEndCommand(deviceId, channelId, 0x87, cruiseId, parameter2, combindCode2); + } + + @Operation(summary = "巡航指令-开始巡航", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cruiseId", description = "巡航组号)", required = true) + @GetMapping("/cruise/start/{deviceId}/{channelId}") + public void startCruise(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId) { + if (cruiseId == null || cruiseId < 0 || cruiseId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x88, cruiseId, 0, 0); + } + + @Operation(summary = "巡航指令-停止巡航", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "cruiseId", description = "巡航组号", required = true) + @GetMapping("/cruise/stop/{deviceId}/{channelId}") + public void stopCruise(@PathVariable String deviceId, @PathVariable String channelId, Integer cruiseId) { + if (cruiseId == null || cruiseId < 0 || cruiseId > 255) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "巡航组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0, 0, 0, 0); + } + + @Operation(summary = "扫描指令-开始自动扫描", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "scanId", description = "扫描组号(0-255)", required = true) + @GetMapping("/scan/start/{deviceId}/{channelId}") + public void startScan(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) { + if (scanId == null || scanId < 0 || scanId > 255 ) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x89, scanId, 0, 0); + } + + @Operation(summary = "扫描指令-停止自动扫描", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "scanId", description = "扫描组号(0-255)", required = true) + @GetMapping("/scan/stop/{deviceId}/{channelId}") + public void stopScan(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) { + if (scanId == null || scanId < 0 || scanId > 255 ) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0, 0, 0, 0); + } + + @Operation(summary = "扫描指令-设置自动扫描左边界", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "scanId", description = "扫描组号(0-255)", required = true) + @GetMapping("/scan/set/left/{deviceId}/{channelId}") + public void setScanLeft(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) { + if (scanId == null || scanId < 0 || scanId > 255 ) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x89, scanId, 1, 0); + } + + @Operation(summary = "扫描指令-设置自动扫描右边界", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "scanId", description = "扫描组号(0-255)", required = true) + @GetMapping("/scan/set/right/{deviceId}/{channelId}") + public void setScanRight(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId) { + if (scanId == null || scanId < 0 || scanId > 255 ) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为0-255之间的数字"); + } + frontEndCommand(deviceId, channelId, 0x89, scanId, 2, 0); + } + + + @Operation(summary = "扫描指令-设置自动扫描速度", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "scanId", description = "扫描组号(0-255)", required = true) + @Parameter(name = "speed", description = "自动扫描速度(1-4095)", required = true) + @GetMapping("/scan/set/speed/{deviceId}/{channelId}") + public void setScanSpeed(@PathVariable String deviceId, @PathVariable String channelId, Integer scanId, Integer speed) { + if (scanId == null || scanId < 0 || scanId > 255 ) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "扫描组号必须为0-255之间的数字"); + } + if (speed == null || speed < 1 || speed > 4095) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "自动扫描速度必须为1-4095之间的数字"); + } + int parameter2 = speed & 0xFF; + int combindCode2 = speed >> 8; + frontEndCommand(deviceId, channelId, 0x8A, scanId, parameter2, combindCode2); + } + + + @Operation(summary = "辅助开关控制指令-雨刷控制", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "command", description = "控制指令,允许值: on, off", required = true) + @GetMapping("/wiper/{deviceId}/{channelId}") + public void wiper(@PathVariable String deviceId,@PathVariable String channelId, String command){ + + if (log.isDebugEnabled()) { + log.debug("辅助开关控制指令-雨刷控制 API调用,deviceId:{} ,channelId:{} ,command:{}",deviceId, channelId, command); + } + + int cmdCode = 0; + switch (command){ + case "on": + cmdCode = 0x8c; + break; + case "off": + cmdCode = 0x8d; + break; + default: + break; + } + frontEndCommand(deviceId, channelId, cmdCode, 1, 0, 0); + } + + @Operation(summary = "辅助开关控制指令", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备国标编号", required = true) + @Parameter(name = "channelId", description = "通道国标编号", required = true) + @Parameter(name = "command", description = "控制指令,允许值: on, off", required = true) + @Parameter(name = "switchId", description = "开关编号", required = true) + @GetMapping("/auxiliary/{deviceId}/{channelId}") + public void auxiliarySwitch(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer switchId){ + + if (log.isDebugEnabled()) { + log.debug("辅助开关控制指令-雨刷控制 API调用,deviceId:{} ,channelId:{} ,command:{}, switchId: {}",deviceId, channelId, command, switchId); + } + + int cmdCode = 0; + switch (command){ + case "on": + cmdCode = 0x8c; + break; + case "off": + cmdCode = 0x8d; + break; + default: + break; + } + frontEndCommand(deviceId, channelId, cmdCode, switchId, 0, 0); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java index 8e775345f..1d0143193 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java @@ -121,6 +121,7 @@ public interface CommonGBChannelMapper { ", gb_block = #{gbBlock}" + ", gb_address = #{gbAddress}" + ", gb_parental = #{gbParental}" + + ", gb_parent_id = #{gbParentId}" + ", gb_safety_way = #{gbSafetyWay}" + ", gb_register_way = #{gbRegisterWay}" + ", gb_cert_num = #{gbCertNum}" + diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java index ea4b97174..a52632354 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceChannelMapper.java @@ -5,13 +5,11 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelReduce; import com.genersoft.iot.vmp.gb28181.dao.provider.DeviceChannelProvider; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; -import com.genersoft.iot.vmp.streamPush.bean.StreamPush; import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend; import org.apache.ibatis.annotations.*; import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Map; /** * 用于存储设备通道信息 @@ -551,7 +549,7 @@ public interface DeviceChannelMapper { "") void updateStreamGPS(List gpsMsgInfoList); - @Update("UPDATE wvp_device_channel SET status=#{status} WHERE device_id=#{deviceId} AND channel_id=#{channelId}") + @Update("UPDATE wvp_device_channel SET status=#{status} WHERE device_db_id=#{deviceDbId} AND device_id=#{deviceId}") void updateStatus(DeviceChannel channel); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java index 3df8b8878..abac64bb5 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/DeviceMapper.java @@ -330,7 +330,11 @@ public interface DeviceMapper { " FROM wvp_device de" + " where 1 = 1 "+ " AND de.on_line=${status}"+ - " AND (coalesce(custom_name, name) LIKE '%${query}%' OR device_id LIKE '%${query}%' OR ip LIKE '%${query}%') " + + " AND (" + + " coalesce(custom_name, name) LIKE concat('%',#{query},'%') escape '/' " + + " OR device_id LIKE concat('%',#{query},'%') escape '/' " + + " OR ip LIKE concat('%',#{query},'%') escape '/')" + + " " + " order by create_time desc "+ " ") List getDeviceList(@Param("query") String query, @Param("status") Boolean status); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformMapper.java index 1fe7ba2a7..b8080bb5d 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/PlatformMapper.java @@ -71,7 +71,7 @@ public interface PlatformMapper { " ) as channel_count" + " FROM wvp_platform pp where 1=1 " + " " + - " AND (pp.name LIKE concat('%',#{query},'%') OR pp.server_gb_id LIKE concat('%',#{query},'%') ) " + + " AND (pp.name LIKE concat('%',#{query},'%') escape '/' OR pp.server_gb_id LIKE concat('%',#{query},'%') escape '/' ) " + " order by pp.id desc"+ " ") List queryList(@Param("query") String query); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java index 9021916a6..f31146721 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/RegionMapper.java @@ -26,7 +26,7 @@ public interface RegionMapper { @Select(value = {" "}) @@ -79,7 +79,7 @@ public interface RegionMapper { " where " + " parent_id = #{parentId} " + " parent_id is null " + - " AND (device_id LIKE concat('%',#{query},'%') OR name LIKE concat('%',#{query},'%')) " + + " AND (device_id LIKE concat('%',#{query},'%') escape '/' OR name LIKE concat('%',#{query},'%') escape '/') " + " ") List queryForTree(@Param("query") String query, @Param("parentId") Integer parentId); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java index 9a5334ce3..c55a3ac43 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/ChannelProvider.java @@ -124,8 +124,8 @@ public class ChannelProvider { sqlBuild.append(BASE_SQL); sqlBuild.append(" where channel_type = 0 "); if (params.get("query") != null) { - sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" + - " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )") + sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%') escape '/'" + + " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') escape '/' )") ; } if (params.get("online") != null && (Boolean)params.get("online")) { @@ -158,8 +158,8 @@ public class ChannelProvider { sqlBuild.append(BASE_SQL); sqlBuild.append(" where channel_type = 0 "); if (params.get("query") != null) { - sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" + - " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )") + sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%') escape '/'" + + " OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') escape '/' )") ; } if (params.get("online") != null && (Boolean)params.get("online")) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java index dc29280e2..719ad2845 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/provider/DeviceChannelProvider.java @@ -71,8 +71,8 @@ public class DeviceChannelProvider { "OR (LENGTH(coalesce(dc.gb_device_id, dc.device_id))=LENGTH(#{civilCode}) + 2) AND coalesce(dc.gb_device_id, dc.device_id) LIKE concat(#{civilCode},'%'))"); } if (params.get("query") != null && !ObjectUtils.isEmpty(params.get("query"))) { - sqlBuild.append(" AND (coalesce(dc.gb_device_id, dc.device_id) LIKE concat('%',#{query},'%')" + - " OR coalesce(dc.gb_name, dc.name) LIKE concat('%',#{query},'%'))") + sqlBuild.append(" AND (coalesce(dc.gb_device_id, dc.device_id) LIKE concat('%',#{query},'%') escape '/'" + + " OR coalesce(dc.gb_name, dc.name) LIKE concat('%',#{query},'%') escape '/')") ; } if (params.get("online") != null && (Boolean)params.get("online")) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java index 8abb01607..4f5779396 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java @@ -10,6 +10,8 @@ public interface IGbChannelPlayService { void start(CommonGBChannel channel, InviteInfo inviteInfo, Platform platform, ErrorCallback callback); + void play(CommonGBChannel channel, Platform platform, ErrorCallback callback); + void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback callback); void playProxy(CommonGBChannel channel, ErrorCallback callback); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPTZService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPTZService.java new file mode 100755 index 000000000..d7c468052 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IPTZService.java @@ -0,0 +1,21 @@ +package com.genersoft.iot.vmp.gb28181.service; + + +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.Preset; + +import java.util.List; + +public interface IPTZService { + + + List queryPresetList(String deviceId, String channelDeviceId); + + void addPreset(Preset preset); + + void deletePreset(Integer qq); + + void ptz(Device device, String channelId, int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed); + + void frontEndCommand(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combindCode2); +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java index 198d65d10..dac640f69 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceChannelServiceImpl.java @@ -609,6 +609,11 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { parentId = channelId; } } + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = channelMapper.queryChannels(deviceDbId, civilCode, businessGroupId, parentId, query, channelType, online,null); return new PageInfo<>(all); } @@ -624,7 +629,11 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { if (device == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId); } - // 获取到所有正在播放的流 + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } PageHelper.startPage(page, count); List all = channelMapper.queryChannels(device.getId(), null,null, null, query, hasSubChannel, online,null); return new PageInfo<>(all); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java index f731ce70b..c5be6386b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/DeviceServiceImpl.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.gb28181.service.impl; +import com.alibaba.fastjson2.JSON; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.CommonCallback; import com.genersoft.iot.vmp.common.VideoManagerConstants; @@ -19,7 +20,6 @@ import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; -import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.service.IMediaServerService; @@ -34,7 +34,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.ObjectUtils; import javax.sip.InvalidArgumentException; import javax.sip.SipException; @@ -51,9 +50,6 @@ import java.util.concurrent.TimeUnit; @DS("master") public class DeviceServiceImpl implements IDeviceService { - @Autowired - private SIPCommander cmder; - @Autowired private DynamicTask dynamicTask; @@ -327,7 +323,8 @@ public class DeviceServiceImpl implements IDeviceService { @Override public void sync(Device device) { if (catalogResponseMessageHandler.isSyncRunning(device.getDeviceId())) { - log.info("开启同步时发现同步已经存在"); + SyncStatus syncStatus = catalogResponseMessageHandler.getChannelSyncProgress(device.getDeviceId()); + log.info("[同步通道] 同步已存在, 设备: {}, 同步信息: {}", device.getDeviceId(), JSON.toJSON(syncStatus)); return; } int sn = (int)((Math.random()*9+1)*100000); @@ -335,6 +332,7 @@ public class DeviceServiceImpl implements IDeviceService { try { sipCommander.catalogQuery(device, sn, event -> { String errorMsg = String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg); + log.info("[同步通道]失败,编号: {}, 错误码: {}, {}", device.getDeviceId(), event.statusCode, event.msg); catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), sn, errorMsg); }); } catch (SipException | InvalidArgumentException | ParseException e) { @@ -524,6 +522,11 @@ public class DeviceServiceImpl implements IDeviceService { @Override public PageInfo getAll(int page, int count, String query, Boolean status) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = deviceMapper.getDeviceList(query, status); return new PageInfo<>(all); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java index 01f6ff8c0..e0a736c7b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java @@ -39,20 +39,7 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { } log.info("[点播通用通道] 类型:{}, 通道: {}({})", inviteInfo.getSessionName(), channel.getGbName(), channel.getGbDeviceId()); if ("Play".equalsIgnoreCase(inviteInfo.getSessionName())) { - if (channel.getGbDeviceDbId() != null) { - // 国标通道 - playGbDeviceChannel(channel, callback); - } else if (channel.getStreamProxyId() != null) { - // 拉流代理 - playProxy(channel, callback); - } else if (channel.getStreamPushId() != null) { - // 推流 - playPush(channel, platform.getServerGBId(), platform.getName(), callback); - } else { - // 通道数据异常 - log.error("[点播通用通道] 通道数据异常,无法识别通道来源: {}({})", channel.getGbName(), channel.getGbDeviceId()); - throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error"); - } + play(channel, platform, callback); }else if ("Playback".equals(inviteInfo.getSessionName())) { if (channel.getGbDeviceDbId() != null) { // 国标通道 @@ -101,6 +88,29 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { } } + @Override + public void play(CommonGBChannel channel, Platform platform, ErrorCallback callback) { + if (channel.getGbDeviceDbId() != null) { + // 国标通道 + playGbDeviceChannel(channel, callback); + } else if (channel.getStreamProxyId() != null) { + // 拉流代理 + playProxy(channel, callback); + } else if (channel.getStreamPushId() != null) { + if (platform != null) { + // 推流 + playPush(channel, platform.getServerGBId(), platform.getName(), callback); + }else { + // 推流 + playPush(channel, null, null, callback); + } + } else { + // 通道数据异常 + log.error("[点播通用通道] 通道数据异常,无法识别通道来源: {}({})", channel.getGbName(), channel.getGbDeviceId()); + throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error"); + } + } + @Override public void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback callback){ // 国标通道 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java index 38e3bd125..f19f4f9ce 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java @@ -390,6 +390,11 @@ public class GbChannelServiceImpl implements IGbChannelService { @Override public PageInfo queryListByCivilCode(int page, int count, String query, Boolean online, Integer channelType, String civilCode) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = commonGBChannelMapper.queryListByCivilCode(query, online, channelType, civilCode); return new PageInfo<>(all); } @@ -397,6 +402,11 @@ public class GbChannelServiceImpl implements IGbChannelService { @Override public PageInfo queryListByParentId(int page, int count, String query, Boolean online, Integer channelType, String groupDeviceId) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = commonGBChannelMapper.queryListByParentId(query, online, channelType, groupDeviceId); return new PageInfo<>(all); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PTZServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PTZServiceImpl.java new file mode 100644 index 000000000..36f60510c --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PTZServiceImpl.java @@ -0,0 +1,62 @@ +package com.genersoft.iot.vmp.gb28181.service.impl; + +import com.genersoft.iot.vmp.conf.exception.ControllerException; +import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.Preset; +import com.genersoft.iot.vmp.gb28181.service.IPTZService; +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; +import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import java.text.ParseException; +import java.util.Collections; +import java.util.List; + +@Slf4j +@Service +public class PTZServiceImpl implements IPTZService { + + + @Autowired + private SIPCommander cmder; + + + @Override + public void ptz(Device device, String channelId, int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed) { + try { + cmder.frontEndCmd(device, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed); + } catch (SipException | InvalidArgumentException | ParseException e) { + log.error("[命令发送失败] 云台控制: {}", e.getMessage()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); + } + } + + @Override + public void frontEndCommand(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combindCode2) { + try { + cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2); + } catch (SipException | InvalidArgumentException | ParseException e) { + log.error("[命令发送失败] 前端控制: {}", e.getMessage()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); + } + } + + @Override + public List queryPresetList(String deviceId, String channelDeviceId) { + return Collections.emptyList(); + } + + @Override + public void addPreset(Preset preset) { + + } + + @Override + public void deletePreset(Integer qq) { + + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlatformServiceImpl.java index 19a5e56fd..bc61f1ef0 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlatformServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlatformServiceImpl.java @@ -159,6 +159,11 @@ public class PlatformServiceImpl implements IPlatformService { @Override public PageInfo queryPlatformList(int page, int count, String query) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = platformMapper.queryList(query); return new PageInfo<>(all); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java index fcc5db8fe..645a4b949 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java @@ -488,8 +488,7 @@ public class PlayServiceImpl implements IPlayService { log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId()); return; } - - + sendRtpInfo.setOnlyAudio(true); sendRtpInfo.setPt(8); sendRtpInfo.setStatus(1); @@ -518,7 +517,14 @@ public class PlayServiceImpl implements IPlayService { }, userSetting.getPlayTimeout()); try { - mediaServerService.startSendRtpPassive(mediaServerItem, sendRtpInfo, userSetting.getPlayTimeout() * 1000); + Integer localPort = mediaServerService.startSendRtpPassive(mediaServerItem, sendRtpInfo, userSetting.getPlayTimeout() * 1000); + if (localPort == null || localPort <= 0) { + timeoutCallback.run(); + mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); + sessionManager.removeByStream(sendRtpInfo.getStream()); + return; + } + sendRtpInfo.setPort(localPort); }catch (ControllerException e) { mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc()); log.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channel.getDeviceId()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/RegionServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/RegionServiceImpl.java index fc4c016be..f40d8c429 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/RegionServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/RegionServiceImpl.java @@ -97,6 +97,11 @@ public class RegionServiceImpl implements IRegionService { @Override public PageInfo query(String query, int page, int count) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List regionList = regionMapper.query(query, null); return new PageInfo<>(regionList); } @@ -140,6 +145,11 @@ public class RegionServiceImpl implements IRegionService { @Override public List queryForTree(String query, Integer parent, Boolean hasChannel) { + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List regionList = regionMapper.queryForTree(query, parent); if (parent != null && hasChannel != null && hasChannel) { Region parentRegion = regionMapper.queryOne(parent); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/CatalogDataManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/CatalogDataManager.java index d53ffaeea..049fc00e4 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/CatalogDataManager.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/CatalogDataManager.java @@ -170,11 +170,16 @@ public class CatalogDataManager implements CommandLineRunner { syncStatus.setCurrent(catalogData.getRedisKeysForChannel().size()); syncStatus.setTotal(catalogData.getTotal()); syncStatus.setErrorMsg(catalogData.getErrorMsg()); - if (catalogData.getStatus().equals(CatalogData.CatalogDataStatus.end)) { + syncStatus.setTime(catalogData.getTime()); + if (catalogData.getStatus().equals(CatalogData.CatalogDataStatus.ready) || catalogData.getStatus().equals(CatalogData.CatalogDataStatus.end)) { syncStatus.setSyncIng(false); }else { syncStatus.setSyncIng(true); } + if (catalogData.getErrorMsg() != null) { + // 失败的同步信息,返回一次后直接移除 + dataMap.remove(key); + } return syncStatus; } } @@ -237,7 +242,8 @@ public class CatalogDataManager implements CommandLineRunner { catalogData.setErrorMsg(errorMsg); } } - if (catalogData.getStatus().equals(CatalogData.CatalogDataStatus.end) && catalogData.getTime().isBefore(instantBefore30S)) { // 超过三十秒,如果标记为end则删除 + if ((catalogData.getStatus().equals(CatalogData.CatalogDataStatus.end) || catalogData.getStatus().equals(CatalogData.CatalogDataStatus.ready)) + && catalogData.getTime().isBefore(instantBefore30S)) { // 超过三十秒,如果标记为end则删除 dataMap.remove(dataKey); Set redisKeysForChannel = catalogData.getRedisKeysForChannel(); if (redisKeysForChannel != null && !redisKeysForChannel.isEmpty()) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java index 2422b8a76..aaf6eff44 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/SSRCFactory.java @@ -8,7 +8,6 @@ import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Set; /** @@ -91,17 +90,14 @@ public class SSRCFactory { * 获取后四位数SN,随机数 */ private String getSN(String mediaServerId) { - String sn = null; String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId; Long size = redisTemplate.opsForSet().size(redisKey); if (size == null || size == 0) { throw new RuntimeException("ssrc已经用完"); } else { // 在集合中移除并返回一个随机成员。 - sn = (String) redisTemplate.opsForSet().pop(redisKey); - redisTemplate.opsForSet().remove(redisKey, sn); + return redisTemplate.opsForSet().pop(redisKey); } - return sn; } /** diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 9a77d7b8c..9e5fb182b 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -142,15 +142,10 @@ public class SIPCommander implements ISIPCommander { builder.append(strTmp, 0, 2); strTmp = String.format("%02X", parameter2); builder.append(strTmp, 0, 2); - //优化zoom变倍速率 - if ((combineCode2 > 0) && (combineCode2 <16)) - { - combineCode2 = 16; - } - strTmp = String.format("%X", combineCode2); - builder.append(strTmp, 0, 1).append("0"); + strTmp = String.format("%02X", combineCode2 << 4); + builder.append(strTmp, 0, 2); //计算校验码 - int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + parameter1 + parameter2 + (combineCode2 & 0XF0)) % 0X100; + int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + parameter1 + parameter2 + (combineCode2 << 4)) % 0X100; strTmp = String.format("%02X", checkCode); builder.append(strTmp, 0, 2); return builder.toString(); @@ -986,8 +981,6 @@ public class SIPCommander implements ISIPCommander { catalogXml.append(" " + device.getDeviceId() + "\r\n"); catalogXml.append("\r\n"); - - Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 3b6dc6a82..6459841ed 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -303,7 +303,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements Media media = mediaDescription.getMedia(); Vector mediaFormats = media.getMediaFormats(false); - if (mediaFormats.contains("96")) { + if (mediaFormats.contains("96") || mediaFormats.contains("8")) { port = media.getMediaPort(); //String mediaType = media.getMediaType(); String protocol = media.getProtocol(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java index 119b0c7f0..21626d8bf 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/PresetQueryResponseMessageHandler.java @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respon import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.Platform; -import com.genersoft.iot.vmp.gb28181.bean.PresetQuerySipReq; +import com.genersoft.iot.vmp.gb28181.bean.Preset; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; @@ -79,11 +79,11 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent return; } int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num")); - List presetQuerySipReqList = new ArrayList<>(); + List presetQuerySipReqList = new ArrayList<>(); if (sumNum > 0) { for (Iterator presetIterator = presetListNumElement.elementIterator(); presetIterator.hasNext(); ) { Element itemListElement = presetIterator.next(); - PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq(); + Preset presetQuerySipReq = new Preset(); for (Iterator itemListIterator = itemListElement.elementIterator(); itemListIterator.hasNext(); ) { // 遍历item Element itemOne = itemListIterator.next(); diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java index ace469866..b8da56788 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java @@ -33,6 +33,10 @@ public class MediaInfo { private Integer width; @Schema(description = "视频高度") private Integer height; + @Schema(description = "FPS") + private Integer fps; + @Schema(description = "丢包率") + private Integer loss; @Schema(description = "音频编码类型") private String audioCodec; @Schema(description = "音频通道数") @@ -58,6 +62,7 @@ public class MediaInfo { @Schema(description = "服务ID") private String serverId; + public static MediaInfo getInstance(JSONObject jsonObject, MediaServer mediaServer, String serverId) { MediaInfo mediaInfo = new MediaInfo(); mediaInfo.setMediaServer(mediaServer); @@ -111,7 +116,14 @@ public class MediaInfo { Integer codecType = trackJson.getInteger("codec_type"); Integer sampleRate = trackJson.getInteger("sample_rate"); Integer height = trackJson.getInteger("height"); - Integer width = trackJson.getInteger("height"); + Integer width = trackJson.getInteger("width"); + Integer fps = trackJson.getInteger("fps"); + Integer loss = trackJson.getInteger("loss"); + Integer frames = trackJson.getInteger("frames"); + Long keyFrames = trackJson.getLongValue("key_frames"); + Integer gop_interval_ms = trackJson.getInteger("gop_interval_ms"); + Long gop_size = trackJson.getLongValue("gop_size"); + Long duration = trackJson.getLongValue("duration"); if (channels != null) { mediaInfo.setAudioChannels(channels); @@ -125,6 +137,12 @@ public class MediaInfo { if (width != null) { mediaInfo.setWidth(width); } + if (fps != null) { + mediaInfo.setFps(fps); + } + if (loss != null) { + mediaInfo.setLoss(loss); + } if (duration > 0L) { mediaInfo.setDuration(duration); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index c5b9d0d6b..6b2a327f5 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -58,7 +58,7 @@ public interface IMediaNodeServerService { Map getFFmpegCMDs(MediaServer mediaServer); - void startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout); + Integer startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout); void startSendRtpStream(MediaServer mediaServer, SendRtpInfo sendRtpItem); diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index 9dcbe20e9..9cf145ad3 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -142,7 +142,7 @@ public interface IMediaServerService { Boolean isStreamReady(MediaServer mediaServer, String rtp, String streamId); - void startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout); + Integer startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout); void startSendRtp(MediaServer mediaServer, SendRtpInfo sendRtpItem); diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index be99b226a..c6c597b07 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; -import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent; import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent; @@ -318,11 +317,6 @@ public class MediaServerServiceImpl implements IMediaServerService { redisTemplate.opsForHash().put(key, mediaServerInDataBase.getId(), mediaServerInDataBase); if (mediaServerInDataBase.isStatus()) { resetOnlineServerItem(mediaServerInDataBase); - }else { - // 发送事件 - MediaServerChangeEvent event = new MediaServerChangeEvent(this); - event.setMediaServerItemList(mediaServerInDataBase); - applicationEventPublisher.publishEvent(event); } } @@ -444,11 +438,6 @@ public class MediaServerServiceImpl implements IMediaServerService { mediaServerMapper.add(mediaServer); if (mediaServer.isStatus()) { mediaNodeServerService.online(mediaServer); - }else { - // 发送事件 - MediaServerChangeEvent event = new MediaServerChangeEvent(this); - event.setMediaServerItemList(mediaServer); - applicationEventPublisher.publishEvent(event); } } @@ -878,13 +867,13 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public void startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout) { + public Integer startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { log.info("[startSendRtpPassive] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类"); } - mediaNodeServerService.startSendRtpPassive(mediaServer, sendRtpItem, timeout); + return mediaNodeServerService.startSendRtpPassive(mediaServer, sendRtpItem, timeout); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 114e4c720..87aa801ea 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -118,15 +118,6 @@ public class ZLMHttpHookListener { } } - /** - * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 - */ -// @ResponseBody -// @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") -// public HookResult onStreamChanged(@RequestBody JSONObject param) { -// System.out.println(11); -// return HookResult.SUCCESS(); -// } /** * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。 */ @@ -299,7 +290,7 @@ public class ZLMHttpHookListener { @ResponseBody @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8") public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) { - log.info("[ZLM HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path()); + log.info("[ZLM HOOK] 录像完成:时长: {}, {}->{}",param.getTime_len(), param.getMediaServerId(), param.getFile_path()); try { MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index f81cb56a9..c5d6f3527 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -180,7 +180,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { if (mediaList.getInteger("code") == 0) { JSONArray data = mediaList.getJSONArray("data"); if (data == null) { - return null; + return streamInfoList; } JSONObject mediaJSON = data.getJSONObject(0); MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer, userSetting.getServerId()); @@ -329,7 +329,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public void startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout) { + public Integer startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout) { Map param = new HashMap<>(12); param.put("vhost","__defaultVhost__"); param.put("app", sendRtpItem.getApp()); @@ -361,6 +361,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { log.info("调用ZLM-TCP被动推流接口, 结果: {}", jsonObject); log.info("启动监听TCP被动推流成功[ {}/{} ],{}->{}:{}, " , sendRtpItem.getApp(), sendRtpItem.getStream(), jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port")); + return jsonObject.getInteger("local_port"); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java index ae3bd685b..8ae9e6fcd 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java @@ -1,19 +1,13 @@ package com.genersoft.iot.vmp.media.zlm.dto.hook; +import lombok.Data; + /** * zlm hook事件的参数 * @author lin */ +@Data public class HookParam { private String mediaServerId; - - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java index 8a3e084da..e117213e3 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java @@ -1,84 +1,48 @@ package com.genersoft.iot.vmp.media.zlm.dto.hook; +import lombok.Getter; +import lombok.Setter; + /** * zlm hook事件中的on_publish事件的参数 * @author lin */ + public class OnPublishHookParam extends HookParam{ + + @Getter + @Setter private String id; + + @Getter + @Setter private String app; + + @Getter + @Setter private String stream; + + @Getter + @Setter private String ip; + + @Getter + @Setter private String params; + + @Getter + @Setter private int port; + + @Getter + @Setter private String schema; + + @Getter + @Setter private String vhost; - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getApp() { - return app; - } - - public void setApp(String app) { - this.app = app; - } - - public String getStream() { - return stream; - } - - public void setStream(String stream) { - this.stream = stream; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public String getParams() { - return params; - } - - public void setParams(String params) { - this.params = params; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getSchema() { - return schema; - } - - public void setSchema(String schema) { - this.schema = schema; - } - - public String getVhost() { - return vhost; - } - - public void setVhost(String vhost) { - this.vhost = vhost; - } - @Override public String toString() { return "OnPublishHookParam{" + diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index 4c521e449..725115fcd 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -71,6 +71,11 @@ public class CloudRecordServiceImpl implements ICloudRecordService { } PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = cloudRecordServiceMapper.getList(query, app, stream, startTimeStamp, endTimeStamp, callId, mediaServerItems, null); return new PageInfo<>(all); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 1b7b43737..d979c8456 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -96,6 +96,12 @@ public class MediaServiceImpl implements IMediaService { public ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params) { // 推流鉴权的处理 if (!"rtp".equals(app)) { + if ("talk".equals(app) && stream.endsWith("_talk")) { + ResultForOnPublish result = new ResultForOnPublish(); + result.setEnable_mp4(false); + result.setEnable_audio(true); + return result; + } StreamProxy streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, stream); if (streamProxyItem != null) { ResultForOnPublish result = new ResultForOnPublish(); diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java index af1b42426..7e7ee54c3 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/CloudRecordServiceMapper.java @@ -41,7 +41,7 @@ public interface CloudRecordServiceMapper { "select * " + " from wvp_cloud_record " + " where 0 = 0" + - " AND (app LIKE concat('%',#{query},'%') OR stream LIKE concat('%',#{query},'%') ) " + + " AND (app LIKE concat('%',#{query},'%') escape '/' OR stream LIKE concat('%',#{query},'%') escape '/' ) " + " and app=#{app}" + " and stream=#{stream}" + " and end_time >= #{startTimeStamp}" + @@ -53,7 +53,7 @@ public interface CloudRecordServiceMapper { " and id in " + " #{item}" + " " + - " order by start_time ASC" + + " order by start_time desc" + " ") List getList(@Param("query") String query, @Param("app") String app, @Param("stream") String stream, @Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp, diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java index 861dea303..543043851 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/controller/StreamProxyController.java @@ -30,7 +30,7 @@ import java.util.Map; * 拉流代理接口 */ @Tag(name = "拉流代理", description = "") -@Controller +@RestController @Slf4j @RequestMapping(value = "/api/proxy") public class StreamProxyController { diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java index 551b6e3c2..82d48e212 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java @@ -48,8 +48,8 @@ public interface StreamProxyMapper { @SelectProvider(type = StreamProxyProvider.class, method = "selectOneByAppAndStream") StreamProxy selectOneByAppAndStream(@Param("app") String app, @Param("stream") String stream); - @SelectProvider(type = StreamProxyProvider.class, method = "selectForEnableInMediaServer") - List selectForEnableInMediaServer(@Param("mediaServerId") String mediaServerId, @Param("enable") boolean enable); + @SelectProvider(type = StreamProxyProvider.class, method = "selectForPushingInMediaServer") + List selectForPushingInMediaServer(@Param("mediaServerId") String mediaServerId, @Param("enable") boolean enable); @Select("select count(1) from wvp_stream_proxy") diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/provider/StreamProxyProvider.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/provider/StreamProxyProvider.java index 653426f67..6586fc647 100644 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/provider/StreamProxyProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/provider/StreamProxyProvider.java @@ -19,9 +19,8 @@ public class StreamProxyProvider { return getBaseSelectSql() + " WHERE st.id = " + params.get("id"); } - public String selectForEnableInMediaServer(Map params ){ - return getBaseSelectSql() + String.format(" WHERE st.enable=%s and st.media_server_id= '%s' order by st.create_time desc", - params.get("enable"), params.get("mediaServerId")); + public String selectForPushingInMediaServer(Map params ){ + return getBaseSelectSql() + " WHERE st.pulling=1 and st.media_server_id=#{mediaServerId} order by st.create_time desc"; } public String selectOneByAppAndStream(Map params ){ @@ -36,13 +35,13 @@ public class StreamProxyProvider { if (params.get("query") != null) { sqlBuild.append(" AND ") .append(" (") - .append(" st.app LIKE ").append("'%").append(params.get("query")).append("%'") + .append(" st.app LIKE ").append("'%").append(params.get("query")).append("%' escape '/'") .append(" OR") - .append(" st.stream LIKE ").append("'%").append(params.get("query")).append("%'") + .append(" st.stream LIKE ").append("'%").append(params.get("query")).append("%' escape '/'") .append(" OR") - .append(" wdc.gb_device_id LIKE ").append("'%").append(params.get("query")).append("%'") + .append(" wdc.gb_device_id LIKE ").append("'%").append(params.get("query")).append("%' escape '/'") .append(" OR") - .append(" wdc.gb_name LIKE ").append("'%").append(params.get("query")).append("%'") + .append(" wdc.gb_name LIKE ").append("'%").append(params.get("query")).append("%' escape '/'") .append(" )") ; } diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java index 3721edb1e..cf1818d9a 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java @@ -230,22 +230,17 @@ public class StreamProxyServiceImpl implements IStreamProxyService { gbChannelService.add(streamProxy.buildCommonGBChannel()); } } - // 判断是否需要重启代理 - if (!streamProxyInDb.getApp().equals(streamProxy.getApp()) - || !streamProxyInDb.getStream().equals(streamProxy.getStream()) - || (streamProxyInDb.getMediaServerId() != null && streamProxyInDb.getMediaServerId().equals(streamProxy.getMediaServerId())) - || (streamProxyInDb.getMediaServerId() == null && streamProxy.getMediaServerId() != null) - ) { - // 变化则重启代理 - playService.stopProxy(streamProxyInDb); - playService.startProxy(streamProxy); - } return true; } @Override public PageInfo getAll(Integer page, Integer count, String query, Boolean pulling, String mediaServerId) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = streamProxyMapper.selectAll(query, pulling, mediaServerId); return new PageInfo<>(all); } @@ -291,7 +286,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService { // 这里主要是控制数据库/redis缓存/以及zlm中存在的代理流 三者状态一致。以数据库中数据为根本 redisCatchStorage.removeStream(mediaServer.getId(), "PULL"); - List streamProxies = streamProxyMapper.selectForEnableInMediaServer(mediaServer.getId(), true); + List streamProxies = streamProxyMapper.selectForPushingInMediaServer(mediaServer.getId(), true); if (streamProxies.isEmpty()) { return; } @@ -348,18 +343,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService { streamProxyMapper.deleteByList(streamProxiesForRemove); } - if (!streamProxyMapForDb.isEmpty()) { for (StreamProxy streamProxy : streamProxyMapForDb.values()) { - log.info("恢复流代理," + streamProxy.getApp() + "/" + streamProxy.getStream()); - mediaServerService.startProxy(mediaServer, streamProxy); + streamProxyMapper.offline(streamProxy.getId()); } } } @Override public void zlmServerOffline(MediaServer mediaServer) { - List streamProxies = streamProxyMapper.selectForEnableInMediaServer(mediaServer.getId(), true); + List streamProxies = streamProxyMapper.selectForPushingInMediaServer(mediaServer.getId(), true); // 清理redis相关的缓存 redisCatchStorage.removeStream(mediaServer.getId(), "PULL"); @@ -382,11 +375,14 @@ public class StreamProxyServiceImpl implements IStreamProxyService { streamProxiesForSendMessage.add(streamProxy); } } - // 移除开启了无人观看自动移除的流 - streamProxyMapper.deleteByList(streamProxiesForRemove); - // 修改国标关联的国标通道的状态 - gbChannelService.offline(channelListForOffline); - + if (!streamProxiesForRemove.isEmpty()) { + // 移除开启了无人观看自动移除的流 + streamProxyMapper.deleteByList(streamProxiesForRemove); + } + if (!streamProxiesForRemove.isEmpty()) { + // 修改国标关联的国标通道的状态 + gbChannelService.offline(channelListForOffline); + } if (!streamProxiesForSendMessage.isEmpty()) { for (StreamProxy streamProxy : streamProxiesForSendMessage) { JSONObject jsonObject = new JSONObject(); diff --git a/src/main/java/com/genersoft/iot/vmp/streamPush/bean/StreamPush.java b/src/main/java/com/genersoft/iot/vmp/streamPush/bean/StreamPush.java index 9a9d5e983..876188aa6 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamPush/bean/StreamPush.java +++ b/src/main/java/com/genersoft/iot/vmp/streamPush/bean/StreamPush.java @@ -84,7 +84,7 @@ public class StreamPush extends CommonGBChannel implements Comparable AND (st.app LIKE concat('%',#{query},'%') OR st.stream LIKE concat('%',#{query},'%') " + - " OR wdc.gb_device_id LIKE concat('%',#{query},'%') OR wdc.gb_name LIKE concat('%',#{query},'%')) " + + " AND (st.app LIKE concat('%',#{query},'%') escape '/' OR st.stream LIKE concat('%',#{query},'%') escape '/' " + + " OR wdc.gb_device_id LIKE concat('%',#{query},'%') escape '/' OR wdc.gb_name LIKE concat('%',#{query},'%') escape '/') " + " AND st.pushing=1" + " AND st.pushing=0 " + " AND st.media_server_id=#{mediaServerId} " + diff --git a/src/main/java/com/genersoft/iot/vmp/streamPush/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/streamPush/service/impl/StreamPushServiceImpl.java index 15028e982..0c252efc2 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamPush/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/streamPush/service/impl/StreamPushServiceImpl.java @@ -175,6 +175,11 @@ public class StreamPushServiceImpl implements IStreamPushService { @Override public PageInfo getPushList(Integer page, Integer count, String query, Boolean pushing, String mediaServerId) { PageHelper.startPage(page, count); + if (query != null) { + query = query.replaceAll("/", "//") + .replaceAll("%", "/%") + .replaceAll("_", "/_"); + } List all = streamPushMapper.selectAll(query, pushing, mediaServerId); return new PageInfo<>(all); } @@ -530,7 +535,7 @@ public class StreamPushServiceImpl implements IStreamPushService { String key = streamInfo.getApp() + "_" + streamInfo.getStream(); StreamPush streamPushItem = result.get(key); if (streamPushItem == null) { - streamPushItem = streamPushItem.getInstance(streamInfo); + streamPushItem = StreamPush.getInstance(streamInfo); result.put(key, streamPushItem); } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java index ad7af6084..7292c9bd2 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java @@ -11,7 +11,9 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.JwtUtils; import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService; import com.genersoft.iot.vmp.gb28181.service.IDeviceService; +import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.media.bean.MediaServer; +import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.MediaServerLoad; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -28,6 +30,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; import oshi.SystemInfo; @@ -73,18 +76,18 @@ public class ServerController { @Autowired private IStreamPushService pushService; - @Autowired private IStreamProxyService proxyService; - @Value("${server.port}") private int serverPort; - @Autowired private IRedisCatchStorage redisCatchStorage; + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + @GetMapping(value = "/media_server/list") @ResponseBody @@ -134,13 +137,17 @@ public class ServerController { @Parameter(name = "mediaServerItem", description = "流媒体信息", required = true) @PostMapping(value = "/media_server/save") @ResponseBody - public void saveMediaServer(@RequestBody MediaServer mediaServerItem) { - MediaServer mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServerItem.getId()); + public void saveMediaServer(@RequestBody MediaServer mediaServer) { + MediaServer mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServer.getId()); if (mediaServerItemInDatabase != null) { - mediaServerService.update(mediaServerItem); + mediaServerService.update(mediaServer); } else { - mediaServerService.add(mediaServerItem); + mediaServerService.add(mediaServer); + // 发送事件 + MediaServerChangeEvent event = new MediaServerChangeEvent(this); + event.setMediaServerItemList(mediaServer); + applicationEventPublisher.publishEvent(event); } } @@ -156,6 +163,20 @@ public class ServerController { mediaServerService.delete(mediaServer); } + @Operation(summary = "获取流信息", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "app", description = "应用名", required = true) + @Parameter(name = "stream", description = "流ID", required = true) + @Parameter(name = "mediaServerId", description = "流媒体ID", required = true) + @GetMapping(value = "/media_server/media_info") + @ResponseBody + public MediaInfo getMediaInfo(String app, String stream, String mediaServerId) { + MediaServer mediaServer = mediaServerService.getOne(mediaServerId); + if (mediaServer == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "流媒体不存在"); + } + return mediaServerService.getMediaInfo(mediaServer, app, stream); + } + @Operation(summary = "重启服务", security = @SecurityRequirement(name = JwtUtils.HEADER)) @GetMapping(value = "/restart") diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java index 359d38145..c8d049529 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiDeviceController.java @@ -4,7 +4,7 @@ import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.gb28181.bean.PresetQuerySipReq; +import com.genersoft.iot.vmp.gb28181.bean.Preset; import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService; import com.genersoft.iot.vmp.gb28181.service.IDeviceService; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; @@ -215,13 +215,13 @@ public class ApiDeviceController { } deferredResultEx.setFilter(filterResult->{ - List presetQuerySipReqList = (List)filterResult; + List presetQuerySipReqList = (List)filterResult; HashMap resultMap = new HashMap<>(); resultMap.put("DeviceID", code); resultMap.put("Result", "OK"); resultMap.put("SumNum", presetQuerySipReqList.size()); ArrayList> presetItemList = new ArrayList<>(presetQuerySipReqList.size()); - for (PresetQuerySipReq presetQuerySipReq : presetQuerySipReqList) { + for (Preset presetQuerySipReq : presetQuerySipReqList) { Map item = new HashMap<>(); item.put("PresetID", presetQuerySipReq.getPresetId()); item.put("PresetName", presetQuerySipReq.getPresetName()); diff --git a/web_src/src/components/CloudRecord.vue b/web_src/src/components/CloudRecord.vue index d9f512e42..def4c2631 100755 --- a/web_src/src/components/CloudRecord.vue +++ b/web_src/src/components/CloudRecord.vue @@ -7,26 +7,28 @@
搜索: - 开始时间: 结束时间: 节点选择: - + @click="initData()">
@@ -146,14 +148,13 @@ export default { computed: {}, mounted() { this.initData(); + this.getMediaServerList(); }, destroyed() { this.$destroy('recordVideoPlayer'); }, methods: { initData: function () { - // 获取媒体节点列表 - this.getMediaServerList(); this.getRecordList(); }, currentChange: function (val) { diff --git a/web_src/src/components/DeviceList.vue b/web_src/src/components/DeviceList.vue index c34c1e7bb..7525def58 100755 --- a/web_src/src/components/DeviceList.vue +++ b/web_src/src/components/DeviceList.vue @@ -246,6 +246,15 @@ export default { type: 'error' }); } else { + if (res.data.data && res.data.data.errorMsg) { + that.$message({ + showClose: true, + message: res.data.data.errorMsg, + type: 'error' + }); + return; + } + this.$refs.syncChannelProgress.openDialog(itemData.deviceId, ()=>{ console.log(32322) this.initData() diff --git a/web_src/src/components/common/mediaInfo.vue b/web_src/src/components/common/mediaInfo.vue new file mode 100644 index 000000000..b410ce398 --- /dev/null +++ b/web_src/src/components/common/mediaInfo.vue @@ -0,0 +1,98 @@ + + + + diff --git a/web_src/src/components/common/ptzCruising.vue b/web_src/src/components/common/ptzCruising.vue new file mode 100644 index 000000000..4a280b331 --- /dev/null +++ b/web_src/src/components/common/ptzCruising.vue @@ -0,0 +1,426 @@ + + + + diff --git a/web_src/src/components/common/ptzPreset.vue b/web_src/src/components/common/ptzPreset.vue new file mode 100644 index 000000000..2a53e6acb --- /dev/null +++ b/web_src/src/components/common/ptzPreset.vue @@ -0,0 +1,212 @@ + + + + diff --git a/web_src/src/components/common/ptzScan.vue b/web_src/src/components/common/ptzScan.vue new file mode 100644 index 000000000..314d03050 --- /dev/null +++ b/web_src/src/components/common/ptzScan.vue @@ -0,0 +1,273 @@ + + + + diff --git a/web_src/src/components/common/ptzSwitch.vue b/web_src/src/components/common/ptzSwitch.vue new file mode 100644 index 000000000..856bfd7e4 --- /dev/null +++ b/web_src/src/components/common/ptzSwitch.vue @@ -0,0 +1,90 @@ + + + + diff --git a/web_src/src/components/common/ptzWiper.vue b/web_src/src/components/common/ptzWiper.vue new file mode 100644 index 000000000..8626c7904 --- /dev/null +++ b/web_src/src/components/common/ptzWiper.vue @@ -0,0 +1,70 @@ + + + + diff --git a/web_src/src/components/dialog/SyncChannelProgress.vue b/web_src/src/components/dialog/SyncChannelProgress.vue index b623d249f..f94d9743a 100755 --- a/web_src/src/components/dialog/SyncChannelProgress.vue +++ b/web_src/src/components/dialog/SyncChannelProgress.vue @@ -60,16 +60,14 @@ export default { url:`/api/device/query/${this.deviceId}/sync_status/`, }).then((res) => { if (res.data.code === 0) { - if (!this.syncFlag) { - this.syncFlag = true; - } if (res.data.data != null) { if (res.data.data.syncIng) { - if (res.data.data.total == 0) { + if (res.data.data.total === 0) { this.msg = `等待同步中`; this.timmer = setTimeout(this.getProgress, 300) }else { + this.syncFlag = true; this.total = res.data.data.total; this.current = res.data.data.current; this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100; @@ -89,6 +87,9 @@ export default { }, 3000) } } + }else { + this.msg = res.data.msg; + this.timmer = setTimeout(this.getProgress, 300) } }else { if (this.syncFlag) { diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index 0eaec92f9..9644d1c81 100755 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -26,6 +26,7 @@
+
@@ -154,148 +155,84 @@ -
-
-
- -
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+ +
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
-
-
- +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ + + + + + + -
- - 预置位编号 - - - 设置 - - 调用 - - 删除 - - 巡航速度 - - - 设置 - - 停留时间 - - - 设置 - - 巡航组编号 - - - 添加点 - - 删除点 - - 删除组 - - 巡航 - - 扫描速度 - - - 设置 - - 扫描组编号 - - - 左边界 - - 右边界 - - 扫描 - - 停止 - - + + + + +
-

- 无法播放或者没有声音?   试一试  - 转码播放 - 停止转码 -

-
-

暂无数据

-
- 流 {{ index }} -
-

格式: {{ item.codec_id_name }}

-

类型: 视频

-

分辨率: {{ item.width }} x {{ item.height }}

-

帧率: {{ item.fps }}

-
-
-

格式: {{ item.codec_id_name }}

-

类型: 音频

-

采样位数: {{ item.sample_bit }}

-

采样率: {{ item.sample_rate }}

-
-
- -
- +
@@ -327,11 +264,18 @@ import rtcPlayer from '../dialog/rtcPlayer.vue' import LivePlayer from '@liveqing/liveplayer' import crypto from 'crypto' import jessibucaPlayer from '../common/jessibuca.vue' +import PtzPreset from "../common/ptzPreset.vue"; +import PtzCruising from "../common/ptzCruising.vue"; +import ptzScan from "../common/ptzScan.vue"; +import ptzWiper from "../common/ptzWiper.vue"; +import ptzSwitch from "../common/ptzSwitch.vue"; +import mediaInfo from "../common/mediaInfo.vue"; export default { name: 'devicePlayer', props: {}, components: { + PtzPreset,PtzCruising,ptzScan,ptzWiper,ptzSwitch,mediaInfo, LivePlayer, jessibucaPlayer, rtcPlayer, }, computed: { @@ -363,9 +307,10 @@ export default { }, showVideoDialog: false, streamId: '', + ptzMethod: 'preset', + ptzPresetId: '', app: '', mediaServerId: '', - convertKey: '', deviceId: '', channelId: '', tabActiveName: 'media', @@ -384,7 +329,6 @@ export default { scanSpeed: 100, scanGroup: 0, tracks: [], - coverPlaying: false, tracksLoading: false, showPtz: true, showRrecord: true, @@ -484,63 +428,6 @@ export default { } return this.videoUrl; - }, - coverPlay: function () { - var that = this; - this.coverPlaying = true; - this.$refs[this.activePlayer].pause() - that.$axios({ - method: 'post', - url: '/api/play/convert/' + that.streamId - }).then(function (res) { - if (res.data.code === 0) { - that.convertKey = res.data.key; - setTimeout(() => { - that.isLoging = false; - that.playFromStreamInfo(false, res.data.data); - }, 2000) - } else { - that.isLoging = false; - that.coverPlaying = false; - that.$message({ - showClose: true, - message: '转码失败', - type: 'error' - }); - } - }).catch(function (e) { - console.log(e) - that.coverPlaying = false; - that.$message({ - showClose: true, - message: '播放错误', - type: 'error' - }); - }); - }, - convertStopClick: function () { - this.convertStop(() => { - this.$refs[this.activePlayer].play(this.videoUrl) - }); - }, - convertStop: function (callback) { - var that = this; - that.$refs.videoPlayer.pause() - this.$axios({ - method: 'post', - url: '/api/play/convertStop/' + this.convertKey - }).then(function (res) { - if (res.data.code == 0) { - console.log(res.data.msg) - } else { - console.error(res.data.msg) - } - if (callback) callback(); - }).catch(function (e) { - }); - that.coverPlaying = false; - that.convertKey = ""; - // if (callback )callback(); }, playFromStreamInfo: function (realHasAudio, streamInfo) { @@ -562,10 +449,6 @@ export default { this.videoUrl = ''; this.coverPlaying = false; this.showVideoDialog = false; - if (this.convertKey != '') { - this.convertStop(); - } - this.convertKey = '' this.stopBroadcast() }, @@ -595,8 +478,22 @@ export default { console.log('云台控制:' + command); let that = this; this.$axios({ - method: 'post', - url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed + method: 'get', + url: '/api/front-end/ptz/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + parseInt(this.controSpeed * 255/100) + '&verticalSpeed=' + parseInt(this.controSpeed * 255/100) + '&zoomSpeed=' + parseInt(this.controSpeed * 16/100) + }).then(function (res) { + }); + }, + irisCamera: function (command) { + this.$axios({ + method: 'get', + url: '/api/front-end/fi/iris/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&speed=' + parseInt(this.controSpeed * 255/100) + }).then(function (res) { + }); + }, + focusCamera: function (command) { + this.$axios({ + method: 'get', + url: '/api/front-end/fi/focus/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&speed=' + parseInt(this.controSpeed * 255/100) }).then(function (res) { }); }, @@ -604,35 +501,6 @@ export default { videoError: function (e) { console.log("播放器错误:" + JSON.stringify(e)); }, - presetPosition: function (cmdCode, presetPos) { - console.log('预置位控制:' + this.presetPos + ' : 0x' + cmdCode.toString(16)); - let that = this; - this.$axios({ - method: 'post', - url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '¶meter1=0¶meter2=' + presetPos + '&combindCode2=0' - }).then(function (res) { - }); - }, - setSpeedOrTime: function (cmdCode, groupNum, parameter) { - let that = this; - let parameter2 = parameter % 256; - let combindCode2 = Math.floor(parameter / 256) * 16; - console.log('前端控制:0x' + cmdCode.toString(16) + ' 0x' + groupNum.toString(16) + ' 0x' + parameter2.toString(16) + ' 0x' + combindCode2.toString(16)); - this.$axios({ - method: 'post', - url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '¶meter1=' + groupNum + '¶meter2=' + parameter2 + '&combindCode2=' + combindCode2 - }).then(function (res) { - }); - }, - setCommand: function (cmdCode, groupNum, parameter) { - let that = this; - console.log('前端控制:0x' + cmdCode.toString(16) + ' 0x' + groupNum.toString(16) + ' 0x' + parameter.toString(16) + ' 0x0'); - this.$axios({ - method: 'post', - url: '/api/ptz/front_end_command/' + this.deviceId + '/' + this.channelId + '?cmdCode=' + cmdCode + '¶meter1=' + groupNum + '¶meter2=' + parameter + '&combindCode2=0' - }).then(function (res) { - }); - }, copyUrl: function (dropdownItem) { console.log(dropdownItem) this.$copyText(dropdownItem).then((e) => { @@ -716,17 +584,6 @@ export default { recvOnly: false, }) - // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,(e)=>{//获取到了远端流,可以播放 - // console.error('播放成功',e.streams) - // this.broadcastStatus = 1; - // }); - // - // webrtcPlayer.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,(s)=>{// 获取到了本地流 - // this.broadcastStatus = 1; - // // document.getElementById('selfVideo').srcObject=s; - // // this.eventcallbacK("LOCAL STREAM", "获取到了本地流") - // }); - this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT, (e) => {// 获取到了本地流 console.error('不支持webrtc', e) this.$message({ @@ -1001,4 +858,14 @@ export default { width: 80%; padding: 0 10%; } +.el-dialog__body{ + padding: 10px 20px; +} +.ptz-btn-box { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0 2rem; + height: 3rem; + line-height: 4rem; +} diff --git a/web_src/static/css/iconfont.css b/web_src/static/css/iconfont.css index 2249c45d1..892c01a6c 100644 --- a/web_src/static/css/iconfont.css +++ b/web_src/static/css/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 1291092 */ - src: url('iconfont.woff2?t=1726109971995') format('woff2'), - url('iconfont.woff?t=1726109971995') format('woff'), - url('iconfont.ttf?t=1726109971995') format('truetype'); + src: url('iconfont.woff2?t=1731484250872') format('woff2'), + url('iconfont.woff?t=1731484250872') format('woff'), + url('iconfont.ttf?t=1731484250872') format('truetype'); } .iconfont { @@ -13,6 +13,22 @@ -moz-osx-font-smoothing: grayscale; } +.icon-bianjiao-suoxiao:before { + content: "\e8c8"; +} + +.icon-bianjiao-fangda:before { + content: "\e8c9"; +} + +.icon-guangquan-:before { + content: "\e7e9"; +} + +.icon-guangquan:before { + content: "\e7ea"; +} + .icon-a-mti-1fenpingshi:before { content: "\e7e5"; } diff --git a/web_src/static/css/iconfont.woff2 b/web_src/static/css/iconfont.woff2 index e9f9cd161..4073daf11 100644 Binary files a/web_src/static/css/iconfont.woff2 and b/web_src/static/css/iconfont.woff2 differ diff --git a/数据库/2.7.3.old/初始化-mysql-2.7.3.sql b/数据库/2.7.3.old/初始化-mysql-2.7.3.sql deleted file mode 100644 index 98d434042..000000000 --- a/数据库/2.7.3.old/初始化-mysql-2.7.3.sql +++ /dev/null @@ -1,342 +0,0 @@ -/*建表*/ -create table wvp_device ( - id serial primary key , - device_id character varying(50) not null , - name character varying(255), - manufacturer character varying(255), - model character varying(255), - firmware character varying(255), - transport character varying(50), - stream_mode character varying(50), - on_line bool default false, - register_time character varying(50), - keepalive_time character varying(50), - ip character varying(50), - create_time character varying(50), - update_time character varying(50), - port integer, - expires integer, - subscribe_cycle_for_catalog integer DEFAULT 0, - subscribe_cycle_for_mobile_position integer DEFAULT 0, - mobile_position_submission_interval integer DEFAULT 5, - subscribe_cycle_for_alarm integer DEFAULT 0, - host_address character varying(50), - charset character varying(50), - ssrc_check bool default false, - geo_coord_sys character varying(50), - media_server_id character varying(50), - custom_name character varying(255), - sdp_ip character varying(50), - local_ip character varying(50), - password character varying(255), - as_message_channel bool default false, - keepalive_interval_time integer, - broadcast_push_after_ack bool default false, - constraint uk_device_device unique (device_id) -); - -create table wvp_device_alarm ( - id serial primary key , - device_id character varying(50) not null, - channel_id character varying(50) not null, - alarm_priority character varying(50), - alarm_method character varying(50), - alarm_time character varying(50), - alarm_description character varying(255), - longitude double precision, - latitude double precision, - alarm_type character varying(50), - create_time character varying(50) not null -); - -create table wvp_device_channel ( - id serial primary key , - channel_id character varying(50) not null, - name character varying(255), - custom_name character varying(255), - manufacture character varying(50), - model character varying(50), - owner character varying(50), - civil_code character varying(50), - block character varying(50), - address character varying(50), - parent_id character varying(50), - safety_way integer, - register_way integer, - cert_num character varying(50), - certifiable integer, - err_code integer, - end_time character varying(50), - secrecy character varying(50), - ip_address character varying(50), - port integer, - password character varying(255), - ptz_type integer, - custom_ptz_type integer, - status bool default false, - longitude double precision, - custom_longitude double precision, - latitude double precision, - custom_latitude double precision, - stream_id character varying(255), - device_id character varying(50) not null, - parental character varying(50), - has_audio bool default false, - create_time character varying(50) not null, - update_time character varying(50) not null, - sub_count integer, - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - business_group_id character varying(50), - gps_time character varying(50), - stream_identification character varying(50), - constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) -); - -create table wvp_device_mobile_position ( - id serial primary key, - device_id character varying(50) not null, - channel_id character varying(50) not null, - device_name character varying(255), - time character varying(50), - longitude double precision, - latitude double precision, - altitude double precision, - speed double precision, - direction double precision, - report_source character varying(50), - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - create_time character varying(50) -); - -create table wvp_gb_stream ( - gb_stream_id serial primary key, - app character varying(255) not null, - stream character varying(255) not null, - gb_id character varying(50) not null, - name character varying(255), - longitude double precision, - latitude double precision, - stream_type character varying(50), - media_server_id character varying(50), - create_time character varying(50), - constraint uk_gb_stream_unique_gb_id unique (gb_id), - constraint uk_gb_stream_unique_app_stream unique (app, stream) -); - -create table wvp_log ( - id serial primary key , - name character varying(50), - type character varying(50), - uri character varying(200), - address character varying(50), - result character varying(50), - timing bigint, - username character varying(50), - create_time character varying(50) -); - -create table wvp_media_server ( - id character varying(255) primary key , - ip character varying(50), - hook_ip character varying(50), - sdp_ip character varying(50), - stream_ip character varying(50), - http_port integer, - http_ssl_port integer, - rtmp_port integer, - rtmp_ssl_port integer, - rtp_proxy_port integer, - rtsp_port integer, - rtsp_ssl_port integer, - flv_port integer, - flv_ssl_port integer, - ws_flv_port integer, - ws_flv_ssl_port integer, - auto_config bool default false, - secret character varying(50), - type character varying(50) default 'zlm', - rtp_enable bool default false, - rtp_port_range character varying(50), - send_rtp_port_range character varying(50), - record_assist_port integer, - default_server bool default false, - create_time character varying(50), - update_time character varying(50), - hook_alive_interval integer, - record_path character varying(255), - record_day integer default 7, - transcode_suffix character varying(255), - constraint uk_media_server_unique_ip_http_port unique (ip, http_port) -); - -create table wvp_platform ( - id serial primary key , - enable bool default false, - name character varying(255), - server_gb_id character varying(50), - server_gb_domain character varying(50), - server_ip character varying(50), - server_port integer, - device_gb_id character varying(50), - device_ip character varying(50), - device_port character varying(50), - username character varying(255), - password character varying(50), - expires character varying(50), - keep_timeout character varying(50), - transport character varying(50), - character_set character varying(50), - catalog_id character varying(50), - ptz bool default false, - rtcp bool default false, - status bool default false, - start_offline_push bool default false, - administrative_division character varying(50), - catalog_group integer, - create_time character varying(50), - update_time character varying(50), - as_message_channel bool default false, - auto_push_channel bool default false, - send_stream_ip character varying(50), - constraint uk_platform_unique_server_gb_id unique (server_gb_id) -); - -create table wvp_platform_catalog ( - id character varying(50), - platform_id character varying(50), - name character varying(255), - parent_id character varying(50), - civil_code character varying(50), - business_group_id character varying(50), - constraint uk_platform_catalog_id_platform_id unique (id, platform_id) -); - -create table wvp_platform_gb_channel ( - id serial primary key , - platform_id character varying(50), - catalog_id character varying(50), - device_channel_id integer, - constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) -); - -create table wvp_platform_gb_stream ( - id serial primary key, - platform_id character varying(50), - catalog_id character varying(50), - gb_stream_id integer, - constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) -); - -create table wvp_stream_proxy ( - id serial primary key, - type character varying(50), - app character varying(255), - stream character varying(255), - url character varying(255), - src_url character varying(255), - dst_url character varying(255), - timeout_ms integer, - ffmpeg_cmd_key character varying(255), - rtp_type character varying(50), - media_server_id character varying(50), - enable_audio bool default false, - enable_mp4 bool default false, - enable bool default false, - status boolean, - enable_remove_none_reader bool default false, - create_time character varying(50), - name character varying(255), - update_time character varying(50), - stream_key character varying(255), - enable_disable_none_reader bool default false, - constraint uk_stream_proxy_app_stream unique (app, stream) -); - -create table wvp_stream_push ( - id serial primary key, - app character varying(255), - stream character varying(255), - total_reader_count character varying(50), - origin_type integer, - origin_type_str character varying(50), - create_time character varying(50), - alive_second integer, - media_server_id character varying(50), - server_id character varying(50), - push_time character varying(50), - status bool default false, - update_time character varying(50), - push_ing bool default false, - self bool default false, - constraint uk_stream_push_app_stream unique (app, stream) -); -create table wvp_cloud_record ( - id serial primary key, - app character varying(255), - stream character varying(255), - call_id character varying(255), - start_time bigint, - end_time bigint, - media_server_id character varying(50), - file_name character varying(255), - folder character varying(255), - file_path character varying(255), - collect bool default false, - file_size bigint, - time_len bigint, - constraint uk_stream_push_app_stream_path unique (app, stream, file_path) -); - -create table wvp_user ( - id serial primary key, - username character varying(255), - password character varying(255), - role_id integer, - create_time character varying(50), - update_time character varying(50), - push_key character varying(50), - constraint uk_user_username unique (username) -); - -create table wvp_user_role ( - id serial primary key, - name character varying(50), - authority character varying(50), - create_time character varying(50), - update_time character varying(50) -); -create table wvp_resources_tree ( - id serial primary key , - is_catalog bool default true, - device_channel_id integer , - gb_stream_id integer, - name character varying(255), - parentId integer, - path character varying(255) -); - -create table wvp_user_api_key ( - id serial primary key , - user_id bigint, - app character varying(255) , - api_key text, - expired_at bigint, - remark character varying(255), - enable bool default true, - create_time character varying(50), - update_time character varying(50) -); - - -/*初始数据*/ -INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); -INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); - - - diff --git a/数据库/2.7.3.old/初始化-postgresql-kingbase-2.7.3.sql b/数据库/2.7.3.old/初始化-postgresql-kingbase-2.7.3.sql deleted file mode 100644 index eb2bc8381..000000000 --- a/数据库/2.7.3.old/初始化-postgresql-kingbase-2.7.3.sql +++ /dev/null @@ -1,342 +0,0 @@ -/*建表*/ -create table wvp_device ( - id serial primary key , - device_id character varying(50) not null , - name character varying(255), - manufacturer character varying(255), - model character varying(255), - firmware character varying(255), - transport character varying(50), - stream_mode character varying(50), - on_line bool default false, - register_time character varying(50), - keepalive_time character varying(50), - ip character varying(50), - create_time character varying(50), - update_time character varying(50), - port integer, - expires integer, - subscribe_cycle_for_catalog integer DEFAULT 0, - subscribe_cycle_for_mobile_position integer DEFAULT 0, - mobile_position_submission_interval integer DEFAULT 5, - subscribe_cycle_for_alarm integer DEFAULT 0, - host_address character varying(50), - charset character varying(50), - ssrc_check bool default false, - geo_coord_sys character varying(50), - media_server_id character varying(50), - custom_name character varying(255), - sdp_ip character varying(50), - local_ip character varying(50), - password character varying(255), - as_message_channel bool default false, - keepalive_interval_time integer, - broadcast_push_after_ack bool default false, - constraint uk_device_device unique (device_id) -); - -create table wvp_device_alarm ( - id serial primary key , - device_id character varying(50) not null, - channel_id character varying(50) not null, - alarm_priority character varying(50), - alarm_method character varying(50), - alarm_time character varying(50), - alarm_description character varying(255), - longitude double precision, - latitude double precision, - alarm_type character varying(50), - create_time character varying(50) not null -); - -create table wvp_device_channel ( - id serial primary key , - channel_id character varying(50) not null, - name character varying(255), - custom_name character varying(255), - manufacture character varying(50), - model character varying(50), - owner character varying(50), - civil_code character varying(50), - block character varying(50), - address character varying(50), - parent_id character varying(50), - safety_way integer, - register_way integer, - cert_num character varying(50), - certifiable integer, - err_code integer, - end_time character varying(50), - secrecy character varying(50), - ip_address character varying(50), - port integer, - password character varying(255), - ptz_type integer, - custom_ptz_type integer, - status bool default false, - longitude double precision, - custom_longitude double precision, - latitude double precision, - custom_latitude double precision, - stream_id character varying(255), - device_id character varying(50) not null, - parental character varying(50), - has_audio bool default false, - create_time character varying(50) not null, - update_time character varying(50) not null, - sub_count integer, - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - business_group_id character varying(50), - gps_time character varying(50), - stream_identification character varying(50), - constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id) -); - -create table wvp_device_mobile_position ( - id serial primary key, - device_id character varying(50) not null, - channel_id character varying(50) not null, - device_name character varying(255), - time character varying(50), - longitude double precision, - latitude double precision, - altitude double precision, - speed double precision, - direction double precision, - report_source character varying(50), - longitude_gcj02 double precision, - latitude_gcj02 double precision, - longitude_wgs84 double precision, - latitude_wgs84 double precision, - create_time character varying(50) -); - -create table wvp_gb_stream ( - gb_stream_id serial primary key, - app character varying(255) not null, - stream character varying(255) not null, - gb_id character varying(50) not null, - name character varying(255), - longitude double precision, - latitude double precision, - stream_type character varying(50), - media_server_id character varying(50), - create_time character varying(50), - constraint uk_gb_stream_unique_gb_id unique (gb_id), - constraint uk_gb_stream_unique_app_stream unique (app, stream) -); - -create table wvp_log ( - id serial primary key , - name character varying(50), - type character varying(50), - uri character varying(200), - address character varying(50), - result character varying(50), - timing bigint, - username character varying(50), - create_time character varying(50) -); - -create table wvp_media_server ( - id character varying(255) primary key , - ip character varying(50), - hook_ip character varying(50), - sdp_ip character varying(50), - stream_ip character varying(50), - http_port integer, - http_ssl_port integer, - rtmp_port integer, - rtmp_ssl_port integer, - rtp_proxy_port integer, - rtsp_port integer, - rtsp_ssl_port integer, - flv_port integer, - flv_ssl_port integer, - ws_flv_port integer, - ws_flv_ssl_port integer, - auto_config bool default false, - secret character varying(50), - type character varying(50) default 'zlm', - rtp_enable bool default false, - rtp_port_range character varying(50), - send_rtp_port_range character varying(50), - record_assist_port integer, - default_server bool default false, - create_time character varying(50), - update_time character varying(50), - hook_alive_interval integer, - record_path character varying(255), - record_day integer default 7, - transcode_suffix character varying(255), - constraint uk_media_server_unique_ip_http_port unique (ip, http_port) -); - -create table wvp_platform ( - id serial primary key , - enable bool default false, - name character varying(255), - server_gb_id character varying(50), - server_gb_domain character varying(50), - server_ip character varying(50), - server_port integer, - device_gb_id character varying(50), - device_ip character varying(50), - device_port character varying(50), - username character varying(255), - password character varying(50), - expires character varying(50), - keep_timeout character varying(50), - transport character varying(50), - character_set character varying(50), - catalog_id character varying(50), - ptz bool default false, - rtcp bool default false, - status bool default false, - start_offline_push bool default false, - administrative_division character varying(50), - catalog_group integer, - create_time character varying(50), - update_time character varying(50), - as_message_channel bool default false, - auto_push_channel bool default false, - send_stream_ip character varying(50), - constraint uk_platform_unique_server_gb_id unique (server_gb_id) -); - -create table wvp_platform_catalog ( - id character varying(50), - platform_id character varying(50), - name character varying(255), - parent_id character varying(50), - civil_code character varying(50), - business_group_id character varying(50), - constraint uk_platform_catalog_id_platform_id unique (id, platform_id) -); - -create table wvp_platform_gb_channel ( - id serial primary key , - platform_id character varying(50), - catalog_id character varying(50), - device_channel_id integer, - constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id) -); - -create table wvp_platform_gb_stream ( - id serial primary key, - platform_id character varying(50), - catalog_id character varying(50), - gb_stream_id integer, - constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id) -); - -create table wvp_stream_proxy ( - id serial primary key, - type character varying(50), - app character varying(255), - stream character varying(255), - url character varying(255), - src_url character varying(255), - dst_url character varying(255), - timeout_ms integer, - ffmpeg_cmd_key character varying(255), - rtp_type character varying(50), - media_server_id character varying(50), - enable_audio bool default false, - enable_mp4 bool default false, - enable bool default false, - status boolean, - enable_remove_none_reader bool default false, - create_time character varying(50), - name character varying(255), - update_time character varying(50), - stream_key character varying(255), - enable_disable_none_reader bool default false, - constraint uk_stream_proxy_app_stream unique (app, stream) -); - -create table wvp_stream_push ( - id serial primary key, - app character varying(255), - stream character varying(255), - total_reader_count character varying(50), - origin_type integer, - origin_type_str character varying(50), - create_time character varying(50), - alive_second integer, - media_server_id character varying(50), - server_id character varying(50), - push_time character varying(50), - status bool default false, - update_time character varying(50), - push_ing bool default false, - self bool default false, - constraint uk_stream_push_app_stream unique (app, stream) -); -create table wvp_cloud_record ( - id serial primary key, - app character varying(255), - stream character varying(255), - call_id character varying(255), - start_time int8, - end_time int8, - media_server_id character varying(50), - file_name character varying(255), - folder character varying(255), - file_path character varying(255), - collect bool default false, - file_size int8, - time_len int8, - constraint uk_stream_push_app_stream_path unique (app, stream, file_path) -); - -create table wvp_user ( - id serial primary key, - username character varying(255), - password character varying(255), - role_id integer, - create_time character varying(50), - update_time character varying(50), - push_key character varying(50), - constraint uk_user_username unique (username) -); - -create table wvp_user_role ( - id serial primary key, - name character varying(50), - authority character varying(50), - create_time character varying(50), - update_time character varying(50) -); -create table wvp_resources_tree ( - id serial primary key , - is_catalog bool default true, - device_channel_id integer , - gb_stream_id integer, - name character varying(255), - parentId integer, - path character varying(255) -); - -create table wvp_user_api_key ( - id serial primary key , - user_id bigint, - app character varying(255) , - api_key text, - expired_at bigint, - remark character varying(255), - enable bool default true, - create_time character varying(50), - update_time character varying(50) -); - - -/*初始数据*/ -INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); -INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57'); - - - diff --git a/数据库/2.7.3.old/更新-mysql-2.7.3.sql b/数据库/2.7.3.old/更新-mysql-2.7.3.sql deleted file mode 100644 index dff85707b..000000000 --- a/数据库/2.7.3.old/更新-mysql-2.7.3.sql +++ /dev/null @@ -1,26 +0,0 @@ -alter table wvp_media_server - add transcode_suffix character varying(255); - -alter table wvp_media_server - add type character varying(50) default 'zlm'; - -alter table wvp_media_server - add flv_port integer; -alter table wvp_media_server - add flv_ssl_port integer; -alter table wvp_media_server - add ws_flv_port integer; -alter table wvp_media_server - add ws_flv_ssl_port integer; - -create table wvp_user_api_key ( - id serial primary key , - user_id bigint, - app character varying(255) , - api_key text, - expired_at bigint, - remark character varying(255), - enable bool default true, - create_time character varying(50), - update_time character varying(50) -); \ No newline at end of file diff --git a/数据库/2.7.3.old/更新-postgresql-kingbase-2.7.3.sql b/数据库/2.7.3.old/更新-postgresql-kingbase-2.7.3.sql deleted file mode 100644 index dff85707b..000000000 --- a/数据库/2.7.3.old/更新-postgresql-kingbase-2.7.3.sql +++ /dev/null @@ -1,26 +0,0 @@ -alter table wvp_media_server - add transcode_suffix character varying(255); - -alter table wvp_media_server - add type character varying(50) default 'zlm'; - -alter table wvp_media_server - add flv_port integer; -alter table wvp_media_server - add flv_ssl_port integer; -alter table wvp_media_server - add ws_flv_port integer; -alter table wvp_media_server - add ws_flv_ssl_port integer; - -create table wvp_user_api_key ( - id serial primary key , - user_id bigint, - app character varying(255) , - api_key text, - expired_at bigint, - remark character varying(255), - enable bool default true, - create_time character varying(50), - update_time character varying(50) -); \ No newline at end of file