mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-06-19 01:37:49 +08:00
Merge branch 'master' into 重构/1078
This commit is contained in:
commit
f528735119
@ -28,7 +28,8 @@ ZLM使用文档 [https://github.com/ZLMediaKit/ZLMediaKit](https://github.com/ZL
|
|||||||
|
|
||||||
# 付费社群
|
# 付费社群
|
||||||
[](https://t.zsxq.com/0d8VAD3Dm)
|
[](https://t.zsxq.com/0d8VAD3Dm)
|
||||||
> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接退款,大家不需要有顾虑,来白嫖三天也不是不可以。
|
> 收费是为了提供更好的服务,也是对作者更大的激励。加入星球的用户三天后可以私信我留下微信号,我会拉大家入群。加入三天内不满意可以直接自行推出,星球会直接退款给大家。
|
||||||
|
> 星球还提供了基于主线master分支的打包, 会随时更新。
|
||||||
|
|
||||||
# gitee同步仓库
|
# gitee同步仓库
|
||||||
https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
||||||
@ -109,9 +110,11 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
|||||||
- [X] 支持Mysql,Postgresql,金仓等数据库
|
- [X] 支持Mysql,Postgresql,金仓等数据库
|
||||||
- [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取)
|
- [X] 支持Onvif(目前在onvif分支,需要安装onvif服务,服务请在知识星球获取)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 非开源的内容
|
# 非开源的内容
|
||||||
- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。在[知识星球](https://t.zsxq.com/10WAnH2MP)放了试用安装包以及使用教程,没有使用时间限制,需要源码可以星球私信我或者邮箱联系。
|
- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。试用安装包以及使用教程: [知识星球](https://t.zsxq.com/10WAnH2MP),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。
|
||||||
- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,需要源码和测试可以在星球私信联系或者发邮件给我
|
- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,试用安装包: [知识星球](https://t.zsxq.com/UJ6V3),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。
|
||||||
|
|
||||||
|
|
||||||
# 授权协议
|
# 授权协议
|
||||||
|
|||||||
20
buildPackage.sh
Executable file
20
buildPackage.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 获取当前日期并格式化为 YYYY-MM-DD 的形式
|
||||||
|
current_date=$(date +"%Y-%m-%d")
|
||||||
|
|
||||||
|
mkdir -p "$current_date"/数据库
|
||||||
|
|
||||||
|
cp -r ./数据库/2.7.3 "$current_date"/数据库
|
||||||
|
|
||||||
|
cp src/main/resources/配置详情.yml "$current_date"
|
||||||
|
cp src/main/resources/application-dev.yml "$current_date"/application.yml
|
||||||
|
|
||||||
|
cp ./target/wvp-pro-*.jar "$current_date"
|
||||||
|
|
||||||
|
zip -r "$current_date".zip "$current_date"
|
||||||
|
|
||||||
|
rm -rf "$current_date"
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>2.7.17</version>
|
<version>2.7.18</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.genersoft</groupId>
|
<groupId>com.genersoft</groupId>
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.bean;
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Delayed;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lin
|
* @author lin
|
||||||
@ -19,7 +15,7 @@ public class CatalogData {
|
|||||||
* 命令序列号
|
* 命令序列号
|
||||||
*/
|
*/
|
||||||
private int sn;
|
private int sn;
|
||||||
private int total;
|
private Integer total;
|
||||||
private Instant time;
|
private Instant time;
|
||||||
private Device device;
|
private Device device;
|
||||||
private String errorMsg;
|
private String errorMsg;
|
||||||
|
|||||||
12
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Preset.java
Executable file
12
src/main/java/com/genersoft/iot/vmp/gb28181/bean/Preset.java
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Preset {
|
||||||
|
|
||||||
|
private String presetId;
|
||||||
|
|
||||||
|
private String presetName;
|
||||||
|
}
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -175,15 +175,18 @@ public class SendRtpInfo {
|
|||||||
return sendRtpItem;
|
return sendRtpItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SendRtpInfo getInstance(Integer localPort, MediaServer mediaServer, String ip, int port, String ssrc,
|
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 deviceId, String platformId, Integer channelId, Boolean isTcp, Boolean rtcp,
|
||||||
String serverId) {
|
String serverId) {
|
||||||
if (localPort == 0) {
|
if (localPort == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
SendRtpInfo sendRtpItem = new SendRtpInfo();
|
SendRtpInfo sendRtpItem = new SendRtpInfo();
|
||||||
sendRtpItem.setIp(ip);
|
sendRtpItem.setIp(ip);
|
||||||
sendRtpItem.setPort(port);
|
if(port != null) {
|
||||||
|
sendRtpItem.setPort(port);
|
||||||
|
}
|
||||||
|
|
||||||
sendRtpItem.setSsrc(ssrc);
|
sendRtpItem.setSsrc(ssrc);
|
||||||
if (deviceId != null) {
|
if (deviceId != null) {
|
||||||
sendRtpItem.setTargetId(deviceId);
|
sendRtpItem.setTargetId(deviceId);
|
||||||
|
|||||||
@ -1,51 +1,31 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.bean;
|
package com.genersoft.iot.vmp.gb28181.bean;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 摄像机同步状态
|
* 摄像机同步状态
|
||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
@Schema(description = "摄像机同步状态")
|
@Schema(description = "摄像机同步状态")
|
||||||
public class SyncStatus {
|
public class SyncStatus {
|
||||||
|
|
||||||
@Schema(description = "总数")
|
@Schema(description = "总数")
|
||||||
private int total;
|
private Integer total;
|
||||||
|
|
||||||
@Schema(description = "当前更新多少")
|
@Schema(description = "当前更新多少")
|
||||||
private int current;
|
private Integer current;
|
||||||
|
|
||||||
@Schema(description = "错误描述")
|
@Schema(description = "错误描述")
|
||||||
private String errorMsg;
|
private String errorMsg;
|
||||||
|
|
||||||
@Schema(description = "是否同步中")
|
@Schema(description = "是否同步中")
|
||||||
private boolean syncIng;
|
private Boolean syncIng;
|
||||||
|
|
||||||
public int getTotal() {
|
@Schema(description = "时间")
|
||||||
return total;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,10 @@ import org.springframework.util.ObjectUtils;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.context.request.async.DeferredResult;
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@ -200,35 +203,44 @@ public class CommonChannelController {
|
|||||||
|
|
||||||
@Operation(summary = "播放通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
@Operation(summary = "播放通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@GetMapping("/play")
|
@GetMapping("/play")
|
||||||
public DeferredResult<WVPResult<StreamContent>> deleteChannelToGroupByGbDevice(Integer channelId){
|
public DeferredResult<WVPResult<StreamContent>> deleteChannelToGroupByGbDevice(HttpServletRequest request, Integer channelId){
|
||||||
Assert.notNull(channelId,"参数异常");
|
Assert.notNull(channelId,"参数异常");
|
||||||
CommonGBChannel channel = channelService.getOne(channelId);
|
CommonGBChannel channel = channelService.getOne(channelId);
|
||||||
Assert.notNull(channel, "通道不存在");
|
Assert.notNull(channel, "通道不存在");
|
||||||
|
|
||||||
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
||||||
|
|
||||||
ErrorCallback<StreamInfo> callback = (code, msg, data) -> {
|
ErrorCallback<StreamInfo> callback = (code, msg, streamInfo) -> {
|
||||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||||
result.setResult(WVPResult.success(new StreamContent(data)));
|
WVPResult<StreamContent> 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 {
|
}else {
|
||||||
result.setResult(WVPResult.fail(code, msg));
|
result.setResult(WVPResult.fail(code, msg));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
channelPlayService.play(channel, null, callback);
|
||||||
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");
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -144,9 +144,21 @@ public class DeviceQuery {
|
|||||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||||
boolean status = deviceService.isSyncRunning(deviceId);
|
boolean status = deviceService.isSyncRunning(deviceId);
|
||||||
// 已存在则返回进度
|
// 已存在则返回进度
|
||||||
if (status) {
|
if (deviceService.isSyncRunning(deviceId)) {
|
||||||
SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(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);
|
deviceService.sync(device);
|
||||||
|
|
||||||
@ -414,15 +426,18 @@ public class DeviceQuery {
|
|||||||
SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);
|
SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);
|
||||||
WVPResult<SyncStatus> wvpResult = new WVPResult<>();
|
WVPResult<SyncStatus> wvpResult = new WVPResult<>();
|
||||||
if (channelSyncStatus == null) {
|
if (channelSyncStatus == null) {
|
||||||
wvpResult.setCode(-1);
|
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||||
wvpResult.setMsg("同步尚未开始");
|
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 {
|
}else {
|
||||||
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
||||||
wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
||||||
wvpResult.setData(channelSyncStatus);
|
wvpResult.setData(channelSyncStatus);
|
||||||
if (channelSyncStatus.getErrorMsg() != null) {
|
|
||||||
wvpResult.setMsg(channelSyncStatus.getErrorMsg());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return wvpResult;
|
return wvpResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,16 +18,13 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
|
||||||
@Tag(name = "媒体流相关")
|
@Tag(name = "媒体流相关")
|
||||||
@Controller
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequestMapping(value = "/api/media")
|
@RequestMapping(value = "/api/media")
|
||||||
public class MediaController {
|
public class MediaController {
|
||||||
|
|||||||
@ -24,10 +24,10 @@ import javax.sip.SipException;
|
|||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Tag(name = "云台控制")
|
@Tag(name = "前端设备控制")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/ptz")
|
@RequestMapping("/api/front-end")
|
||||||
public class PtzController {
|
public class PtzController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -39,30 +39,67 @@ public class PtzController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private DeferredResultHolder resultHolder;
|
private DeferredResultHolder resultHolder;
|
||||||
|
|
||||||
/***
|
@Operation(summary = "通用前端控制命令(参考国标文档A.3.1指令格式)", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
* 云台控制
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
* @param deviceId 设备id
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
* @param channelId 通道id
|
@Parameter(name = "cmdCode", description = "指令码(对应国标文档指令格式中的字节4)", required = true)
|
||||||
* @param command 控制指令
|
@Parameter(name = "parameter1", description = "数据一(对应国标文档指令格式中的字节5, 范围0-255)", required = true)
|
||||||
* @param horizonSpeed 水平移动速度
|
@Parameter(name = "parameter2", description = "数据二(对应国标文档指令格式中的字节6, 范围0-255)", required = true)
|
||||||
* @param verticalSpeed 垂直移动速度
|
@Parameter(name = "combindCode2", description = "组合码二(对应国标文档指令格式中的字节7, 范围0-16)", required = true)
|
||||||
* @param zoomSpeed 缩放速度
|
@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))
|
@Operation(summary = "云台控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", 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 = "command", description = "控制指令,允许值: left, right, up, down, upleft, upright, downleft, downright, zoomin, zoomout, stop", required = true)
|
||||||
@Parameter(name = "horizonSpeed", description = "水平速度", required = true)
|
@Parameter(name = "horizonSpeed", description = "水平速度(0-255)", required = true)
|
||||||
@Parameter(name = "verticalSpeed", description = "垂直速度", required = true)
|
@Parameter(name = "verticalSpeed", description = "垂直速度(0-255)", required = true)
|
||||||
@Parameter(name = "zoomSpeed", description = "缩放速度", required = true)
|
@Parameter(name = "zoomSpeed", description = "缩放速度(0-16)", required = true)
|
||||||
@PostMapping("/control/{deviceId}/{channelId}")
|
@GetMapping("/ptz/{deviceId}/{channelId}")
|
||||||
public void ptz(@PathVariable String deviceId,@PathVariable String channelId, String command, int horizonSpeed, int verticalSpeed, int zoomSpeed){
|
public void ptz(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer horizonSpeed, Integer verticalSpeed, Integer zoomSpeed){
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
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));
|
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;
|
int cmdCode = 0;
|
||||||
switch (command){
|
switch (command){
|
||||||
case "left":
|
case "left":
|
||||||
@ -103,44 +140,79 @@ public class PtzController {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
frontEndCommand(deviceId, channelId, cmdCode, horizonSpeed, verticalSpeed, zoomSpeed);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Operation(summary = "通用前端控制命令", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
@Operation(summary = "光圈控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
@Parameter(name = "cmdCode", description = "指令码", required = true)
|
@Parameter(name = "command", description = "控制指令,允许值: in, out, stop", required = true)
|
||||||
@Parameter(name = "parameter1", description = "数据一", required = true)
|
@Parameter(name = "speed", description = "光圈速度(0-255)", required = true)
|
||||||
@Parameter(name = "parameter2", description = "数据二", required = true)
|
@GetMapping("/fi/iris/{deviceId}/{channelId}")
|
||||||
@Parameter(name = "combindCode2", description = "组合码二", required = true)
|
public void iris(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer speed){
|
||||||
@PostMapping("/front_end_command/{deviceId}/{channelId}")
|
|
||||||
public void frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int parameter1, int parameter2, int combindCode2){
|
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
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 {
|
int cmdCode = 0x40;
|
||||||
cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
|
switch (command){
|
||||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
case "in":
|
||||||
log.error("[命令发送失败] 前端控制: {}", e.getMessage());
|
cmdCode = 0x44;
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
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 = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
@GetMapping("/preset/query/{deviceId}/{channelId}")
|
@GetMapping("/preset/query/{deviceId}/{channelId}")
|
||||||
public DeferredResult<String> presetQueryApi(@PathVariable String deviceId, @PathVariable String channelId) {
|
public DeferredResult<String> queryPreset(@PathVariable String deviceId, @PathVariable String channelId) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("设备预置位查询API调用");
|
log.debug("设备预置位查询API调用");
|
||||||
}
|
}
|
||||||
@ -175,4 +247,248 @@ public class PtzController {
|
|||||||
}
|
}
|
||||||
return result;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,6 +121,7 @@ public interface CommonGBChannelMapper {
|
|||||||
", gb_block = #{gbBlock}" +
|
", gb_block = #{gbBlock}" +
|
||||||
", gb_address = #{gbAddress}" +
|
", gb_address = #{gbAddress}" +
|
||||||
", gb_parental = #{gbParental}" +
|
", gb_parental = #{gbParental}" +
|
||||||
|
", gb_parent_id = #{gbParentId}" +
|
||||||
", gb_safety_way = #{gbSafetyWay}" +
|
", gb_safety_way = #{gbSafetyWay}" +
|
||||||
", gb_register_way = #{gbRegisterWay}" +
|
", gb_register_way = #{gbRegisterWay}" +
|
||||||
", gb_cert_num = #{gbCertNum}" +
|
", gb_cert_num = #{gbCertNum}" +
|
||||||
|
|||||||
@ -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.controller.bean.ChannelReduce;
|
||||||
import com.genersoft.iot.vmp.gb28181.dao.provider.DeviceChannelProvider;
|
import com.genersoft.iot.vmp.gb28181.dao.provider.DeviceChannelProvider;
|
||||||
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
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 com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
|
||||||
import org.apache.ibatis.annotations.*;
|
import org.apache.ibatis.annotations.*;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于存储设备通道信息
|
* 用于存储设备通道信息
|
||||||
@ -551,7 +549,7 @@ public interface DeviceChannelMapper {
|
|||||||
"</script>")
|
"</script>")
|
||||||
void updateStreamGPS(List<GPSMsgInfo> gpsMsgInfoList);
|
void updateStreamGPS(List<GPSMsgInfo> 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);
|
void updateStatus(DeviceChannel channel);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -330,7 +330,11 @@ public interface DeviceMapper {
|
|||||||
" FROM wvp_device de" +
|
" FROM wvp_device de" +
|
||||||
" where 1 = 1 "+
|
" where 1 = 1 "+
|
||||||
" <if test='status != null'> AND de.on_line=${status}</if>"+
|
" <if test='status != null'> AND de.on_line=${status}</if>"+
|
||||||
" <if test='query != null'> AND (coalesce(custom_name, name) LIKE '%${query}%' OR device_id LIKE '%${query}%' OR ip LIKE '%${query}%')</if> " +
|
" <if test='query != null'> AND (" +
|
||||||
|
" coalesce(custom_name, name) LIKE concat('%',#{query},'%') escape '/' " +
|
||||||
|
" OR device_id LIKE concat('%',#{query},'%') escape '/' " +
|
||||||
|
" OR ip LIKE concat('%',#{query},'%') escape '/')" +
|
||||||
|
"</if> " +
|
||||||
" order by create_time desc "+
|
" order by create_time desc "+
|
||||||
" </script>")
|
" </script>")
|
||||||
List<Device> getDeviceList(@Param("query") String query, @Param("status") Boolean status);
|
List<Device> getDeviceList(@Param("query") String query, @Param("status") Boolean status);
|
||||||
|
|||||||
@ -71,7 +71,7 @@ public interface PlatformMapper {
|
|||||||
" ) as channel_count" +
|
" ) as channel_count" +
|
||||||
" FROM wvp_platform pp where 1=1 " +
|
" FROM wvp_platform pp where 1=1 " +
|
||||||
" <if test='query != null'> " +
|
" <if test='query != null'> " +
|
||||||
" AND (pp.name LIKE concat('%',#{query},'%') OR pp.server_gb_id LIKE concat('%',#{query},'%') )</if> " +
|
" AND (pp.name LIKE concat('%',#{query},'%') escape '/' OR pp.server_gb_id LIKE concat('%',#{query},'%') escape '/' )</if> " +
|
||||||
" order by pp.id desc"+
|
" order by pp.id desc"+
|
||||||
" </script>")
|
" </script>")
|
||||||
List<Platform> queryList(@Param("query") String query);
|
List<Platform> queryList(@Param("query") String query);
|
||||||
|
|||||||
@ -26,7 +26,7 @@ public interface RegionMapper {
|
|||||||
|
|
||||||
@Select(value = {" <script>" +
|
@Select(value = {" <script>" +
|
||||||
"SELECT * from wvp_common_region WHERE 1=1 " +
|
"SELECT * from wvp_common_region WHERE 1=1 " +
|
||||||
" <if test='query != null'> AND (device_id LIKE concat('%',#{query},'%') OR name LIKE concat('%',#{query},'%'))</if> " +
|
" <if test='query != null'> AND (device_id LIKE concat('%',#{query},'%') escape '/' OR name LIKE concat('%',#{query},'%') escape '/')</if> " +
|
||||||
" <if test='parentId != null'> AND parent_device_id = #{parentId}</if> " +
|
" <if test='parentId != null'> AND parent_device_id = #{parentId}</if> " +
|
||||||
"ORDER BY id " +
|
"ORDER BY id " +
|
||||||
" </script>"})
|
" </script>"})
|
||||||
@ -79,7 +79,7 @@ public interface RegionMapper {
|
|||||||
" where " +
|
" where " +
|
||||||
" <if test='parentId != null'> parent_id = #{parentId} </if> " +
|
" <if test='parentId != null'> parent_id = #{parentId} </if> " +
|
||||||
" <if test='parentId == null'> parent_id is null </if> " +
|
" <if test='parentId == null'> parent_id is null </if> " +
|
||||||
" <if test='query != null'> AND (device_id LIKE concat('%',#{query},'%') OR name LIKE concat('%',#{query},'%'))</if> " +
|
" <if test='query != null'> AND (device_id LIKE concat('%',#{query},'%') escape '/' OR name LIKE concat('%',#{query},'%') escape '/')</if> " +
|
||||||
" </script>")
|
" </script>")
|
||||||
List<RegionTree> queryForTree(@Param("query") String query, @Param("parentId") Integer parentId);
|
List<RegionTree> queryForTree(@Param("query") String query, @Param("parentId") Integer parentId);
|
||||||
|
|
||||||
|
|||||||
@ -124,8 +124,8 @@ public class ChannelProvider {
|
|||||||
sqlBuild.append(BASE_SQL);
|
sqlBuild.append(BASE_SQL);
|
||||||
sqlBuild.append(" where channel_type = 0 ");
|
sqlBuild.append(" where channel_type = 0 ");
|
||||||
if (params.get("query") != null) {
|
if (params.get("query") != null) {
|
||||||
sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" +
|
sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%') escape '/'" +
|
||||||
" OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )")
|
" OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') escape '/' )")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (params.get("online") != null && (Boolean)params.get("online")) {
|
if (params.get("online") != null && (Boolean)params.get("online")) {
|
||||||
@ -158,8 +158,8 @@ public class ChannelProvider {
|
|||||||
sqlBuild.append(BASE_SQL);
|
sqlBuild.append(BASE_SQL);
|
||||||
sqlBuild.append(" where channel_type = 0 ");
|
sqlBuild.append(" where channel_type = 0 ");
|
||||||
if (params.get("query") != null) {
|
if (params.get("query") != null) {
|
||||||
sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" +
|
sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%') escape '/'" +
|
||||||
" OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )")
|
" OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') escape '/' )")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (params.get("online") != null && (Boolean)params.get("online")) {
|
if (params.get("online") != null && (Boolean)params.get("online")) {
|
||||||
|
|||||||
@ -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},'%'))");
|
"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"))) {
|
if (params.get("query") != null && !ObjectUtils.isEmpty(params.get("query"))) {
|
||||||
sqlBuild.append(" AND (coalesce(dc.gb_device_id, dc.device_id) 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},'%'))")
|
" OR coalesce(dc.gb_name, dc.name) LIKE concat('%',#{query},'%') escape '/')")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (params.get("online") != null && (Boolean)params.get("online")) {
|
if (params.get("online") != null && (Boolean)params.get("online")) {
|
||||||
|
|||||||
@ -10,6 +10,8 @@ public interface IGbChannelPlayService {
|
|||||||
|
|
||||||
void start(CommonGBChannel channel, InviteInfo inviteInfo, Platform platform, ErrorCallback<StreamInfo> callback);
|
void start(CommonGBChannel channel, InviteInfo inviteInfo, Platform platform, ErrorCallback<StreamInfo> callback);
|
||||||
|
|
||||||
|
void play(CommonGBChannel channel, Platform platform, ErrorCallback<StreamInfo> callback);
|
||||||
|
|
||||||
void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
||||||
|
|
||||||
void playProxy(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
void playProxy(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
||||||
|
|||||||
21
src/main/java/com/genersoft/iot/vmp/gb28181/service/IPTZService.java
Executable file
21
src/main/java/com/genersoft/iot/vmp/gb28181/service/IPTZService.java
Executable file
@ -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<Preset> 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);
|
||||||
|
}
|
||||||
@ -609,6 +609,11 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
|||||||
parentId = channelId;
|
parentId = channelId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<DeviceChannel> all = channelMapper.queryChannels(deviceDbId, civilCode, businessGroupId, parentId, query, channelType, online,null);
|
List<DeviceChannel> all = channelMapper.queryChannels(deviceDbId, civilCode, businessGroupId, parentId, query, channelType, online,null);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
@ -624,7 +629,11 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
|||||||
if (device == null) {
|
if (device == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId);
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId);
|
||||||
}
|
}
|
||||||
// 获取到所有正在播放的流
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
List<DeviceChannel> all = channelMapper.queryChannels(device.getId(), null,null, null, query, hasSubChannel, online,null);
|
List<DeviceChannel> all = channelMapper.queryChannels(device.getId(), null,null, null, query, hasSubChannel, online,null);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
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.CatalogSubscribeTask;
|
||||||
import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
|
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.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.gb28181.transmit.event.request.impl.message.response.cmd.CatalogResponseMessageHandler;
|
||||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
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.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.ObjectUtils;
|
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
import javax.sip.InvalidArgumentException;
|
||||||
import javax.sip.SipException;
|
import javax.sip.SipException;
|
||||||
@ -51,9 +50,6 @@ import java.util.concurrent.TimeUnit;
|
|||||||
@DS("master")
|
@DS("master")
|
||||||
public class DeviceServiceImpl implements IDeviceService {
|
public class DeviceServiceImpl implements IDeviceService {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SIPCommander cmder;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DynamicTask dynamicTask;
|
private DynamicTask dynamicTask;
|
||||||
|
|
||||||
@ -327,7 +323,8 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
@Override
|
@Override
|
||||||
public void sync(Device device) {
|
public void sync(Device device) {
|
||||||
if (catalogResponseMessageHandler.isSyncRunning(device.getDeviceId())) {
|
if (catalogResponseMessageHandler.isSyncRunning(device.getDeviceId())) {
|
||||||
log.info("开启同步时发现同步已经存在");
|
SyncStatus syncStatus = catalogResponseMessageHandler.getChannelSyncProgress(device.getDeviceId());
|
||||||
|
log.info("[同步通道] 同步已存在, 设备: {}, 同步信息: {}", device.getDeviceId(), JSON.toJSON(syncStatus));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int sn = (int)((Math.random()*9+1)*100000);
|
int sn = (int)((Math.random()*9+1)*100000);
|
||||||
@ -335,6 +332,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
try {
|
try {
|
||||||
sipCommander.catalogQuery(device, sn, event -> {
|
sipCommander.catalogQuery(device, sn, event -> {
|
||||||
String errorMsg = String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg);
|
String errorMsg = String.format("同步通道失败,错误码: %s, %s", event.statusCode, event.msg);
|
||||||
|
log.info("[同步通道]失败,编号: {}, 错误码: {}, {}", device.getDeviceId(), event.statusCode, event.msg);
|
||||||
catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), sn, errorMsg);
|
catalogResponseMessageHandler.setChannelSyncEnd(device.getDeviceId(), sn, errorMsg);
|
||||||
});
|
});
|
||||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
@ -524,6 +522,11 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
@Override
|
@Override
|
||||||
public PageInfo<Device> getAll(int page, int count, String query, Boolean status) {
|
public PageInfo<Device> getAll(int page, int count, String query, Boolean status) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<Device> all = deviceMapper.getDeviceList(query, status);
|
List<Device> all = deviceMapper.getDeviceList(query, status);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,20 +39,7 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
|||||||
}
|
}
|
||||||
log.info("[点播通用通道] 类型:{}, 通道: {}({})", inviteInfo.getSessionName(), channel.getGbName(), channel.getGbDeviceId());
|
log.info("[点播通用通道] 类型:{}, 通道: {}({})", inviteInfo.getSessionName(), channel.getGbName(), channel.getGbDeviceId());
|
||||||
if ("Play".equalsIgnoreCase(inviteInfo.getSessionName())) {
|
if ("Play".equalsIgnoreCase(inviteInfo.getSessionName())) {
|
||||||
if (channel.getGbDeviceDbId() != null) {
|
play(channel, platform, callback);
|
||||||
// 国标通道
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}else if ("Playback".equals(inviteInfo.getSessionName())) {
|
}else if ("Playback".equals(inviteInfo.getSessionName())) {
|
||||||
if (channel.getGbDeviceDbId() != null) {
|
if (channel.getGbDeviceDbId() != null) {
|
||||||
// 国标通道
|
// 国标通道
|
||||||
@ -101,6 +88,29 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void play(CommonGBChannel channel, Platform platform, ErrorCallback<StreamInfo> 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
|
@Override
|
||||||
public void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback<StreamInfo> callback){
|
public void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback<StreamInfo> callback){
|
||||||
// 国标通道
|
// 国标通道
|
||||||
|
|||||||
@ -390,6 +390,11 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
|||||||
@Override
|
@Override
|
||||||
public PageInfo<CommonGBChannel> queryListByCivilCode(int page, int count, String query, Boolean online, Integer channelType, String civilCode) {
|
public PageInfo<CommonGBChannel> queryListByCivilCode(int page, int count, String query, Boolean online, Integer channelType, String civilCode) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<CommonGBChannel> all = commonGBChannelMapper.queryListByCivilCode(query, online, channelType, civilCode);
|
List<CommonGBChannel> all = commonGBChannelMapper.queryListByCivilCode(query, online, channelType, civilCode);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
@ -397,6 +402,11 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
|||||||
@Override
|
@Override
|
||||||
public PageInfo<CommonGBChannel> queryListByParentId(int page, int count, String query, Boolean online, Integer channelType, String groupDeviceId) {
|
public PageInfo<CommonGBChannel> queryListByParentId(int page, int count, String query, Boolean online, Integer channelType, String groupDeviceId) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<CommonGBChannel> all = commonGBChannelMapper.queryListByParentId(query, online, channelType, groupDeviceId);
|
List<CommonGBChannel> all = commonGBChannelMapper.queryListByParentId(query, online, channelType, groupDeviceId);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<Preset> queryPresetList(String deviceId, String channelDeviceId) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPreset(Preset preset) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deletePreset(Integer qq) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -159,6 +159,11 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
@Override
|
@Override
|
||||||
public PageInfo<Platform> queryPlatformList(int page, int count, String query) {
|
public PageInfo<Platform> queryPlatformList(int page, int count, String query) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<Platform> all = platformMapper.queryList(query);
|
List<Platform> all = platformMapper.queryList(query);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -488,8 +488,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId());
|
log.info("[语音对讲]开始 获取发流端口失败 deviceId: {}, channelId: {},", device.getDeviceId(), channel.getDeviceId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sendRtpInfo.setOnlyAudio(true);
|
sendRtpInfo.setOnlyAudio(true);
|
||||||
sendRtpInfo.setPt(8);
|
sendRtpInfo.setPt(8);
|
||||||
sendRtpInfo.setStatus(1);
|
sendRtpInfo.setStatus(1);
|
||||||
@ -518,7 +517,14 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
}, userSetting.getPlayTimeout());
|
}, userSetting.getPlayTimeout());
|
||||||
|
|
||||||
try {
|
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) {
|
}catch (ControllerException e) {
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc());
|
||||||
log.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channel.getDeviceId());
|
log.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channel.getDeviceId());
|
||||||
|
|||||||
@ -97,6 +97,11 @@ public class RegionServiceImpl implements IRegionService {
|
|||||||
@Override
|
@Override
|
||||||
public PageInfo<Region> query(String query, int page, int count) {
|
public PageInfo<Region> query(String query, int page, int count) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<Region> regionList = regionMapper.query(query, null);
|
List<Region> regionList = regionMapper.query(query, null);
|
||||||
return new PageInfo<>(regionList);
|
return new PageInfo<>(regionList);
|
||||||
}
|
}
|
||||||
@ -140,6 +145,11 @@ public class RegionServiceImpl implements IRegionService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RegionTree> queryForTree(String query, Integer parent, Boolean hasChannel) {
|
public List<RegionTree> queryForTree(String query, Integer parent, Boolean hasChannel) {
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<RegionTree> regionList = regionMapper.queryForTree(query, parent);
|
List<RegionTree> regionList = regionMapper.queryForTree(query, parent);
|
||||||
if (parent != null && hasChannel != null && hasChannel) {
|
if (parent != null && hasChannel != null && hasChannel) {
|
||||||
Region parentRegion = regionMapper.queryOne(parent);
|
Region parentRegion = regionMapper.queryOne(parent);
|
||||||
|
|||||||
@ -170,11 +170,16 @@ public class CatalogDataManager implements CommandLineRunner {
|
|||||||
syncStatus.setCurrent(catalogData.getRedisKeysForChannel().size());
|
syncStatus.setCurrent(catalogData.getRedisKeysForChannel().size());
|
||||||
syncStatus.setTotal(catalogData.getTotal());
|
syncStatus.setTotal(catalogData.getTotal());
|
||||||
syncStatus.setErrorMsg(catalogData.getErrorMsg());
|
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);
|
syncStatus.setSyncIng(false);
|
||||||
}else {
|
}else {
|
||||||
syncStatus.setSyncIng(true);
|
syncStatus.setSyncIng(true);
|
||||||
}
|
}
|
||||||
|
if (catalogData.getErrorMsg() != null) {
|
||||||
|
// 失败的同步信息,返回一次后直接移除
|
||||||
|
dataMap.remove(key);
|
||||||
|
}
|
||||||
return syncStatus;
|
return syncStatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +242,8 @@ public class CatalogDataManager implements CommandLineRunner {
|
|||||||
catalogData.setErrorMsg(errorMsg);
|
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);
|
dataMap.remove(dataKey);
|
||||||
Set<String> redisKeysForChannel = catalogData.getRedisKeysForChannel();
|
Set<String> redisKeysForChannel = catalogData.getRedisKeysForChannel();
|
||||||
if (redisKeysForChannel != null && !redisKeysForChannel.isEmpty()) {
|
if (redisKeysForChannel != null && !redisKeysForChannel.isEmpty()) {
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,17 +90,14 @@ public class SSRCFactory {
|
|||||||
* 获取后四位数SN,随机数
|
* 获取后四位数SN,随机数
|
||||||
*/
|
*/
|
||||||
private String getSN(String mediaServerId) {
|
private String getSN(String mediaServerId) {
|
||||||
String sn = null;
|
|
||||||
String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
|
String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
|
||||||
Long size = redisTemplate.opsForSet().size(redisKey);
|
Long size = redisTemplate.opsForSet().size(redisKey);
|
||||||
if (size == null || size == 0) {
|
if (size == null || size == 0) {
|
||||||
throw new RuntimeException("ssrc已经用完");
|
throw new RuntimeException("ssrc已经用完");
|
||||||
} else {
|
} else {
|
||||||
// 在集合中移除并返回一个随机成员。
|
// 在集合中移除并返回一个随机成员。
|
||||||
sn = (String) redisTemplate.opsForSet().pop(redisKey);
|
return redisTemplate.opsForSet().pop(redisKey);
|
||||||
redisTemplate.opsForSet().remove(redisKey, sn);
|
|
||||||
}
|
}
|
||||||
return sn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -142,15 +142,10 @@ public class SIPCommander implements ISIPCommander {
|
|||||||
builder.append(strTmp, 0, 2);
|
builder.append(strTmp, 0, 2);
|
||||||
strTmp = String.format("%02X", parameter2);
|
strTmp = String.format("%02X", parameter2);
|
||||||
builder.append(strTmp, 0, 2);
|
builder.append(strTmp, 0, 2);
|
||||||
//优化zoom变倍速率
|
strTmp = String.format("%02X", combineCode2 << 4);
|
||||||
if ((combineCode2 > 0) && (combineCode2 <16))
|
builder.append(strTmp, 0, 2);
|
||||||
{
|
|
||||||
combineCode2 = 16;
|
|
||||||
}
|
|
||||||
strTmp = String.format("%X", combineCode2);
|
|
||||||
builder.append(strTmp, 0, 1).append("0");
|
|
||||||
//计算校验码
|
//计算校验码
|
||||||
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);
|
strTmp = String.format("%02X", checkCode);
|
||||||
builder.append(strTmp, 0, 2);
|
builder.append(strTmp, 0, 2);
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
@ -986,8 +981,6 @@ public class SIPCommander implements ISIPCommander {
|
|||||||
catalogXml.append(" <DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
catalogXml.append(" <DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||||
catalogXml.append("</Query>\r\n");
|
catalogXml.append("</Query>\r\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
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);
|
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent);
|
||||||
|
|||||||
@ -303,7 +303,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
Media media = mediaDescription.getMedia();
|
Media media = mediaDescription.getMedia();
|
||||||
|
|
||||||
Vector mediaFormats = media.getMediaFormats(false);
|
Vector mediaFormats = media.getMediaFormats(false);
|
||||||
if (mediaFormats.contains("96")) {
|
if (mediaFormats.contains("96") || mediaFormats.contains("8")) {
|
||||||
port = media.getMediaPort();
|
port = media.getMediaPort();
|
||||||
//String mediaType = media.getMediaType();
|
//String mediaType = media.getMediaType();
|
||||||
String protocol = media.getProtocol();
|
String protocol = media.getProtocol();
|
||||||
|
|||||||
@ -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.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
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.DeferredResultHolder;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||||
@ -79,11 +79,11 @@ public class PresetQueryResponseMessageHandler extends SIPRequestProcessorParent
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
|
int sumNum = Integer.parseInt(presetListNumElement.attributeValue("Num"));
|
||||||
List<PresetQuerySipReq> presetQuerySipReqList = new ArrayList<>();
|
List<Preset> presetQuerySipReqList = new ArrayList<>();
|
||||||
if (sumNum > 0) {
|
if (sumNum > 0) {
|
||||||
for (Iterator<Element> presetIterator = presetListNumElement.elementIterator(); presetIterator.hasNext(); ) {
|
for (Iterator<Element> presetIterator = presetListNumElement.elementIterator(); presetIterator.hasNext(); ) {
|
||||||
Element itemListElement = presetIterator.next();
|
Element itemListElement = presetIterator.next();
|
||||||
PresetQuerySipReq presetQuerySipReq = new PresetQuerySipReq();
|
Preset presetQuerySipReq = new Preset();
|
||||||
for (Iterator<Element> itemListIterator = itemListElement.elementIterator(); itemListIterator.hasNext(); ) {
|
for (Iterator<Element> itemListIterator = itemListElement.elementIterator(); itemListIterator.hasNext(); ) {
|
||||||
// 遍历item
|
// 遍历item
|
||||||
Element itemOne = itemListIterator.next();
|
Element itemOne = itemListIterator.next();
|
||||||
|
|||||||
@ -33,6 +33,10 @@ public class MediaInfo {
|
|||||||
private Integer width;
|
private Integer width;
|
||||||
@Schema(description = "视频高度")
|
@Schema(description = "视频高度")
|
||||||
private Integer height;
|
private Integer height;
|
||||||
|
@Schema(description = "FPS")
|
||||||
|
private Integer fps;
|
||||||
|
@Schema(description = "丢包率")
|
||||||
|
private Integer loss;
|
||||||
@Schema(description = "音频编码类型")
|
@Schema(description = "音频编码类型")
|
||||||
private String audioCodec;
|
private String audioCodec;
|
||||||
@Schema(description = "音频通道数")
|
@Schema(description = "音频通道数")
|
||||||
@ -58,6 +62,7 @@ public class MediaInfo {
|
|||||||
@Schema(description = "服务ID")
|
@Schema(description = "服务ID")
|
||||||
private String serverId;
|
private String serverId;
|
||||||
|
|
||||||
|
|
||||||
public static MediaInfo getInstance(JSONObject jsonObject, MediaServer mediaServer, String serverId) {
|
public static MediaInfo getInstance(JSONObject jsonObject, MediaServer mediaServer, String serverId) {
|
||||||
MediaInfo mediaInfo = new MediaInfo();
|
MediaInfo mediaInfo = new MediaInfo();
|
||||||
mediaInfo.setMediaServer(mediaServer);
|
mediaInfo.setMediaServer(mediaServer);
|
||||||
@ -111,7 +116,14 @@ public class MediaInfo {
|
|||||||
Integer codecType = trackJson.getInteger("codec_type");
|
Integer codecType = trackJson.getInteger("codec_type");
|
||||||
Integer sampleRate = trackJson.getInteger("sample_rate");
|
Integer sampleRate = trackJson.getInteger("sample_rate");
|
||||||
Integer height = trackJson.getInteger("height");
|
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");
|
Long duration = trackJson.getLongValue("duration");
|
||||||
if (channels != null) {
|
if (channels != null) {
|
||||||
mediaInfo.setAudioChannels(channels);
|
mediaInfo.setAudioChannels(channels);
|
||||||
@ -125,6 +137,12 @@ public class MediaInfo {
|
|||||||
if (width != null) {
|
if (width != null) {
|
||||||
mediaInfo.setWidth(width);
|
mediaInfo.setWidth(width);
|
||||||
}
|
}
|
||||||
|
if (fps != null) {
|
||||||
|
mediaInfo.setFps(fps);
|
||||||
|
}
|
||||||
|
if (loss != null) {
|
||||||
|
mediaInfo.setLoss(loss);
|
||||||
|
}
|
||||||
if (duration > 0L) {
|
if (duration > 0L) {
|
||||||
mediaInfo.setDuration(duration);
|
mediaInfo.setDuration(duration);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,7 @@ public interface IMediaNodeServerService {
|
|||||||
|
|
||||||
Map<String, String> getFFmpegCMDs(MediaServer mediaServer);
|
Map<String, String> 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);
|
void startSendRtpStream(MediaServer mediaServer, SendRtpInfo sendRtpItem);
|
||||||
|
|
||||||
|
|||||||
@ -142,7 +142,7 @@ public interface IMediaServerService {
|
|||||||
|
|
||||||
Boolean isStreamReady(MediaServer mediaServer, String rtp, String streamId);
|
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);
|
void startSendRtp(MediaServer mediaServer, SendRtpInfo sendRtpItem);
|
||||||
|
|
||||||
|
|||||||
@ -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.bean.MediaServer;
|
||||||
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
|
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.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.MediaServerDeleteEvent;
|
||||||
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent;
|
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent;
|
||||||
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent;
|
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);
|
redisTemplate.opsForHash().put(key, mediaServerInDataBase.getId(), mediaServerInDataBase);
|
||||||
if (mediaServerInDataBase.isStatus()) {
|
if (mediaServerInDataBase.isStatus()) {
|
||||||
resetOnlineServerItem(mediaServerInDataBase);
|
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);
|
mediaServerMapper.add(mediaServer);
|
||||||
if (mediaServer.isStatus()) {
|
if (mediaServer.isStatus()) {
|
||||||
mediaNodeServerService.online(mediaServer);
|
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
|
@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());
|
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
|
||||||
if (mediaNodeServerService == null) {
|
if (mediaNodeServerService == null) {
|
||||||
log.info("[startSendRtpPassive] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
|
log.info("[startSendRtpPassive] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类");
|
||||||
}
|
}
|
||||||
mediaNodeServerService.startSendRtpPassive(mediaServer, sendRtpItem, timeout);
|
return mediaNodeServerService.startSendRtpPassive(mediaServer, sendRtpItem, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -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流注册或注销时触发此事件;此事件对回复不敏感。
|
* rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。
|
||||||
*/
|
*/
|
||||||
@ -299,7 +290,7 @@ public class ZLMHttpHookListener {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8")
|
@PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8")
|
||||||
public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) {
|
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 {
|
try {
|
||||||
MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
|
MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
|
||||||
|
|||||||
@ -180,7 +180,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
|
|||||||
if (mediaList.getInteger("code") == 0) {
|
if (mediaList.getInteger("code") == 0) {
|
||||||
JSONArray data = mediaList.getJSONArray("data");
|
JSONArray data = mediaList.getJSONArray("data");
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return streamInfoList;
|
||||||
}
|
}
|
||||||
JSONObject mediaJSON = data.getJSONObject(0);
|
JSONObject mediaJSON = data.getJSONObject(0);
|
||||||
MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer, userSetting.getServerId());
|
MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer, userSetting.getServerId());
|
||||||
@ -329,7 +329,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout) {
|
public Integer startSendRtpPassive(MediaServer mediaServer, SendRtpInfo sendRtpItem, Integer timeout) {
|
||||||
Map<String, Object> param = new HashMap<>(12);
|
Map<String, Object> param = new HashMap<>(12);
|
||||||
param.put("vhost","__defaultVhost__");
|
param.put("vhost","__defaultVhost__");
|
||||||
param.put("app", sendRtpItem.getApp());
|
param.put("app", sendRtpItem.getApp());
|
||||||
@ -361,6 +361,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService {
|
|||||||
log.info("调用ZLM-TCP被动推流接口, 结果: {}", jsonObject);
|
log.info("调用ZLM-TCP被动推流接口, 结果: {}", jsonObject);
|
||||||
log.info("启动监听TCP被动推流成功[ {}/{} ],{}->{}:{}, " , sendRtpItem.getApp(), sendRtpItem.getStream(),
|
log.info("启动监听TCP被动推流成功[ {}/{} ],{}->{}:{}, " , sendRtpItem.getApp(), sendRtpItem.getStream(),
|
||||||
jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
|
jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
|
||||||
|
return jsonObject.getInteger("local_port");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1,19 +1,13 @@
|
|||||||
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* zlm hook事件的参数
|
* zlm hook事件的参数
|
||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
public class HookParam {
|
public class HookParam {
|
||||||
private String mediaServerId;
|
private String mediaServerId;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getMediaServerId() {
|
|
||||||
return mediaServerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMediaServerId(String mediaServerId) {
|
|
||||||
this.mediaServerId = mediaServerId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,84 +1,48 @@
|
|||||||
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* zlm hook事件中的on_publish事件的参数
|
* zlm hook事件中的on_publish事件的参数
|
||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class OnPublishHookParam extends HookParam{
|
public class OnPublishHookParam extends HookParam{
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String app;
|
private String app;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String stream;
|
private String stream;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String ip;
|
private String ip;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String params;
|
private String params;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String schema;
|
private String schema;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String vhost;
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "OnPublishHookParam{" +
|
return "OnPublishHookParam{" +
|
||||||
|
|||||||
@ -71,6 +71,11 @@ public class CloudRecordServiceImpl implements ICloudRecordService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<CloudRecordItem> all = cloudRecordServiceMapper.getList(query, app, stream, startTimeStamp, endTimeStamp,
|
List<CloudRecordItem> all = cloudRecordServiceMapper.getList(query, app, stream, startTimeStamp, endTimeStamp,
|
||||||
callId, mediaServerItems, null);
|
callId, mediaServerItems, null);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
|
|||||||
@ -96,6 +96,12 @@ public class MediaServiceImpl implements IMediaService {
|
|||||||
public ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params) {
|
public ResultForOnPublish authenticatePublish(MediaServer mediaServer, String app, String stream, String params) {
|
||||||
// 推流鉴权的处理
|
// 推流鉴权的处理
|
||||||
if (!"rtp".equals(app)) {
|
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);
|
StreamProxy streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, stream);
|
||||||
if (streamProxyItem != null) {
|
if (streamProxyItem != null) {
|
||||||
ResultForOnPublish result = new ResultForOnPublish();
|
ResultForOnPublish result = new ResultForOnPublish();
|
||||||
|
|||||||
@ -41,7 +41,7 @@ public interface CloudRecordServiceMapper {
|
|||||||
"select * " +
|
"select * " +
|
||||||
" from wvp_cloud_record " +
|
" from wvp_cloud_record " +
|
||||||
" where 0 = 0" +
|
" where 0 = 0" +
|
||||||
" <if test='query != null'> AND (app LIKE concat('%',#{query},'%') OR stream LIKE concat('%',#{query},'%') )</if> " +
|
" <if test='query != null'> AND (app LIKE concat('%',#{query},'%') escape '/' OR stream LIKE concat('%',#{query},'%') escape '/' )</if> " +
|
||||||
" <if test= 'app != null '> and app=#{app}</if>" +
|
" <if test= 'app != null '> and app=#{app}</if>" +
|
||||||
" <if test= 'stream != null '> and stream=#{stream}</if>" +
|
" <if test= 'stream != null '> and stream=#{stream}</if>" +
|
||||||
" <if test= 'startTimeStamp != null '> and end_time >= #{startTimeStamp}</if>" +
|
" <if test= 'startTimeStamp != null '> and end_time >= #{startTimeStamp}</if>" +
|
||||||
@ -53,7 +53,7 @@ public interface CloudRecordServiceMapper {
|
|||||||
" <if test= 'ids != null ' > and id in " +
|
" <if test= 'ids != null ' > and id in " +
|
||||||
" <foreach collection='ids' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
|
" <foreach collection='ids' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
|
||||||
" </if>" +
|
" </if>" +
|
||||||
" order by start_time ASC" +
|
" order by start_time desc" +
|
||||||
" </script>")
|
" </script>")
|
||||||
List<CloudRecordItem> getList(@Param("query") String query, @Param("app") String app, @Param("stream") String stream,
|
List<CloudRecordItem> getList(@Param("query") String query, @Param("app") String app, @Param("stream") String stream,
|
||||||
@Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp,
|
@Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp,
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import java.util.Map;
|
|||||||
* 拉流代理接口
|
* 拉流代理接口
|
||||||
*/
|
*/
|
||||||
@Tag(name = "拉流代理", description = "")
|
@Tag(name = "拉流代理", description = "")
|
||||||
@Controller
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequestMapping(value = "/api/proxy")
|
@RequestMapping(value = "/api/proxy")
|
||||||
public class StreamProxyController {
|
public class StreamProxyController {
|
||||||
|
|||||||
@ -48,8 +48,8 @@ public interface StreamProxyMapper {
|
|||||||
@SelectProvider(type = StreamProxyProvider.class, method = "selectOneByAppAndStream")
|
@SelectProvider(type = StreamProxyProvider.class, method = "selectOneByAppAndStream")
|
||||||
StreamProxy selectOneByAppAndStream(@Param("app") String app, @Param("stream") String stream);
|
StreamProxy selectOneByAppAndStream(@Param("app") String app, @Param("stream") String stream);
|
||||||
|
|
||||||
@SelectProvider(type = StreamProxyProvider.class, method = "selectForEnableInMediaServer")
|
@SelectProvider(type = StreamProxyProvider.class, method = "selectForPushingInMediaServer")
|
||||||
List<StreamProxy> selectForEnableInMediaServer(@Param("mediaServerId") String mediaServerId, @Param("enable") boolean enable);
|
List<StreamProxy> selectForPushingInMediaServer(@Param("mediaServerId") String mediaServerId, @Param("enable") boolean enable);
|
||||||
|
|
||||||
|
|
||||||
@Select("select count(1) from wvp_stream_proxy")
|
@Select("select count(1) from wvp_stream_proxy")
|
||||||
|
|||||||
@ -19,9 +19,8 @@ public class StreamProxyProvider {
|
|||||||
return getBaseSelectSql() + " WHERE st.id = " + params.get("id");
|
return getBaseSelectSql() + " WHERE st.id = " + params.get("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String selectForEnableInMediaServer(Map<String, Object> params ){
|
public String selectForPushingInMediaServer(Map<String, Object> params ){
|
||||||
return getBaseSelectSql() + String.format(" WHERE st.enable=%s and st.media_server_id= '%s' order by st.create_time desc",
|
return getBaseSelectSql() + " WHERE st.pulling=1 and st.media_server_id=#{mediaServerId} order by st.create_time desc";
|
||||||
params.get("enable"), params.get("mediaServerId"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String selectOneByAppAndStream(Map<String, Object> params ){
|
public String selectOneByAppAndStream(Map<String, Object> params ){
|
||||||
@ -36,13 +35,13 @@ public class StreamProxyProvider {
|
|||||||
if (params.get("query") != null) {
|
if (params.get("query") != null) {
|
||||||
sqlBuild.append(" AND ")
|
sqlBuild.append(" AND ")
|
||||||
.append(" (")
|
.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(" 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(" 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(" 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(" )")
|
.append(" )")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -230,22 +230,17 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
|||||||
gbChannelService.add(streamProxy.buildCommonGBChannel());
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageInfo<StreamProxy> getAll(Integer page, Integer count, String query, Boolean pulling, String mediaServerId) {
|
public PageInfo<StreamProxy> getAll(Integer page, Integer count, String query, Boolean pulling, String mediaServerId) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<StreamProxy> all = streamProxyMapper.selectAll(query, pulling, mediaServerId);
|
List<StreamProxy> all = streamProxyMapper.selectAll(query, pulling, mediaServerId);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
@ -291,7 +286,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
|||||||
// 这里主要是控制数据库/redis缓存/以及zlm中存在的代理流 三者状态一致。以数据库中数据为根本
|
// 这里主要是控制数据库/redis缓存/以及zlm中存在的代理流 三者状态一致。以数据库中数据为根本
|
||||||
redisCatchStorage.removeStream(mediaServer.getId(), "PULL");
|
redisCatchStorage.removeStream(mediaServer.getId(), "PULL");
|
||||||
|
|
||||||
List<StreamProxy> streamProxies = streamProxyMapper.selectForEnableInMediaServer(mediaServer.getId(), true);
|
List<StreamProxy> streamProxies = streamProxyMapper.selectForPushingInMediaServer(mediaServer.getId(), true);
|
||||||
if (streamProxies.isEmpty()) {
|
if (streamProxies.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -348,18 +343,16 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
|||||||
streamProxyMapper.deleteByList(streamProxiesForRemove);
|
streamProxyMapper.deleteByList(streamProxiesForRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!streamProxyMapForDb.isEmpty()) {
|
if (!streamProxyMapForDb.isEmpty()) {
|
||||||
for (StreamProxy streamProxy : streamProxyMapForDb.values()) {
|
for (StreamProxy streamProxy : streamProxyMapForDb.values()) {
|
||||||
log.info("恢复流代理," + streamProxy.getApp() + "/" + streamProxy.getStream());
|
streamProxyMapper.offline(streamProxy.getId());
|
||||||
mediaServerService.startProxy(mediaServer, streamProxy);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void zlmServerOffline(MediaServer mediaServer) {
|
public void zlmServerOffline(MediaServer mediaServer) {
|
||||||
List<StreamProxy> streamProxies = streamProxyMapper.selectForEnableInMediaServer(mediaServer.getId(), true);
|
List<StreamProxy> streamProxies = streamProxyMapper.selectForPushingInMediaServer(mediaServer.getId(), true);
|
||||||
|
|
||||||
// 清理redis相关的缓存
|
// 清理redis相关的缓存
|
||||||
redisCatchStorage.removeStream(mediaServer.getId(), "PULL");
|
redisCatchStorage.removeStream(mediaServer.getId(), "PULL");
|
||||||
@ -382,11 +375,14 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
|||||||
streamProxiesForSendMessage.add(streamProxy);
|
streamProxiesForSendMessage.add(streamProxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 移除开启了无人观看自动移除的流
|
if (!streamProxiesForRemove.isEmpty()) {
|
||||||
streamProxyMapper.deleteByList(streamProxiesForRemove);
|
// 移除开启了无人观看自动移除的流
|
||||||
// 修改国标关联的国标通道的状态
|
streamProxyMapper.deleteByList(streamProxiesForRemove);
|
||||||
gbChannelService.offline(channelListForOffline);
|
}
|
||||||
|
if (!streamProxiesForRemove.isEmpty()) {
|
||||||
|
// 修改国标关联的国标通道的状态
|
||||||
|
gbChannelService.offline(channelListForOffline);
|
||||||
|
}
|
||||||
if (!streamProxiesForSendMessage.isEmpty()) {
|
if (!streamProxiesForSendMessage.isEmpty()) {
|
||||||
for (StreamProxy streamProxy : streamProxiesForSendMessage) {
|
for (StreamProxy streamProxy : streamProxiesForSendMessage) {
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
|||||||
@ -84,7 +84,7 @@ public class StreamPush extends CommonGBChannel implements Comparable<StreamPush
|
|||||||
- DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(streamPushItem.getCreateTime())).intValue();
|
- DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(streamPushItem.getCreateTime())).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamPush getInstance(StreamInfo streamInfo) {
|
public static StreamPush getInstance(StreamInfo streamInfo) {
|
||||||
StreamPush streamPush = new StreamPush();
|
StreamPush streamPush = new StreamPush();
|
||||||
streamPush.setApp(streamInfo.getApp());
|
streamPush.setApp(streamInfo.getApp());
|
||||||
if (streamInfo.getMediaServer() != null) {
|
if (streamInfo.getMediaServer() != null) {
|
||||||
|
|||||||
@ -43,7 +43,7 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Tag(name = "推流信息管理")
|
@Tag(name = "推流信息管理")
|
||||||
@Controller
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequestMapping(value = "/api/push")
|
@RequestMapping(value = "/api/push")
|
||||||
public class StreamPushController {
|
public class StreamPushController {
|
||||||
|
|||||||
@ -48,8 +48,8 @@ public interface StreamPushMapper {
|
|||||||
" on st.id = wdc.stream_push_id " +
|
" on st.id = wdc.stream_push_id " +
|
||||||
" WHERE " +
|
" WHERE " +
|
||||||
" 1=1 " +
|
" 1=1 " +
|
||||||
" <if test='query != null'> AND (st.app LIKE concat('%',#{query},'%') OR st.stream LIKE concat('%',#{query},'%') " +
|
" <if test='query != null'> AND (st.app LIKE concat('%',#{query},'%') escape '/' OR st.stream LIKE concat('%',#{query},'%') escape '/' " +
|
||||||
" OR wdc.gb_device_id LIKE concat('%',#{query},'%') OR wdc.gb_name LIKE concat('%',#{query},'%'))</if> " +
|
" OR wdc.gb_device_id LIKE concat('%',#{query},'%') escape '/' OR wdc.gb_name LIKE concat('%',#{query},'%') escape '/')</if> " +
|
||||||
" <if test='pushing == true' > AND st.pushing=1</if>" +
|
" <if test='pushing == true' > AND st.pushing=1</if>" +
|
||||||
" <if test='pushing == false' > AND st.pushing=0 </if>" +
|
" <if test='pushing == false' > AND st.pushing=0 </if>" +
|
||||||
" <if test='mediaServerId != null' > AND st.media_server_id=#{mediaServerId} </if>" +
|
" <if test='mediaServerId != null' > AND st.media_server_id=#{mediaServerId} </if>" +
|
||||||
|
|||||||
@ -175,6 +175,11 @@ public class StreamPushServiceImpl implements IStreamPushService {
|
|||||||
@Override
|
@Override
|
||||||
public PageInfo<StreamPush> getPushList(Integer page, Integer count, String query, Boolean pushing, String mediaServerId) {
|
public PageInfo<StreamPush> getPushList(Integer page, Integer count, String query, Boolean pushing, String mediaServerId) {
|
||||||
PageHelper.startPage(page, count);
|
PageHelper.startPage(page, count);
|
||||||
|
if (query != null) {
|
||||||
|
query = query.replaceAll("/", "//")
|
||||||
|
.replaceAll("%", "/%")
|
||||||
|
.replaceAll("_", "/_");
|
||||||
|
}
|
||||||
List<StreamPush> all = streamPushMapper.selectAll(query, pushing, mediaServerId);
|
List<StreamPush> all = streamPushMapper.selectAll(query, pushing, mediaServerId);
|
||||||
return new PageInfo<>(all);
|
return new PageInfo<>(all);
|
||||||
}
|
}
|
||||||
@ -530,7 +535,7 @@ public class StreamPushServiceImpl implements IStreamPushService {
|
|||||||
String key = streamInfo.getApp() + "_" + streamInfo.getStream();
|
String key = streamInfo.getApp() + "_" + streamInfo.getStream();
|
||||||
StreamPush streamPushItem = result.get(key);
|
StreamPush streamPushItem = result.get(key);
|
||||||
if (streamPushItem == null) {
|
if (streamPushItem == null) {
|
||||||
streamPushItem = streamPushItem.getInstance(streamInfo);
|
streamPushItem = StreamPush.getInstance(streamInfo);
|
||||||
result.put(key, streamPushItem);
|
result.put(key, streamPushItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.conf.security.JwtUtils;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
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.bean.MediaServer;
|
||||||
|
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent;
|
||||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||||
import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
|
import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
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.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import oshi.SystemInfo;
|
import oshi.SystemInfo;
|
||||||
@ -73,18 +76,18 @@ public class ServerController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IStreamPushService pushService;
|
private IStreamPushService pushService;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IStreamProxyService proxyService;
|
private IStreamProxyService proxyService;
|
||||||
|
|
||||||
|
|
||||||
@Value("${server.port}")
|
@Value("${server.port}")
|
||||||
private int serverPort;
|
private int serverPort;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IRedisCatchStorage redisCatchStorage;
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
|
|
||||||
@GetMapping(value = "/media_server/list")
|
@GetMapping(value = "/media_server/list")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@ -134,13 +137,17 @@ public class ServerController {
|
|||||||
@Parameter(name = "mediaServerItem", description = "流媒体信息", required = true)
|
@Parameter(name = "mediaServerItem", description = "流媒体信息", required = true)
|
||||||
@PostMapping(value = "/media_server/save")
|
@PostMapping(value = "/media_server/save")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public void saveMediaServer(@RequestBody MediaServer mediaServerItem) {
|
public void saveMediaServer(@RequestBody MediaServer mediaServer) {
|
||||||
MediaServer mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServerItem.getId());
|
MediaServer mediaServerItemInDatabase = mediaServerService.getOneFromDatabase(mediaServer.getId());
|
||||||
|
|
||||||
if (mediaServerItemInDatabase != null) {
|
if (mediaServerItemInDatabase != null) {
|
||||||
mediaServerService.update(mediaServerItem);
|
mediaServerService.update(mediaServer);
|
||||||
} else {
|
} 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);
|
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))
|
@Operation(summary = "重启服务", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@GetMapping(value = "/restart")
|
@GetMapping(value = "/restart")
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import com.alibaba.fastjson2.JSONArray;
|
|||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
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.IDeviceChannelService;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
@ -215,13 +215,13 @@ public class ApiDeviceController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deferredResultEx.setFilter(filterResult->{
|
deferredResultEx.setFilter(filterResult->{
|
||||||
List<PresetQuerySipReq> presetQuerySipReqList = (List<PresetQuerySipReq>)filterResult;
|
List<Preset> presetQuerySipReqList = (List<Preset>)filterResult;
|
||||||
HashMap<String, Object> resultMap = new HashMap<>();
|
HashMap<String, Object> resultMap = new HashMap<>();
|
||||||
resultMap.put("DeviceID", code);
|
resultMap.put("DeviceID", code);
|
||||||
resultMap.put("Result", "OK");
|
resultMap.put("Result", "OK");
|
||||||
resultMap.put("SumNum", presetQuerySipReqList.size());
|
resultMap.put("SumNum", presetQuerySipReqList.size());
|
||||||
ArrayList<Map<String, Object>> presetItemList = new ArrayList<>(presetQuerySipReqList.size());
|
ArrayList<Map<String, Object>> presetItemList = new ArrayList<>(presetQuerySipReqList.size());
|
||||||
for (PresetQuerySipReq presetQuerySipReq : presetQuerySipReqList) {
|
for (Preset presetQuerySipReq : presetQuerySipReqList) {
|
||||||
Map<String, Object> item = new HashMap<>();
|
Map<String, Object> item = new HashMap<>();
|
||||||
item.put("PresetID", presetQuerySipReq.getPresetId());
|
item.put("PresetID", presetQuerySipReq.getPresetId());
|
||||||
item.put("PresetName", presetQuerySipReq.getPresetName());
|
item.put("PresetName", presetQuerySipReq.getPresetName());
|
||||||
|
|||||||
@ -7,26 +7,28 @@
|
|||||||
|
|
||||||
<div class="page-header-btn">
|
<div class="page-header-btn">
|
||||||
搜索:
|
搜索:
|
||||||
<el-input @input="getRecordList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
|
<el-input @input="initData" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
|
||||||
prefix-icon="el-icon-search" v-model="search" clearable></el-input>
|
prefix-icon="el-icon-search" v-model="search" clearable></el-input>
|
||||||
开始时间:
|
开始时间:
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="startTime"
|
v-model="startTime"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
|
size="mini"
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
@change="getMediaServerList"
|
@change="initData"
|
||||||
placeholder="选择日期时间">
|
placeholder="选择日期时间">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
结束时间:
|
结束时间:
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="endTime"
|
v-model="endTime"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
|
size="mini"
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
@change="getMediaServerList"
|
@change="initData"
|
||||||
placeholder="选择日期时间">
|
placeholder="选择日期时间">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
节点选择:
|
节点选择:
|
||||||
<el-select size="mini" @change="getMediaServerList" style="width: 16rem; margin-right: 1rem;"
|
<el-select size="mini" @change="initData" style="width: 16rem; margin-right: 1rem;"
|
||||||
v-model="mediaServerId" placeholder="请选择" >
|
v-model="mediaServerId" placeholder="请选择" >
|
||||||
<el-option label="全部" value=""></el-option>
|
<el-option label="全部" value=""></el-option>
|
||||||
<el-option
|
<el-option
|
||||||
@ -38,7 +40,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord()">批量删除</el-button>-->
|
<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord()">批量删除</el-button>-->
|
||||||
<el-button icon="el-icon-refresh-right" circle size="mini" :loading="loading"
|
<el-button icon="el-icon-refresh-right" circle size="mini" :loading="loading"
|
||||||
@click="getRecordList()"></el-button>
|
@click="initData()"></el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--设备列表-->
|
<!--设备列表-->
|
||||||
@ -146,14 +148,13 @@ export default {
|
|||||||
computed: {},
|
computed: {},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.initData();
|
this.initData();
|
||||||
|
this.getMediaServerList();
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.$destroy('recordVideoPlayer');
|
this.$destroy('recordVideoPlayer');
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initData: function () {
|
initData: function () {
|
||||||
// 获取媒体节点列表
|
|
||||||
this.getMediaServerList();
|
|
||||||
this.getRecordList();
|
this.getRecordList();
|
||||||
},
|
},
|
||||||
currentChange: function (val) {
|
currentChange: function (val) {
|
||||||
|
|||||||
@ -246,6 +246,15 @@ export default {
|
|||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
} else {
|
} 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, ()=>{
|
this.$refs.syncChannelProgress.openDialog(itemData.deviceId, ()=>{
|
||||||
console.log(32322)
|
console.log(32322)
|
||||||
this.initData()
|
this.initData()
|
||||||
|
|||||||
98
web_src/src/components/common/mediaInfo.vue
Normal file
98
web_src/src/components/common/mediaInfo.vue
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<template>
|
||||||
|
<div id="mediaInfo" >
|
||||||
|
<el-button style="position: absolute; right: 1rem;" icon="el-icon-refresh-right" circle size="mini" @click="getMediaInfo"></el-button>
|
||||||
|
<el-descriptions size="mini" :column="3" title="概况">
|
||||||
|
<el-descriptions-item label="观看人数">{{ info.readerCount }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="网络">{{ formatByteSpeed() }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="持续时间">{{info.aliveSecond}}秒</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr">
|
||||||
|
<el-descriptions size="mini" v-if="info.videoCodec" :column="2" title="视频信息">
|
||||||
|
<el-descriptions-item label="编码">{{ info.videoCodec }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="分辨率"
|
||||||
|
>{{ info.width }}x{{ info.height }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="FPS">{{ info.fps }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="丢包率">{{ info.loss }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-descriptions size="mini" v-if="info.audioCodec" :column="2" title="音频信息">
|
||||||
|
<el-descriptions-item label="编码">
|
||||||
|
{{ info.audioCodec }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="采样率">{{ info.audioSampleRate }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "mediaInfo",
|
||||||
|
props: [ 'app', 'stream', 'mediaServerId'],
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
this.getMediaInfo()
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
info: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getMediaInfo: function () {
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/server/media_server/media_info`,
|
||||||
|
params: {
|
||||||
|
app: this.app,
|
||||||
|
stream: this.stream,
|
||||||
|
mediaServerId: this.mediaServerId,
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
console.log(res.data.data);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.info = res.data.data
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch((error)=> {
|
||||||
|
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formatByteSpeed: function (){
|
||||||
|
let bytesSpeed = this.info.bytesSpeed
|
||||||
|
let num = 1024.0 //byte
|
||||||
|
if (bytesSpeed < num) return bytesSpeed + ' B/S'
|
||||||
|
if (bytesSpeed < Math.pow(num, 2)) return (bytesSpeed / num).toFixed(2) + ' KB/S' //kb
|
||||||
|
if (bytesSpeed < Math.pow(num, 3))
|
||||||
|
return (bytesSpeed / Math.pow(num, 2)).toFixed(2) + ' MB/S' //M
|
||||||
|
if (bytesSpeed < Math.pow(num, 4))
|
||||||
|
return (bytesSpeed / Math.pow(num, 3)).toFixed(2) + ' G/S' //G
|
||||||
|
return (bytesSpeed / Math.pow(num, 4)).toFixed(2) + ' T/S' //T
|
||||||
|
},
|
||||||
|
formatAliveSecond: function (){
|
||||||
|
let aliveSecond = this.info.aliveSecond
|
||||||
|
const h = parseInt(aliveSecond.value / 3600)
|
||||||
|
const minute = parseInt((aliveSecond.value / 60) % 60)
|
||||||
|
const second = Math.ceil(aliveSecond.value % 60)
|
||||||
|
|
||||||
|
const hours = h < 10 ? '0' + h : h
|
||||||
|
const formatSecond = second > 59 ? 59 : second
|
||||||
|
return `${hours > 0 ? `${hours}小时` : ''}${minute < 10 ? '0' + minute : minute}分${
|
||||||
|
formatSecond < 10 ? '0' + formatSecond : formatSecond
|
||||||
|
}秒`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.channel-form {
|
||||||
|
display: grid;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
426
web_src/src/components/common/ptzCruising.vue
Normal file
426
web_src/src/components/common/ptzCruising.vue
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
<template>
|
||||||
|
<div id="ptzCruising">
|
||||||
|
<div style="display: grid; grid-template-columns: 80px auto; line-height: 28px">
|
||||||
|
<span>巡航组号: </span>
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="255"
|
||||||
|
placeholder="巡航组号"
|
||||||
|
addonBefore="巡航组号"
|
||||||
|
addonAfter="(1-255)"
|
||||||
|
v-model="cruiseId"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<el-tag v-for="(item, index) in presetList"
|
||||||
|
key="item.presetId"
|
||||||
|
closable
|
||||||
|
@close="delPreset(item, index)"
|
||||||
|
style="margin-right: 1rem; cursor: pointer"
|
||||||
|
>
|
||||||
|
{{item.presetName?item.presetName:item.presetId}}
|
||||||
|
</el-tag>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<el-form size="mini" :inline="true" v-if="selectPresetVisible">
|
||||||
|
<el-form-item >
|
||||||
|
<el-select v-model="selectPreset" placeholder="请选择预置点">
|
||||||
|
<el-option
|
||||||
|
v-for="item in allPresetList"
|
||||||
|
:key="item.presetId"
|
||||||
|
:label="item.presetName"
|
||||||
|
:value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="addCruisePoint">保存</el-button>
|
||||||
|
<el-button type="primary" @click="cancelAddCruisePoint">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-button size="mini" v-else @click="selectPresetVisible=true">添加巡航点</el-button>
|
||||||
|
|
||||||
|
<el-form size="mini" :inline="true" v-if="setSpeedVisible">
|
||||||
|
<el-form-item >
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="4095"
|
||||||
|
placeholder="巡航速度"
|
||||||
|
addonBefore="巡航速度"
|
||||||
|
addonAfter="(1-4095)"
|
||||||
|
v-if="setSpeedVisible"
|
||||||
|
v-model="cruiseSpeed"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="setCruiseSpeed">保存</el-button>
|
||||||
|
<el-button @click="cancelSetCruiseSpeed">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-button v-else size="mini" @click="setSpeedVisible = true">设置巡航速度</el-button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<el-form size="mini" :inline="true" v-if="setTimeVisible">
|
||||||
|
<el-form-item >
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="4095"
|
||||||
|
placeholder="巡航停留时间(秒)"
|
||||||
|
addonBefore="巡航停留时间(秒)"
|
||||||
|
addonAfter="(1-4095)"
|
||||||
|
style="width: 100%;"
|
||||||
|
v-model="cruiseTime"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="setCruiseTime">保存</el-button>
|
||||||
|
<el-button @click="cancelSetCruiseTime">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-button v-else size="mini" @click="setTimeVisible = true">设置巡航时间</el-button>
|
||||||
|
<el-button size="mini" @click="startCruise">开始巡航</el-button>
|
||||||
|
<el-button size="mini" @click="stopCruise">停止巡航</el-button>
|
||||||
|
<el-button size="mini" type="danger" @click="deleteCruise">删除巡航</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ptzCruising",
|
||||||
|
props: [ 'channelDeviceId', 'deviceId'],
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
this.getPresetList()
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cruiseId: 1,
|
||||||
|
presetList: [],
|
||||||
|
allPresetList: [],
|
||||||
|
selectPreset: "",
|
||||||
|
inputVisible: false,
|
||||||
|
selectPresetVisible: false,
|
||||||
|
setSpeedVisible: false,
|
||||||
|
setTimeVisible: false,
|
||||||
|
cruiseSpeed: '',
|
||||||
|
cruiseTime: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getPresetList: function () {
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/preset/query/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.allPresetList = res.data.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch((error)=> {
|
||||||
|
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addCruisePoint: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/point/add/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId,
|
||||||
|
presetId: this.selectPreset.presetId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.presetList.push(this.selectPreset)
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
this.selectPreset = ""
|
||||||
|
this.selectPresetVisible = false;
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancelAddCruisePoint: function () {
|
||||||
|
this.selectPreset = ""
|
||||||
|
this.selectPresetVisible = false;
|
||||||
|
},
|
||||||
|
delPreset: function (preset, index){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/point/delete/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId,
|
||||||
|
presetId: preset.presetId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.presetList.splice(index, 1)
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
deleteCruise: function (preset, index){
|
||||||
|
this.$confirm("确定删除此巡航组", '提示', {
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/point/delete/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId,
|
||||||
|
presetId: 0
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.presetList = []
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setCruiseSpeed: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/speed/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId,
|
||||||
|
speed: this.cruiseSpeed
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
this.cruiseSpeed = ""
|
||||||
|
this.setSpeedVisible = false
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancelSetCruiseSpeed: function (){
|
||||||
|
this.cruiseSpeed = ""
|
||||||
|
this.setSpeedVisible = false
|
||||||
|
},
|
||||||
|
setCruiseTime: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/time/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId,
|
||||||
|
time: this.cruiseTime
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
this.setTimeVisible = false;
|
||||||
|
this.cruiseTime = "";
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancelSetCruiseTime: function (){
|
||||||
|
this.setTimeVisible = false;
|
||||||
|
this.cruiseTime = "";
|
||||||
|
},
|
||||||
|
startCruise: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/start/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "发送成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
stopCruise: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/cruise/stop/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
cruiseId: this.cruiseId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "发送成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.channel-form {
|
||||||
|
display: grid;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
212
web_src/src/components/common/ptzPreset.vue
Normal file
212
web_src/src/components/common/ptzPreset.vue
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
<template>
|
||||||
|
<div id="ptzPreset" style="width: 100%">
|
||||||
|
<el-tag v-for="item in presetList"
|
||||||
|
key="item.presetId"
|
||||||
|
closable
|
||||||
|
@close="delPreset(item)"
|
||||||
|
@click="gotoPreset(item)"
|
||||||
|
size="mini"
|
||||||
|
style="margin-right: 1rem; cursor: pointer; margin-bottom: 0.6rem"
|
||||||
|
>
|
||||||
|
{{item.presetName?item.presetName:item.presetId}}
|
||||||
|
</el-tag>
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="255"
|
||||||
|
placeholder="预置位编号"
|
||||||
|
addonBefore="预置位编号"
|
||||||
|
addonAfter="(1-255)"
|
||||||
|
style="width: 300px; vertical-align: bottom;"
|
||||||
|
v-if="inputVisible"
|
||||||
|
v-model="ptzPresetId"
|
||||||
|
ref="saveTagInput"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<el-button @click="addPreset()">保存</el-button>
|
||||||
|
<el-button @click="cancel()">取消</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-button v-else size="small" @click="showInput">+ 添加</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ptzPreset",
|
||||||
|
props: [ 'channelDeviceId', 'deviceId'],
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
this.getPresetList()
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
presetList: [],
|
||||||
|
inputVisible: false,
|
||||||
|
ptzPresetId: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getPresetList: function () {
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/preset/query/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.presetList = res.data.data;
|
||||||
|
// 防止出现表格错位
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.channelListTable.doLayout();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch((error)=> {
|
||||||
|
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showInput() {
|
||||||
|
this.inputVisible = true;
|
||||||
|
this.$nextTick(_ => {
|
||||||
|
this.$refs.saveTagInput.$refs.input.focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addPreset: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/preset/add/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
presetId: this.ptzPresetId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.close()
|
||||||
|
this.inputVisible = false;
|
||||||
|
this.ptzPresetId = ""
|
||||||
|
this.getPresetList()
|
||||||
|
}, 1000)
|
||||||
|
}else {
|
||||||
|
loading.close()
|
||||||
|
this.inputVisible = false;
|
||||||
|
this.ptzPresetId = ""
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
loading.close()
|
||||||
|
this.inputVisible = false;
|
||||||
|
this.ptzPresetId = ""
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancel: function () {
|
||||||
|
this.inputVisible = false;
|
||||||
|
this.ptzPresetId = ""
|
||||||
|
},
|
||||||
|
gotoPreset: function (preset){
|
||||||
|
console.log(preset)
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/preset/call/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
presetId: preset.presetId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: '调用成功',
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
delPreset: function (preset){
|
||||||
|
this.$confirm("确定删除此预置位", '提示', {
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/preset/delete/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
presetId: preset.presetId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.close()
|
||||||
|
this.getPresetList()
|
||||||
|
}, 1000)
|
||||||
|
}else {
|
||||||
|
loading.close()
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}).catch((error)=> {
|
||||||
|
loading.close()
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).catch(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.channel-form {
|
||||||
|
display: grid;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
273
web_src/src/components/common/ptzScan.vue
Normal file
273
web_src/src/components/common/ptzScan.vue
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<div id="ptzScan">
|
||||||
|
<div style="display: grid; grid-template-columns: 80px auto; line-height: 28px">
|
||||||
|
<span>扫描组号: </span>
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="255"
|
||||||
|
placeholder="扫描组号"
|
||||||
|
addonBefore="扫描组号"
|
||||||
|
addonAfter="(1-255)"
|
||||||
|
v-model="scanId"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button size="mini" @click="setScanLeft">设置左边界</el-button>
|
||||||
|
<el-button size="mini" @click="setScanRight">设置右边界</el-button>
|
||||||
|
|
||||||
|
<el-form size="mini" :inline="true" v-if="setSpeedVisible">
|
||||||
|
<el-form-item >
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="4095"
|
||||||
|
placeholder="巡航速度"
|
||||||
|
addonBefore="巡航速度"
|
||||||
|
addonAfter="(1-4095)"
|
||||||
|
v-if="setSpeedVisible"
|
||||||
|
v-model="speed"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="setSpeed">保存</el-button>
|
||||||
|
<el-button @click="cancelSetSpeed">取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-button v-else size="mini" @click="setSpeedVisible = true">设置扫描速度</el-button>
|
||||||
|
|
||||||
|
<el-button size="mini" @click="startScan">开始自动扫描</el-button>
|
||||||
|
<el-button size="mini" @click="stopScan">停止自动扫描</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ptzScan",
|
||||||
|
props: [ 'channelDeviceId', 'deviceId'],
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
scanId: 1,
|
||||||
|
setSpeedVisible: false,
|
||||||
|
speed: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setSpeed: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/scan/set/speed/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
scanId: this.scanId,
|
||||||
|
speed: this.speed
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
this.speed = ""
|
||||||
|
this.setSpeedVisible = false
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cancelSetSpeed: function (){
|
||||||
|
this.speed = ""
|
||||||
|
this.setSpeedVisible = false
|
||||||
|
},
|
||||||
|
setScanLeft: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/scan/set/left/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
scanId: this.scanId,
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setScanRight: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/scan/set/right/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
scanId: this.scanId,
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
this.setSpeedVisible = false;
|
||||||
|
this.speed = "";
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
startScan: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/scan/start/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
scanId: this.scanId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "发送成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
stopScan: function (){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/scan/stop/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
scanId: this.scanId
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "发送成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.channel-form {
|
||||||
|
display: grid;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
90
web_src/src/components/common/ptzSwitch.vue
Normal file
90
web_src/src/components/common/ptzSwitch.vue
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<div id="ptzScan">
|
||||||
|
<el-form size="mini" :inline="true" >
|
||||||
|
<el-form-item >
|
||||||
|
<el-input
|
||||||
|
min="1"
|
||||||
|
max="4095"
|
||||||
|
placeholder="开关编号"
|
||||||
|
addonBefore="开关编号"
|
||||||
|
addonAfter="(2-255)"
|
||||||
|
v-model="switchId"
|
||||||
|
size="mini"
|
||||||
|
>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button size="mini" @click="open('on')">开启</el-button>
|
||||||
|
<el-button size="mini" @click="open('off')">关闭</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ptzScan",
|
||||||
|
props: [ 'channelDeviceId', 'deviceId'],
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
switchId: 1,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open: function (command){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/auxiliary/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
command: command,
|
||||||
|
switchId: this.switchId,
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.channel-form {
|
||||||
|
display: grid;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
70
web_src/src/components/common/ptzWiper.vue
Normal file
70
web_src/src/components/common/ptzWiper.vue
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div id="ptzWiper">
|
||||||
|
<el-button size="mini" @click="open('on')">开启</el-button>
|
||||||
|
<el-button size="mini" @click="open('off')">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ptzWiper",
|
||||||
|
props: [ 'channelDeviceId', 'deviceId'],
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open: function (command){
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
fullscreen: true,
|
||||||
|
text: '正在发送指令',
|
||||||
|
spinner: 'el-icon-loading',
|
||||||
|
background: 'rgba(0, 0, 0, 0.7)'
|
||||||
|
})
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/front-end/wiper/${this.deviceId}/${this.channelDeviceId}`,
|
||||||
|
params: {
|
||||||
|
command: command,
|
||||||
|
}
|
||||||
|
}).then((res)=> {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: "保存成功",
|
||||||
|
type: 'success'
|
||||||
|
});
|
||||||
|
}else {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: res.data.msg,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((error)=> {
|
||||||
|
this.$message({
|
||||||
|
showClose: true,
|
||||||
|
message: error,
|
||||||
|
type: 'error'
|
||||||
|
});
|
||||||
|
}).finally(()=>{
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.channel-form {
|
||||||
|
display: grid;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 1rem 2rem 0 2rem;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -60,16 +60,14 @@ export default {
|
|||||||
url:`/api/device/query/${this.deviceId}/sync_status/`,
|
url:`/api/device/query/${this.deviceId}/sync_status/`,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
if (!this.syncFlag) {
|
|
||||||
this.syncFlag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.data.data != null) {
|
if (res.data.data != null) {
|
||||||
if (res.data.data.syncIng) {
|
if (res.data.data.syncIng) {
|
||||||
if (res.data.data.total == 0) {
|
if (res.data.data.total === 0) {
|
||||||
this.msg = `等待同步中`;
|
this.msg = `等待同步中`;
|
||||||
this.timmer = setTimeout(this.getProgress, 300)
|
this.timmer = setTimeout(this.getProgress, 300)
|
||||||
}else {
|
}else {
|
||||||
|
this.syncFlag = true;
|
||||||
this.total = res.data.data.total;
|
this.total = res.data.data.total;
|
||||||
this.current = res.data.data.current;
|
this.current = res.data.data.current;
|
||||||
this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100;
|
this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100;
|
||||||
@ -89,6 +87,9 @@ export default {
|
|||||||
}, 3000)
|
}, 3000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
this.msg = res.data.msg;
|
||||||
|
this.timmer = setTimeout(this.getProgress, 300)
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
if (this.syncFlag) {
|
if (this.syncFlag) {
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="shared" style="text-align: right; margin-top: 1rem;">
|
<div id="shared" style="text-align: right; margin-top: 1rem;">
|
||||||
|
|
||||||
<el-tabs v-model="tabActiveName" @tab-click="tabHandleClick">
|
<el-tabs v-model="tabActiveName" @tab-click="tabHandleClick">
|
||||||
<el-tab-pane label="实时视频" name="media">
|
<el-tab-pane label="实时视频" name="media">
|
||||||
<div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
|
<div style="display: flex; margin-bottom: 0.5rem; height: 2.5rem;">
|
||||||
@ -154,148 +155,84 @@
|
|||||||
<!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
|
<!--{"code":0,"data":{"paths":["22-29-30.mp4"],"rootPath":"/home/kkkkk/Documents/ZLMediaKit/release/linux/Debug/www/record/hls/kkkkk/2020-05-11/"}}-->
|
||||||
<!--遥控界面-->
|
<!--遥控界面-->
|
||||||
<el-tab-pane label="云台控制" name="control" v-if="showPtz">
|
<el-tab-pane label="云台控制" name="control" v-if="showPtz">
|
||||||
<div style="display: flex; justify-content: left;">
|
<div style="display: grid; grid-template-columns: 240px auto; height: 180px; overflow: auto">
|
||||||
<div class="control-wrapper">
|
<div style="display: grid; grid-template-columns: 6.25rem auto;">
|
||||||
<div class="control-btn control-top" @mousedown="ptzCamera('up')" @mouseup="ptzCamera('stop')">
|
|
||||||
<i class="el-icon-caret-top"></i>
|
<div class="control-wrapper">
|
||||||
<div class="control-inner-btn control-inner"></div>
|
<div class="control-btn control-top" @mousedown="ptzCamera('up')" @mouseup="ptzCamera('stop')">
|
||||||
|
<i class="el-icon-caret-top"></i>
|
||||||
|
<div class="control-inner-btn control-inner"></div>
|
||||||
|
</div>
|
||||||
|
<div class="control-btn control-left" @mousedown="ptzCamera('left')" @mouseup="ptzCamera('stop')">
|
||||||
|
<i class="el-icon-caret-left"></i>
|
||||||
|
<div class="control-inner-btn control-inner"></div>
|
||||||
|
</div>
|
||||||
|
<div class="control-btn control-bottom" @mousedown="ptzCamera('down')" @mouseup="ptzCamera('stop')">
|
||||||
|
<i class="el-icon-caret-bottom"></i>
|
||||||
|
<div class="control-inner-btn control-inner"></div>
|
||||||
|
</div>
|
||||||
|
<div class="control-btn control-right" @mousedown="ptzCamera('right')" @mouseup="ptzCamera('stop')">
|
||||||
|
<i class="el-icon-caret-right"></i>
|
||||||
|
<div class="control-inner-btn control-inner"></div>
|
||||||
|
</div>
|
||||||
|
<div class="control-round">
|
||||||
|
<div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
|
||||||
|
</div>
|
||||||
|
<div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 6.25rem;">
|
||||||
|
<el-slider v-model="controSpeed" :max="100"></el-slider>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-btn control-left" @mousedown="ptzCamera('left')" @mouseup="ptzCamera('stop')">
|
<div>
|
||||||
<i class="el-icon-caret-left"></i>
|
<div class="ptz-btn-box">
|
||||||
<div class="control-inner-btn control-inner"></div>
|
<div style="" @mousedown="ptzCamera('zoomin')" @mouseup="ptzCamera('stop')" title="变倍+">
|
||||||
</div>
|
<i class="el-icon-zoom-in control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||||
<div class="control-btn control-bottom" @mousedown="ptzCamera('down')" @mouseup="ptzCamera('stop')">
|
</div>
|
||||||
<i class="el-icon-caret-bottom"></i>
|
<div style="" @mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')" title="变倍-">
|
||||||
<div class="control-inner-btn control-inner"></div>
|
<i class="el-icon-zoom-out control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-btn control-right" @mousedown="ptzCamera('right')" @mouseup="ptzCamera('stop')">
|
</div>
|
||||||
<i class="el-icon-caret-right"></i>
|
<div class="ptz-btn-box">
|
||||||
<div class="control-inner-btn control-inner"></div>
|
<div @mousedown="focusCamera('near')" @mouseup="focusCamera('stop')" title="聚焦+">
|
||||||
</div>
|
<i class="iconfont icon-bianjiao-fangda control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||||
<div class="control-round">
|
</div>
|
||||||
<div class="control-round-inner"><i class="fa fa-pause-circle"></i></div>
|
<div @mousedown="focusCamera('far')" @mouseup="focusCamera('stop')" title="聚焦-">
|
||||||
</div>
|
<i class="iconfont icon-bianjiao-suoxiao control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||||
<div style="position: absolute; left: 7.25rem; top: 1.25rem" @mousedown="ptzCamera('zoomin')"
|
</div>
|
||||||
@mouseup="ptzCamera('stop')"><i class="el-icon-zoom-in control-zoom-btn"
|
</div>
|
||||||
style="font-size: 1.875rem;"></i></div>
|
<div class="ptz-btn-box">
|
||||||
<div style="position: absolute; left: 7.25rem; top: 3.25rem; font-size: 1.875rem;"
|
<div @mousedown="irisCamera('in')" @mouseup="irisCamera('stop')" title="光圈+">
|
||||||
@mousedown="ptzCamera('zoomout')" @mouseup="ptzCamera('stop')"><i
|
<i class="iconfont icon-guangquan control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||||
class="el-icon-zoom-out control-zoom-btn"></i></div>
|
</div>
|
||||||
<div class="contro-speed" style="position: absolute; left: 4px; top: 7rem; width: 9rem;">
|
<div @mousedown="pirisCamera('out')" @mouseup="irisCamera('stop')" title="光圈-">
|
||||||
<el-slider v-model="controSpeed" :max="255"></el-slider>
|
<i class="iconfont icon-guangquan- control-zoom-btn" style="font-size: 1.5rem;"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="text-align: left" >
|
||||||
|
<el-select
|
||||||
|
v-model="ptzMethod"
|
||||||
|
style="width: 100%"
|
||||||
|
size="mini"
|
||||||
|
placeholder="请选择云台功能"
|
||||||
|
>
|
||||||
|
<el-option label="预置点" value="preset"></el-option>
|
||||||
|
<el-option label="巡航组" value="cruise"></el-option>
|
||||||
|
<el-option label="自动扫描" value="scan"></el-option>
|
||||||
|
<el-option label="雨刷" value="wiper"></el-option>
|
||||||
|
<el-option label="辅助开关" value="switch"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
<div class="control-panel">
|
<ptzPreset :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'preset'" style="margin-top: 1rem"></ptzPreset>
|
||||||
<el-button-group>
|
<ptzCruising :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'cruise'" style="margin-top: 1rem"></ptzCruising>
|
||||||
<el-tag style="position :absolute; left: 0rem; top: 0rem; width: 5rem; text-align: center"
|
<ptzScan :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'scan'" style="margin-top: 1rem"></ptzScan>
|
||||||
size="medium">预置位编号
|
<ptzWiper :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'wiper'" style="margin-top: 1rem"></ptzWiper>
|
||||||
</el-tag>
|
<ptzSwitch :channelDeviceId="channelId" :deviceId="deviceId" v-if="ptzMethod === 'switch'" style="margin-top: 1rem"></ptzSwitch>
|
||||||
<el-input-number style="position: absolute; left: 5rem; top: 0rem; width: 6rem" size="mini"
|
|
||||||
v-model="presetPos" controls-position="right" :precision="0" :step="1" :min="1"
|
|
||||||
:max="255"></el-input-number>
|
|
||||||
<el-button style="position: absolute; left: 11rem; top: 0rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-add-location" @click="presetPosition(129, presetPos)">设置
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 27rem; top: 0rem; width: 5rem" size="mini" type="primary"
|
|
||||||
icon="el-icon-place" @click="presetPosition(130, presetPos)">调用
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 16rem; top: 0rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-delete-location" @click="presetPosition(131, presetPos)">删除
|
|
||||||
</el-button>
|
|
||||||
<el-tag style="position :absolute; left: 0rem; top: 2.5rem; width: 5rem; text-align: center"
|
|
||||||
size="medium">巡航速度
|
|
||||||
</el-tag>
|
|
||||||
<el-input-number style="position: absolute; left: 5rem; top: 2.5rem; width: 6rem" size="mini"
|
|
||||||
v-model="cruisingSpeed" controls-position="right" :precision="0" :min="1"
|
|
||||||
:max="4095"></el-input-number>
|
|
||||||
<el-button style="position: absolute; left: 11rem; top: 2.5rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-loading" @click="setSpeedOrTime(134, cruisingGroup, cruisingSpeed)">设置
|
|
||||||
</el-button>
|
|
||||||
<el-tag style="position :absolute; left: 16rem; top: 2.5rem; width: 5rem; text-align: center"
|
|
||||||
size="medium">停留时间
|
|
||||||
</el-tag>
|
|
||||||
<el-input-number style="position: absolute; left: 21rem; top: 2.5rem; width: 6rem" size="mini"
|
|
||||||
v-model="cruisingTime" controls-position="right" :precision="0" :min="1"
|
|
||||||
:max="4095"></el-input-number>
|
|
||||||
<el-button style="position: absolute; left: 27rem; top: 2.5rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-timer" @click="setSpeedOrTime(135, cruisingGroup, cruisingTime)">设置
|
|
||||||
</el-button>
|
|
||||||
<el-tag style="position :absolute; left: 0rem; top: 4.5rem; width: 5rem; text-align: center"
|
|
||||||
size="medium">巡航组编号
|
|
||||||
</el-tag>
|
|
||||||
<el-input-number style="position: absolute; left: 5rem; top: 4.5rem; width: 6rem" size="mini"
|
|
||||||
v-model="cruisingGroup" controls-position="right" :precision="0" :min="0"
|
|
||||||
:max="255"></el-input-number>
|
|
||||||
<el-button style="position: absolute; left: 11rem; top: 4.5rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-add-location" @click="setCommand(132, cruisingGroup, presetPos)">添加点
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 16rem; top: 4.5rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-delete-location" @click="setCommand(133, cruisingGroup, presetPos)">删除点
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 21rem; top: 4.5rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-delete" @click="setCommand(133, cruisingGroup, 0)">删除组
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 27rem; top: 5rem; width: 5rem" size="mini" type="primary"
|
|
||||||
icon="el-icon-video-camera-solid" @click="setCommand(136, cruisingGroup, 0)">巡航
|
|
||||||
</el-button>
|
|
||||||
<el-tag style="position :absolute; left: 0rem; top: 7rem; width: 5rem; text-align: center"
|
|
||||||
size="medium">扫描速度
|
|
||||||
</el-tag>
|
|
||||||
<el-input-number style="position: absolute; left: 5rem; top: 7rem; width: 6rem" size="mini"
|
|
||||||
v-model="scanSpeed" controls-position="right" :precision="0" :min="1"
|
|
||||||
:max="4095"></el-input-number>
|
|
||||||
<el-button style="position: absolute; left: 11rem; top: 7rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-loading" @click="setSpeedOrTime(138, scanGroup, scanSpeed)">设置
|
|
||||||
</el-button>
|
|
||||||
<el-tag style="position :absolute; left: 0rem; top: 9rem; width: 5rem; text-align: center"
|
|
||||||
size="medium">扫描组编号
|
|
||||||
</el-tag>
|
|
||||||
<el-input-number style="position: absolute; left: 5rem; top: 9rem; width: 6rem" size="mini"
|
|
||||||
v-model="scanGroup" controls-position="right" :precision="0" :step="1" :min="0"
|
|
||||||
:max="255"></el-input-number>
|
|
||||||
<el-button style="position: absolute; left: 11rem; top: 9rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-d-arrow-left" @click="setCommand(137, scanGroup, 1)">左边界
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 16rem; top: 9rem; width: 5rem" size="mini"
|
|
||||||
icon="el-icon-d-arrow-right" @click="setCommand(137, scanGroup, 2)">右边界
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 27rem; top: 7rem; width: 5rem" size="mini" type="primary"
|
|
||||||
icon="el-icon-video-camera-solid" @click="setCommand(137, scanGroup, 0)">扫描
|
|
||||||
</el-button>
|
|
||||||
<el-button style="position: absolute; left: 27rem; top: 9rem; width: 5rem" size="mini" type="danger"
|
|
||||||
icon="el-icon-switch-button" @click="ptzCamera('stop')">停止
|
|
||||||
</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="编码信息" name="codec" v-loading="tracksLoading">
|
<el-tab-pane label="编码信息" name="codec" v-loading="tracksLoading">
|
||||||
<p>
|
<mediaInfo :app="app" :stream="streamId" :mediaServerId="mediaServerId"></mediaInfo>
|
||||||
无法播放或者没有声音?   试一试 
|
|
||||||
<el-button size="mini" type="primary" v-if="!coverPlaying" @click="coverPlay">转码播放</el-button>
|
|
||||||
<el-button size="mini" type="danger" v-if="coverPlaying" @click="convertStopClick">停止转码</el-button>
|
|
||||||
</p>
|
|
||||||
<div class="trank">
|
|
||||||
<p v-if="tracksNotLoaded" style="text-align: center;padding-top: 3rem;">暂无数据</p>
|
|
||||||
<div v-for="(item, index) in tracks" style="width: 50%; float: left" loading>
|
|
||||||
<span>流 {{ index }}</span>
|
|
||||||
<div class="trankInfo" v-if="item.codec_type == 0">
|
|
||||||
<p>格式: {{ item.codec_id_name }}</p>
|
|
||||||
<p>类型: 视频</p>
|
|
||||||
<p>分辨率: {{ item.width }} x {{ item.height }}</p>
|
|
||||||
<p>帧率: {{ item.fps }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="trankInfo" v-if="item.codec_type == 1">
|
|
||||||
<p>格式: {{ item.codec_id_name }}</p>
|
|
||||||
<p>类型: 音频</p>
|
|
||||||
<p>采样位数: {{ item.sample_bit }}</p>
|
|
||||||
<p>采样率: {{ item.sample_rate }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="语音对讲" name="broadcast">
|
<el-tab-pane label="语音对讲" name="broadcast">
|
||||||
<div style="padding: 0 10px">
|
<div style="padding: 0 10px">
|
||||||
@ -327,11 +264,18 @@ import rtcPlayer from '../dialog/rtcPlayer.vue'
|
|||||||
import LivePlayer from '@liveqing/liveplayer'
|
import LivePlayer from '@liveqing/liveplayer'
|
||||||
import crypto from 'crypto'
|
import crypto from 'crypto'
|
||||||
import jessibucaPlayer from '../common/jessibuca.vue'
|
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 {
|
export default {
|
||||||
name: 'devicePlayer',
|
name: 'devicePlayer',
|
||||||
props: {},
|
props: {},
|
||||||
components: {
|
components: {
|
||||||
|
PtzPreset,PtzCruising,ptzScan,ptzWiper,ptzSwitch,mediaInfo,
|
||||||
LivePlayer, jessibucaPlayer, rtcPlayer,
|
LivePlayer, jessibucaPlayer, rtcPlayer,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -363,9 +307,10 @@ export default {
|
|||||||
},
|
},
|
||||||
showVideoDialog: false,
|
showVideoDialog: false,
|
||||||
streamId: '',
|
streamId: '',
|
||||||
|
ptzMethod: 'preset',
|
||||||
|
ptzPresetId: '',
|
||||||
app: '',
|
app: '',
|
||||||
mediaServerId: '',
|
mediaServerId: '',
|
||||||
convertKey: '',
|
|
||||||
deviceId: '',
|
deviceId: '',
|
||||||
channelId: '',
|
channelId: '',
|
||||||
tabActiveName: 'media',
|
tabActiveName: 'media',
|
||||||
@ -384,7 +329,6 @@ export default {
|
|||||||
scanSpeed: 100,
|
scanSpeed: 100,
|
||||||
scanGroup: 0,
|
scanGroup: 0,
|
||||||
tracks: [],
|
tracks: [],
|
||||||
coverPlaying: false,
|
|
||||||
tracksLoading: false,
|
tracksLoading: false,
|
||||||
showPtz: true,
|
showPtz: true,
|
||||||
showRrecord: true,
|
showRrecord: true,
|
||||||
@ -484,63 +428,6 @@ export default {
|
|||||||
}
|
}
|
||||||
return this.videoUrl;
|
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) {
|
playFromStreamInfo: function (realHasAudio, streamInfo) {
|
||||||
@ -562,10 +449,6 @@ export default {
|
|||||||
this.videoUrl = '';
|
this.videoUrl = '';
|
||||||
this.coverPlaying = false;
|
this.coverPlaying = false;
|
||||||
this.showVideoDialog = false;
|
this.showVideoDialog = false;
|
||||||
if (this.convertKey != '') {
|
|
||||||
this.convertStop();
|
|
||||||
}
|
|
||||||
this.convertKey = ''
|
|
||||||
this.stopBroadcast()
|
this.stopBroadcast()
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -595,8 +478,22 @@ export default {
|
|||||||
console.log('云台控制:' + command);
|
console.log('云台控制:' + command);
|
||||||
let that = this;
|
let that = this;
|
||||||
this.$axios({
|
this.$axios({
|
||||||
method: 'post',
|
method: 'get',
|
||||||
url: '/api/ptz/control/' + this.deviceId + '/' + this.channelId + '?command=' + command + '&horizonSpeed=' + this.controSpeed + '&verticalSpeed=' + this.controSpeed + '&zoomSpeed=' + this.controSpeed
|
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) {
|
}).then(function (res) {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -604,35 +501,6 @@ export default {
|
|||||||
videoError: function (e) {
|
videoError: function (e) {
|
||||||
console.log("播放器错误:" + JSON.stringify(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) {
|
copyUrl: function (dropdownItem) {
|
||||||
console.log(dropdownItem)
|
console.log(dropdownItem)
|
||||||
this.$copyText(dropdownItem).then((e) => {
|
this.$copyText(dropdownItem).then((e) => {
|
||||||
@ -716,17 +584,6 @@ export default {
|
|||||||
recvOnly: false,
|
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) => {// 获取到了本地流
|
this.broadcastRtc.on(ZLMRTCClient.Events.WEBRTC_NOT_SUPPORT, (e) => {// 获取到了本地流
|
||||||
console.error('不支持webrtc', e)
|
console.error('不支持webrtc', e)
|
||||||
this.$message({
|
this.$message({
|
||||||
@ -1001,4 +858,14 @@ export default {
|
|||||||
width: 80%;
|
width: 80%;
|
||||||
padding: 0 10%;
|
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;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 1291092 */
|
font-family: "iconfont"; /* Project id 1291092 */
|
||||||
src: url('iconfont.woff2?t=1726109971995') format('woff2'),
|
src: url('iconfont.woff2?t=1731484250872') format('woff2'),
|
||||||
url('iconfont.woff?t=1726109971995') format('woff'),
|
url('iconfont.woff?t=1731484250872') format('woff'),
|
||||||
url('iconfont.ttf?t=1726109971995') format('truetype');
|
url('iconfont.ttf?t=1731484250872') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -13,6 +13,22 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-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 {
|
.icon-a-mti-1fenpingshi:before {
|
||||||
content: "\e7e5";
|
content: "\e7e5";
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@ -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');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -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');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -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)
|
|
||||||
);
|
|
||||||
@ -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)
|
|
||||||
);
|
|
||||||
Loading…
Reference in New Issue
Block a user