mirror of
https://gitee.com/pan648540858/wvp-GB28181-pro.git
synced 2026-06-22 02:57:49 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
89009bce07
@ -46,6 +46,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
||||
# 功能特性
|
||||
- [X] 集成web界面
|
||||
- [X] 兼容性良好
|
||||
- [X] 跨平台服务,一次编译多端部署, 可以同时用于x86和arm架构
|
||||
- [X] 接入设备
|
||||
- [X] 视频预览
|
||||
- [X] 支持主码流子码流切换
|
||||
@ -98,7 +99,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
||||
- [X] 语音对讲
|
||||
- [X] 支持同时级联到多个上级平台
|
||||
- [X] 支持自动配置ZLM媒体服务, 减少因配置问题所出现的问题;
|
||||
- [X] 多流媒体节点,自动选择负载最低的节点使用。
|
||||
- [X] 支持流媒体节点集群,负载均衡。
|
||||
- [X] 支持启用udp多端口模式, 提高udp模式下媒体传输性能;
|
||||
- [X] 支持公网部署;
|
||||
- [X] 支持wvp与zlm分开部署,提升平台并发能力
|
||||
@ -113,10 +114,12 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
||||
- [X] 支持录制计划, 根据设定的时间对通道进行录制. 暂不支持将录制的内容转发到国标上级
|
||||
- [X] 支持Onvif, 目前付费提供, 永久免费试用包在知识星球获取
|
||||
- [X] 支持国标28181-2022协议, 目前付费提供, 永久免费试用包在知识星球获取
|
||||
- [X] 支持国标信令集群
|
||||
|
||||
|
||||
# 非开源的内容
|
||||
- [X] ONVIF设备的接入,支持点播,云台控制,国标级联点播,自动点播。试用安装包以及使用教程: [知识星球](https://t.zsxq.com/10WAnH2MP),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。
|
||||
- [X] 支持部标1078+808协议,支持点播,云台控制,录像回放,位置上报,自动点播。
|
||||
- [X] 支持国标28181-2022协议,支持巡航轨迹查询,PTZ精准控制,存储卡格式化,设备软件升级,OSD配置,h265+aac,支持辅码流,录像倒放等。具体的功能列表可在[知识星球](https://t.zsxq.com/18GXkpkqs)查看,试用安装包: [知识星球](https://t.zsxq.com/UJ6V3),没有使用时间限制,需要源码可以星球私信我或者邮箱联系。
|
||||
|
||||
|
||||
|
||||
7
pom.xml
7
pom.xml
@ -199,13 +199,6 @@
|
||||
<artifactId>springdoc-openapi-security</artifactId>
|
||||
<version>1.6.10</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>3.6.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--在线文档 -->
|
||||
<dependency>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp;
|
||||
|
||||
import com.genersoft.iot.vmp.jt1078.util.ClassUtil;
|
||||
import com.genersoft.iot.vmp.utils.GitUtil;
|
||||
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -33,6 +34,7 @@ public class VManageBootstrap extends SpringBootServletInitializer {
|
||||
public static void main(String[] args) {
|
||||
VManageBootstrap.args = args;
|
||||
VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args);
|
||||
ClassUtil.context = VManageBootstrap.context;
|
||||
GitUtil gitUtil = SpringBeanFactory.getBean("gitUtil");
|
||||
if (gitUtil == null) {
|
||||
log.info("获取版本信息失败");
|
||||
@ -62,6 +64,5 @@ public class VManageBootstrap extends SpringBootServletInitializer {
|
||||
);
|
||||
SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
|
||||
sessionCookieConfig.setHttpOnly(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,10 +35,16 @@ public class InviteInfo {
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private Boolean record;
|
||||
|
||||
private String startTime;
|
||||
|
||||
private String endTime;
|
||||
|
||||
|
||||
public static InviteInfo getInviteInfo(String deviceId, Integer channelId, String stream, SSRCInfo ssrcInfo, String mediaServerId,
|
||||
String receiveIp, Integer receivePort, String streamMode,
|
||||
InviteSessionType type, InviteSessionStatus status) {
|
||||
InviteSessionType type, InviteSessionStatus status, Boolean record) {
|
||||
InviteInfo inviteInfo = new InviteInfo();
|
||||
inviteInfo.setDeviceId(deviceId);
|
||||
inviteInfo.setChannelId(channelId);
|
||||
@ -50,6 +56,7 @@ public class InviteInfo {
|
||||
inviteInfo.setType(type);
|
||||
inviteInfo.setStatus(status);
|
||||
inviteInfo.setMediaServerId(mediaServerId);
|
||||
inviteInfo.setRecord(record);
|
||||
return inviteInfo;
|
||||
}
|
||||
|
||||
|
||||
23
src/main/java/com/genersoft/iot/vmp/common/ServerInfo.java
Normal file
23
src/main/java/com/genersoft/iot/vmp/common/ServerInfo.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.genersoft.iot.vmp.common;
|
||||
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ServerInfo {
|
||||
|
||||
private String ip;
|
||||
private int port;
|
||||
/**
|
||||
* 现在使用的线程数
|
||||
*/
|
||||
private String createTime;
|
||||
|
||||
public static ServerInfo create(String ip, int port) {
|
||||
ServerInfo serverInfo = new ServerInfo();
|
||||
serverInfo.setIp(ip);
|
||||
serverInfo.setPort(port);
|
||||
serverInfo.setCreateTime(DateUtil.getNow());
|
||||
return serverInfo;
|
||||
}
|
||||
}
|
||||
@ -4,11 +4,12 @@ import com.genersoft.iot.vmp.media.bean.MediaInfo;
|
||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
@Data
|
||||
@Schema(description = "流信息")
|
||||
public class StreamInfo implements Serializable, Cloneable{
|
||||
|
||||
@ -91,100 +92,15 @@ public class StreamInfo implements Serializable, Cloneable{
|
||||
@Schema(description = "产生源类型,包括 unknown = 0,rtmp_push=1,rtsp_push=2,rtp_push=3,pull=4,ffmpeg_pull=5,mp4_vod=6,device_chn=7")
|
||||
private int originType;
|
||||
|
||||
@Schema(description = "originType的文本描述")
|
||||
private String originTypeStr;
|
||||
|
||||
@Schema(description = "转码后的视频流")
|
||||
private StreamInfo transcodeStream;
|
||||
|
||||
@Schema(description = "使用的WVP ID")
|
||||
private String serverId;
|
||||
|
||||
public void setFlv(StreamURL flv) {
|
||||
this.flv = flv;
|
||||
}
|
||||
|
||||
public void setHttps_flv(StreamURL https_flv) {
|
||||
this.https_flv = https_flv;
|
||||
}
|
||||
|
||||
public void setWs_flv(StreamURL ws_flv) {
|
||||
this.ws_flv = ws_flv;
|
||||
}
|
||||
|
||||
public void setWss_flv(StreamURL wss_flv) {
|
||||
this.wss_flv = wss_flv;
|
||||
}
|
||||
|
||||
public void setFmp4(StreamURL fmp4) {
|
||||
this.fmp4 = fmp4;
|
||||
}
|
||||
|
||||
public void setHttps_fmp4(StreamURL https_fmp4) {
|
||||
this.https_fmp4 = https_fmp4;
|
||||
}
|
||||
|
||||
public void setWs_fmp4(StreamURL ws_fmp4) {
|
||||
this.ws_fmp4 = ws_fmp4;
|
||||
}
|
||||
|
||||
public void setWss_fmp4(StreamURL wss_fmp4) {
|
||||
this.wss_fmp4 = wss_fmp4;
|
||||
}
|
||||
|
||||
public void setHls(StreamURL hls) {
|
||||
this.hls = hls;
|
||||
}
|
||||
|
||||
public void setHttps_hls(StreamURL https_hls) {
|
||||
this.https_hls = https_hls;
|
||||
}
|
||||
|
||||
public void setWs_hls(StreamURL ws_hls) {
|
||||
this.ws_hls = ws_hls;
|
||||
}
|
||||
|
||||
public void setWss_hls(StreamURL wss_hls) {
|
||||
this.wss_hls = wss_hls;
|
||||
}
|
||||
|
||||
public void setTs(StreamURL ts) {
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
public void setHttps_ts(StreamURL https_ts) {
|
||||
this.https_ts = https_ts;
|
||||
}
|
||||
|
||||
public void setWs_ts(StreamURL ws_ts) {
|
||||
this.ws_ts = ws_ts;
|
||||
}
|
||||
|
||||
public void setWss_ts(StreamURL wss_ts) {
|
||||
this.wss_ts = wss_ts;
|
||||
}
|
||||
|
||||
public void setRtmp(StreamURL rtmp) {
|
||||
this.rtmp = rtmp;
|
||||
}
|
||||
|
||||
public void setRtmps(StreamURL rtmps) {
|
||||
this.rtmps = rtmps;
|
||||
}
|
||||
|
||||
public void setRtsp(StreamURL rtsp) {
|
||||
this.rtsp = rtsp;
|
||||
}
|
||||
|
||||
public void setRtsps(StreamURL rtsps) {
|
||||
this.rtsps = rtsps;
|
||||
}
|
||||
|
||||
public void setRtc(StreamURL rtc) {
|
||||
this.rtc = rtc;
|
||||
}
|
||||
|
||||
public void setRtcs(StreamURL rtcs) {
|
||||
this.rtcs = rtcs;
|
||||
}
|
||||
|
||||
public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) {
|
||||
String file = String.format("%s/%s%s", app, stream, callIdParam);
|
||||
if (port > 0) {
|
||||
@ -275,7 +191,7 @@ public class StreamInfo implements Serializable, Cloneable{
|
||||
}
|
||||
}
|
||||
|
||||
public void channgeStreamIp(String localAddr) {
|
||||
public void changeStreamIp(String localAddr) {
|
||||
if (this.flv != null) {
|
||||
this.flv.setHost(localAddr);
|
||||
}
|
||||
@ -351,205 +267,6 @@ public class StreamInfo implements Serializable, Cloneable{
|
||||
|
||||
private TransactionInfo transactionInfo;
|
||||
|
||||
public String getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
public void setApp(String app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public Integer getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(Integer channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
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 StreamURL getFlv() {
|
||||
return flv;
|
||||
}
|
||||
|
||||
public StreamURL getHttps_flv() {
|
||||
return https_flv;
|
||||
}
|
||||
|
||||
public StreamURL getWs_flv() {
|
||||
return ws_flv;
|
||||
}
|
||||
|
||||
|
||||
public StreamURL getWss_flv() {
|
||||
return wss_flv;
|
||||
}
|
||||
|
||||
public StreamURL getFmp4() {
|
||||
return fmp4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public StreamURL getHttps_fmp4() {
|
||||
return https_fmp4;
|
||||
}
|
||||
|
||||
public StreamURL getWs_fmp4() {
|
||||
return ws_fmp4;
|
||||
}
|
||||
|
||||
public StreamURL getWss_fmp4() {
|
||||
return wss_fmp4;
|
||||
}
|
||||
|
||||
public StreamURL getHls() {
|
||||
return hls;
|
||||
}
|
||||
|
||||
|
||||
public StreamURL getHttps_hls() {
|
||||
return https_hls;
|
||||
}
|
||||
|
||||
public StreamURL getWs_hls() {
|
||||
return ws_hls;
|
||||
}
|
||||
|
||||
public StreamURL getWss_hls() {
|
||||
return wss_hls;
|
||||
}
|
||||
|
||||
public StreamURL getTs() {
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
public StreamURL getHttps_ts() {
|
||||
return https_ts;
|
||||
}
|
||||
|
||||
|
||||
public StreamURL getWs_ts() {
|
||||
return ws_ts;
|
||||
}
|
||||
|
||||
|
||||
public StreamURL getWss_ts() {
|
||||
return wss_ts;
|
||||
}
|
||||
|
||||
|
||||
public StreamURL getRtmp() {
|
||||
return rtmp;
|
||||
}
|
||||
|
||||
public StreamURL getRtmps() {
|
||||
return rtmps;
|
||||
}
|
||||
|
||||
public StreamURL getRtsp() {
|
||||
return rtsp;
|
||||
}
|
||||
|
||||
public StreamURL getRtsps() {
|
||||
return rtsps;
|
||||
}
|
||||
|
||||
public StreamURL getRtc() {
|
||||
return rtc;
|
||||
}
|
||||
|
||||
public StreamURL getRtcs() {
|
||||
return rtcs;
|
||||
}
|
||||
|
||||
public MediaServer getMediaServer() {
|
||||
return mediaServer;
|
||||
}
|
||||
|
||||
public void setMediaServer(MediaServer mediaServer) {
|
||||
this.mediaServer = mediaServer;
|
||||
}
|
||||
|
||||
public MediaInfo getMediaInfo() {
|
||||
return mediaInfo;
|
||||
}
|
||||
|
||||
public void setMediaInfo(MediaInfo mediaInfo) {
|
||||
this.mediaInfo = mediaInfo;
|
||||
}
|
||||
|
||||
public String getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(String startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public String getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(String endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public double getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setProgress(double progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public boolean isPause() {
|
||||
return pause;
|
||||
}
|
||||
|
||||
public void setPause(boolean pause) {
|
||||
this.pause = pause;
|
||||
}
|
||||
|
||||
public TransactionInfo getTransactionInfo() {
|
||||
return transactionInfo;
|
||||
}
|
||||
|
||||
public void setTransactionInfo(TransactionInfo transactionInfo) {
|
||||
this.transactionInfo = transactionInfo;
|
||||
}
|
||||
|
||||
public StreamInfo getTranscodeStream() {
|
||||
return transcodeStream;
|
||||
}
|
||||
|
||||
public void setTranscodeStream(StreamInfo transcodeStream) {
|
||||
this.transcodeStream = transcodeStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamInfo clone() {
|
||||
@ -625,48 +342,4 @@ public class StreamInfo implements Serializable, Cloneable{
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
/*=========================设备主子码流逻辑START====================*/
|
||||
@Schema(description = "是否为子码流(true-是,false-主码流)")
|
||||
private boolean subStream;
|
||||
|
||||
public boolean isSubStream() {
|
||||
return subStream;
|
||||
}
|
||||
|
||||
public void setSubStream(boolean subStream) {
|
||||
this.subStream = subStream;
|
||||
}
|
||||
|
||||
public DownloadFileInfo getDownLoadFilePath() {
|
||||
return downLoadFilePath;
|
||||
}
|
||||
|
||||
public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) {
|
||||
this.downLoadFilePath = downLoadFilePath;
|
||||
}
|
||||
|
||||
public int getOriginType() {
|
||||
return originType;
|
||||
}
|
||||
|
||||
public void setOriginType(int originType) {
|
||||
this.originType = originType;
|
||||
}
|
||||
|
||||
public String getServerId() {
|
||||
return serverId;
|
||||
}
|
||||
|
||||
public void setServerId(String serverId) {
|
||||
this.serverId = serverId;
|
||||
}
|
||||
|
||||
public String getCallId() {
|
||||
return callId;
|
||||
}
|
||||
|
||||
public void setCallId(String callId) {
|
||||
this.callId = callId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ public class VideoManagerConstants {
|
||||
|
||||
public static final String WVP_SERVER_PREFIX = "VMP_SIGNALLING_SERVER_INFO_";
|
||||
|
||||
public static final String WVP_SERVER_LIST = "VMP_SERVER_LIST";
|
||||
|
||||
public static final String WVP_SERVER_STREAM_PREFIX = "VMP_SIGNALLING_STREAM_";
|
||||
|
||||
public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_INFO:";
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.genersoft.iot.vmp.common.enums;
|
||||
|
||||
/**
|
||||
* 支持的通道数据类型
|
||||
*/
|
||||
|
||||
public enum ChannelDataType {
|
||||
|
||||
GB28181(1,"国标28181"),
|
||||
STREAM_PUSH(2,"推流设备"),
|
||||
STREAM_PROXY(3,"拉流代理");
|
||||
|
||||
public final int value;
|
||||
|
||||
public final String desc;
|
||||
|
||||
ChannelDataType(Integer value, String desc) {
|
||||
this.value = value;
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true)
|
||||
@Order(0)
|
||||
@ -16,6 +18,8 @@ public class SipConfig {
|
||||
|
||||
private String showIp;
|
||||
|
||||
private List<String> monitorIps;
|
||||
|
||||
private Integer port;
|
||||
|
||||
private String domain;
|
||||
@ -30,5 +34,5 @@ public class SipConfig {
|
||||
|
||||
private boolean alarm = false;
|
||||
|
||||
private long timeout = 15;
|
||||
private long timeout = 150;
|
||||
}
|
||||
|
||||
@ -31,10 +31,13 @@ public class SipPlatformRunner implements CommandLineRunner {
|
||||
@Autowired
|
||||
private ISIPCommanderForPlatform sipCommanderForPlatform;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
// 获取所有启用的平台
|
||||
List<Platform> parentPlatforms = platformService.queryEnablePlatformList();
|
||||
List<Platform> parentPlatforms = platformService.queryEnablePlatformList(userSetting.getServerId());
|
||||
|
||||
for (Platform platform : parentPlatforms) {
|
||||
|
||||
|
||||
@ -37,6 +37,11 @@ public class UserSetting {
|
||||
*/
|
||||
private Integer playTimeout = 10000;
|
||||
|
||||
/**
|
||||
* 获取设备录像数据超时时间,单位:毫秒
|
||||
*/
|
||||
private Integer recordInfoTimeout = 15000;
|
||||
|
||||
/**
|
||||
* 上级点播等待超时时间,单位:毫秒
|
||||
*/
|
||||
@ -170,4 +175,20 @@ public class UserSetting {
|
||||
*/
|
||||
private int gbDeviceOnline = 1;
|
||||
|
||||
/**
|
||||
* 登录超时时间(分钟),
|
||||
*/
|
||||
private long loginTimeout = 30;
|
||||
|
||||
/**
|
||||
* jwk文件路径,若不指定则使用resources目录下的jwk.json
|
||||
*/
|
||||
private String jwkFile = "classpath:jwk.json";
|
||||
|
||||
/**
|
||||
* wvp集群模式下如果注册向上级的wvp奔溃,则自动选择一个其他wvp继续注册到上级
|
||||
*/
|
||||
private boolean autoRegisterPlatform = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
package com.genersoft.iot.vmp.conf;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.ServerInfo;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
public class WVPTimerTask {
|
||||
|
||||
@ -19,11 +21,8 @@ public class WVPTimerTask {
|
||||
@Autowired
|
||||
private SipConfig sipConfig;
|
||||
|
||||
@Scheduled(fixedDelay = 2 * 1000) //每3秒执行一次
|
||||
@Scheduled(fixedDelay = 2, timeUnit = TimeUnit.SECONDS) //每3秒执行一次
|
||||
public void execute(){
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("ip", sipConfig.getShowIp());
|
||||
jsonObject.put("port", serverPort);
|
||||
redisCatchStorage.updateWVPInfo(jsonObject, 3);
|
||||
redisCatchStorage.updateWVPInfo(ServerInfo.create(sipConfig.getShowIp(), serverPort), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,12 @@ package com.genersoft.iot.vmp.conf.redis;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcClassHandler;
|
||||
import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcMessage;
|
||||
import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcRequest;
|
||||
import com.genersoft.iot.vmp.conf.redis.bean.RedisRpcResponse;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.control.RedisRpcController;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.dto.RpcController;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@ -16,8 +18,10 @@ import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.message.Response;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -36,9 +40,6 @@ public class RedisRpcConfig implements MessageListener {
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private RedisRpcController redisRpcController;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
@ -48,6 +49,40 @@ public class RedisRpcConfig implements MessageListener {
|
||||
@Autowired
|
||||
private ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
private final static Map<String, RedisRpcClassHandler> protocolHash = new HashMap<>();
|
||||
|
||||
public void addHandler(String path, RedisRpcClassHandler handler) {
|
||||
protocolHash.put(path, handler);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void run(String... args) throws Exception {
|
||||
// List<Class<?>> classList = ClassUtil.getClassList("com.genersoft.iot.vmp.service.redisMsg.control", RedisRpcController.class);
|
||||
// for (Class<?> handlerClass : classList) {
|
||||
// String controllerPath = handlerClass.getAnnotation(RedisRpcController.class).value();
|
||||
// Object bean = ClassUtil.getBean(controllerPath, handlerClass);
|
||||
// // 扫描其下的方法
|
||||
// Method[] methods = handlerClass.getDeclaredMethods();
|
||||
// for (Method method : methods) {
|
||||
// RedisRpcMapping annotation = method.getAnnotation(RedisRpcMapping.class);
|
||||
// if (annotation != null) {
|
||||
// String methodPath = annotation.value();
|
||||
// if (methodPath != null) {
|
||||
// protocolHash.put(controllerPath + "/" + methodPath, new RedisRpcClassHandler(bean, method));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// for (String s : protocolHash.keySet()) {
|
||||
// System.out.println(s);
|
||||
// }
|
||||
// if (log.isDebugEnabled()) {
|
||||
// log.debug("消息ID缓存表 protocolHash:{}", protocolHash);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onMessage(Message message, byte[] pattern) {
|
||||
boolean isEmpty = taskQueue.isEmpty();
|
||||
@ -63,10 +98,10 @@ public class RedisRpcConfig implements MessageListener {
|
||||
} else if (redisRpcMessage.getResponse() != null){
|
||||
handlerResponse(redisRpcMessage.getResponse());
|
||||
} else {
|
||||
log.error("[redis rpc 解析失败] {}", JSON.toJSONString(redisRpcMessage));
|
||||
log.error("[redis-rpc]解析失败 {}", JSON.toJSONString(redisRpcMessage));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[redis rpc 解析异常] ", e);
|
||||
log.error("[redis-rpc]解析异常 {}",new String(msg.getBody()), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -87,17 +122,23 @@ public class RedisRpcConfig implements MessageListener {
|
||||
return;
|
||||
}
|
||||
log.info("[redis-rpc] << {}", request);
|
||||
Method method = getMethod(request.getUri());
|
||||
RedisRpcClassHandler redisRpcClassHandler = protocolHash.get(request.getUri());
|
||||
if (redisRpcClassHandler == null) {
|
||||
log.error("[redis-rpc] 路径: {}不存在", request.getUri());
|
||||
return;
|
||||
}
|
||||
RpcController controller = redisRpcClassHandler.getController();
|
||||
Method method = redisRpcClassHandler.getMethod();
|
||||
// 没有携带目标ID的可以理解为哪个wvp有结果就哪个回复,携带目标ID,但是如果是不存在的uri则直接回复404
|
||||
if (userSetting.getServerId().equals(request.getToId())) {
|
||||
if (method == null) {
|
||||
// 回复404结果
|
||||
RedisRpcResponse response = request.getResponse();
|
||||
response.setStatusCode(404);
|
||||
response.setStatusCode(ErrorCode.ERROR404.getCode());
|
||||
sendResponse(response);
|
||||
return;
|
||||
}
|
||||
RedisRpcResponse response = (RedisRpcResponse)method.invoke(redisRpcController, request);
|
||||
RedisRpcResponse response = (RedisRpcResponse)method.invoke(controller, request);
|
||||
if(response != null) {
|
||||
sendResponse(response);
|
||||
}
|
||||
@ -105,26 +146,14 @@ public class RedisRpcConfig implements MessageListener {
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
RedisRpcResponse response = (RedisRpcResponse)method.invoke(redisRpcController, request);
|
||||
RedisRpcResponse response = (RedisRpcResponse)method.invoke(controller, request);
|
||||
if (response != null) {
|
||||
sendResponse(response);
|
||||
}
|
||||
}
|
||||
}catch (InvocationTargetException | IllegalAccessException e) {
|
||||
log.error("[redis rpc ] 处理请求失败 ", e);
|
||||
log.error("[redis-rpc ] 处理请求失败 ", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Method getMethod(String name) {
|
||||
// 启动后扫描所有的路径注解
|
||||
Method[] methods = redisRpcController.getClass().getMethods();
|
||||
for (Method method : methods) {
|
||||
if (method.getName().equals(name)) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void sendResponse(RedisRpcResponse response){
|
||||
@ -142,23 +171,28 @@ public class RedisRpcConfig implements MessageListener {
|
||||
redisTemplate.convertAndSend(REDIS_REQUEST_CHANNEL_KEY, message);
|
||||
}
|
||||
|
||||
|
||||
private final Map<Long, SynchronousQueue<RedisRpcResponse>> topicSubscribers = new ConcurrentHashMap<>();
|
||||
private final Map<Long, CommonCallback<RedisRpcResponse>> callbacks = new ConcurrentHashMap<>();
|
||||
|
||||
public RedisRpcResponse request(RedisRpcRequest request, int timeOut) {
|
||||
public RedisRpcResponse request(RedisRpcRequest request, long timeOut) {
|
||||
return request(request, timeOut, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public RedisRpcResponse request(RedisRpcRequest request, long timeOut, TimeUnit timeUnit) {
|
||||
request.setSn((long) random.nextInt(1000) + 1);
|
||||
SynchronousQueue<RedisRpcResponse> subscribe = subscribe(request.getSn());
|
||||
|
||||
try {
|
||||
sendRequest(request);
|
||||
return subscribe.poll(timeOut, TimeUnit.SECONDS);
|
||||
return subscribe.poll(timeOut, timeUnit);
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("[redis rpc timeout] uri: {}, sn: {}", request.getUri(), request.getSn(), e);
|
||||
RedisRpcResponse redisRpcResponse = new RedisRpcResponse();
|
||||
redisRpcResponse.setStatusCode(ErrorCode.ERROR486.getCode());
|
||||
return redisRpcResponse;
|
||||
} finally {
|
||||
this.unsubscribe(request.getSn());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void request(RedisRpcRequest request, CommonCallback<RedisRpcResponse> callback) {
|
||||
@ -209,6 +243,9 @@ public class RedisRpcConfig implements MessageListener {
|
||||
return callbacks.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// @Scheduled(fixedRate = 1000) //每1秒执行一次
|
||||
// public void execute(){
|
||||
// logger.info("callbacks的长度: " + callbacks.size());
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.genersoft.iot.vmp.conf.redis.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.service.redisMsg.dto.RpcController;
|
||||
import lombok.Data;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@Data
|
||||
public class RedisRpcClassHandler {
|
||||
|
||||
private RpcController controller;
|
||||
private Method method;
|
||||
|
||||
public RedisRpcClassHandler(RpcController controller, Method method) {
|
||||
this.controller = controller;
|
||||
this.method = method;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.conf.security;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.security.dto.JwtUser;
|
||||
import com.genersoft.iot.vmp.service.IUserApiKeyService;
|
||||
import com.genersoft.iot.vmp.service.IUserService;
|
||||
@ -20,12 +21,16 @@ import org.jose4j.jwt.consumer.JwtConsumer;
|
||||
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
|
||||
import org.jose4j.lang.JoseException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
@ -53,6 +58,8 @@ public class JwtUtils implements InitializingBean {
|
||||
private static IUserService userService;
|
||||
|
||||
private static IUserApiKeyService userApiKeyService;
|
||||
|
||||
private static UserSetting userSetting;
|
||||
|
||||
public static String getApiKeyHeader() {
|
||||
return API_KEY_HEADER;
|
||||
@ -68,6 +75,11 @@ public class JwtUtils implements InitializingBean {
|
||||
JwtUtils.userApiKeyService = userApiKeyService;
|
||||
}
|
||||
|
||||
@Resource
|
||||
public void setUserSetting(UserSetting userSetting) {
|
||||
JwtUtils.userSetting = userSetting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
try {
|
||||
@ -84,8 +96,46 @@ public class JwtUtils implements InitializingBean {
|
||||
*/
|
||||
private RsaJsonWebKey generateRsaJsonWebKey() throws JoseException {
|
||||
RsaJsonWebKey rsaJsonWebKey = null;
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("/jwk.json"), StandardCharsets.UTF_8))) {
|
||||
String jwkJson = reader.readLine();
|
||||
try {
|
||||
String jwkFile = userSetting.getJwkFile();
|
||||
InputStream inputStream = null;
|
||||
if (jwkFile.startsWith("classpath:")){
|
||||
String filePath = jwkFile.substring("classpath:".length());
|
||||
ClassPathResource civilCodeFile = new ClassPathResource(filePath);
|
||||
if (civilCodeFile.exists()) {
|
||||
inputStream = civilCodeFile.getInputStream();
|
||||
}
|
||||
}else {
|
||||
File civilCodeFile = new File(userSetting.getCivilCodeFile());
|
||||
if (civilCodeFile.exists()) {
|
||||
inputStream = Files.newInputStream(civilCodeFile.toPath());
|
||||
}
|
||||
|
||||
}
|
||||
if (inputStream == null ) {
|
||||
log.warn("[API AUTH] 读取jwk.json失败,文件不存在,将使用新生成的随机RSA密钥对");
|
||||
// 生成一个RSA密钥对,该密钥对将用于JWT的签名和验证,包装在JWK中
|
||||
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
||||
// 给JWK一个密钥ID
|
||||
rsaJsonWebKey.setKeyId(keyId);
|
||||
return rsaJsonWebKey;
|
||||
}
|
||||
BufferedReader inputStreamReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
int index = -1;
|
||||
String line;
|
||||
StringBuilder content = new StringBuilder();
|
||||
while ((line = inputStreamReader.readLine()) != null) {
|
||||
content.append(line);
|
||||
index ++;
|
||||
if (index == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
inputStreamReader.close();
|
||||
inputStream.close();
|
||||
|
||||
|
||||
String jwkJson = content.toString();
|
||||
JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwkJson);
|
||||
List<JsonWebKey> jsonWebKeys = jsonWebKeySet.getJsonWebKeys();
|
||||
if (!jsonWebKeys.isEmpty()) {
|
||||
@ -94,14 +144,15 @@ public class JwtUtils implements InitializingBean {
|
||||
rsaJsonWebKey = (RsaJsonWebKey) jsonWebKey;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignored
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
if (rsaJsonWebKey == null) {
|
||||
log.warn("[API AUTH] 读取jwk.json失败,获取内容失败,将使用新生成的随机RSA密钥对");
|
||||
// 生成一个RSA密钥对,该密钥对将用于JWT的签名和验证,包装在JWK中
|
||||
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
||||
// 给JWK一个密钥ID
|
||||
rsaJsonWebKey.setKeyId(keyId);
|
||||
}else {
|
||||
log.info("[API AUTH] 读取jwk.json成功");
|
||||
}
|
||||
return rsaJsonWebKey;
|
||||
}
|
||||
@ -153,7 +204,7 @@ public class JwtUtils implements InitializingBean {
|
||||
}
|
||||
|
||||
public static String createToken(String username) {
|
||||
return createToken(username, EXPIRATION_TIME);
|
||||
return createToken(username, userSetting.getLoginTimeout());
|
||||
}
|
||||
|
||||
public static String getHeader() {
|
||||
|
||||
@ -148,8 +148,10 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
corsConfiguration.setAllowedOrigins(userSetting.getAllowedOrigins());
|
||||
}else {
|
||||
corsConfiguration.setAllowCredentials(false);
|
||||
corsConfiguration.setAllowedOrigins(Collections.singletonList(CorsConfiguration.ALL));
|
||||
// 在SpringBoot 2.4及以上版本处理跨域时,遇到错误提示:当allowCredentials为true时,allowedOrigins不能包含特殊值"*"。
|
||||
// 解决方法是明确指定allowedOrigins或使用allowedOriginPatterns。
|
||||
corsConfiguration.setAllowCredentials(true);
|
||||
corsConfiguration.addAllowedOriginPattern(CorsConfiguration.ALL); // 默认全部允许所有跨域
|
||||
}
|
||||
|
||||
corsConfiguration.setExposedHeaders(Arrays.asList(JwtUtils.getHeader()));
|
||||
|
||||
@ -80,11 +80,12 @@ public class SipLayer implements CommandLineRunner {
|
||||
monitorIps.add(sipConfig.getIp());
|
||||
}
|
||||
}
|
||||
sipConfig.setMonitorIps(monitorIps);
|
||||
if (ObjectUtils.isEmpty(sipConfig.getShowIp())){
|
||||
sipConfig.setShowIp(String.join(",", monitorIps));
|
||||
}
|
||||
SipFactory.getInstance().setPathName("gov.nist");
|
||||
if (monitorIps.size() > 0) {
|
||||
if (!monitorIps.isEmpty()) {
|
||||
for (String monitorIp : monitorIps) {
|
||||
addListeningPoint(monitorIp, sipConfig.getPort());
|
||||
}
|
||||
|
||||
@ -156,8 +156,17 @@ public class DigestServerAuthenticationHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate the inbound request given plain text password.
|
||||
* 鉴权
|
||||
*
|
||||
* A1 = username + ":" + realm + ":" + password
|
||||
* A2 = REGISTER:URI
|
||||
*
|
||||
* HA1 = md5(A1)
|
||||
* HA2 = md5(A2)
|
||||
*
|
||||
* KD = HA2:HA2:qop
|
||||
*
|
||||
* response = md5(KD)
|
||||
* @param request - the request to authenticate.
|
||||
* @param pass -- the plain text password.
|
||||
*
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 基础配置
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "基础配置")
|
||||
public class BasicParam {
|
||||
|
||||
@Schema(description = "设备ID")
|
||||
private String deviceId;
|
||||
|
||||
@Schema(description = "通道ID,如果时对设备配置直接设置同设备ID一样即可")
|
||||
private String channelId;
|
||||
|
||||
@Schema(description = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "注册过期时间")
|
||||
private String expiration;
|
||||
|
||||
@Schema(description = "心跳间隔时间")
|
||||
private Integer heartBeatInterval;
|
||||
|
||||
@Schema(description = "心跳超时次数")
|
||||
private Integer heartBeatCount;
|
||||
|
||||
@Schema(description = "定位功能支持情况。取值:0-不支持;1-支持 GPS定位;2-支持北斗定位(可选,默认取值为0)," +
|
||||
"用于接受配置查询结果, 基础配置时无效")
|
||||
private Integer positionCapability;
|
||||
|
||||
@Schema(description = "经度(可选),用于接受配置查询结果, 基础配置时无效")
|
||||
private Double longitude;
|
||||
|
||||
@Schema(description = "纬度(可选),用于接受配置查询结果, 基础配置时无效")
|
||||
private Double latitude;
|
||||
|
||||
public static BasicParam getInstance(String name, String expiration, Integer heartBeatInterval, Integer heartBeatCount) {
|
||||
BasicParam basicParam = new BasicParam();
|
||||
basicParam.setName(name);
|
||||
basicParam.setExpiration(expiration);
|
||||
basicParam.setHeartBeatInterval(heartBeatInterval);
|
||||
basicParam.setHeartBeatCount(heartBeatCount);
|
||||
return basicParam;
|
||||
}
|
||||
}
|
||||
@ -123,17 +123,14 @@ public class CommonGBChannel {
|
||||
@Schema(description = "国标-时域编码能力,取值0-不支持;1-1级增强;2-2级增强;3-3级增强(可选)")
|
||||
private Integer gbSvcTimeSupportMode;
|
||||
|
||||
@Schema(description = "关联的国标设备数据库ID")
|
||||
private Integer gbDeviceDbId;
|
||||
|
||||
@Schema(description = "二进制保存的录制计划, 每一位表示每个小时的前半个小时")
|
||||
private Long recordPLan;
|
||||
|
||||
@Schema(description = "关联的推流Id(流来源是推流时有效)")
|
||||
private Integer streamPushId;
|
||||
@Schema(description = "关联的数据类型")
|
||||
private Integer dataType;
|
||||
|
||||
@Schema(description = "关联的拉流代理Id(流来源是拉流代理时有效)")
|
||||
private Integer streamProxyId;
|
||||
@Schema(description = "关联的设备ID")
|
||||
private Integer dataDeviceId;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
@ -104,7 +104,21 @@ public class Device {
|
||||
* 心跳间隔
|
||||
*/
|
||||
@Schema(description = "心跳间隔")
|
||||
private int keepaliveIntervalTime;
|
||||
private Integer heartBeatInterval;
|
||||
|
||||
|
||||
/**
|
||||
* 心跳超时次数
|
||||
*/
|
||||
@Schema(description = "心跳超时次数")
|
||||
private Integer heartBeatCount;
|
||||
|
||||
|
||||
/**
|
||||
* 定位功能支持情况
|
||||
*/
|
||||
@Schema(description = "定位功能支持情况。取值:0-不支持;1-支持 GPS定位;2-支持北斗定位(可选,默认取值为0")
|
||||
private Integer positionCapability;
|
||||
|
||||
/**
|
||||
* 通道个数
|
||||
@ -195,4 +209,7 @@ public class Device {
|
||||
|
||||
@Schema(description = "控制语音对讲流程,释放收到ACK后发流")
|
||||
private boolean broadcastPushAfterAck;
|
||||
|
||||
@Schema(description = "所属服务Id")
|
||||
private String serverId;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.MessageElementForCatalog;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@ -20,9 +21,6 @@ public class DeviceChannel extends CommonGBChannel {
|
||||
@Schema(description = "数据库自增ID")
|
||||
private int id;
|
||||
|
||||
@Schema(description = "设备的数据库自增ID")
|
||||
private Integer deviceDbId;
|
||||
|
||||
@MessageElementForCatalog("DeviceID")
|
||||
@Schema(description = "编码")
|
||||
private String deviceId;
|
||||
@ -191,6 +189,8 @@ public class DeviceChannel extends CommonGBChannel {
|
||||
@Schema(description = "通道类型, 默认0, 0: 普通通道,1 行政区划 2 业务分组/虚拟组织")
|
||||
private int channelType;
|
||||
|
||||
private Integer dataType = ChannelDataType.GB28181.value;
|
||||
|
||||
public void setPtzType(int ptzType) {
|
||||
this.ptzType = ptzType;
|
||||
switch (ptzType) {
|
||||
@ -244,5 +244,15 @@ public class DeviceChannel extends CommonGBChannel {
|
||||
return deviceChannel;
|
||||
}
|
||||
|
||||
public CommonGBChannel buildCommonGBChannelForStatus() {
|
||||
CommonGBChannel commonGBChannel = new CommonGBChannel();
|
||||
commonGBChannel.setGbId(id);
|
||||
commonGBChannel.setGbDeviceId(deviceId);
|
||||
commonGBChannel.setGbName(name);
|
||||
commonGBChannel.setDataType(ChannelDataType.GB28181.value);
|
||||
commonGBChannel.setDataDeviceId(getDataDeviceId());
|
||||
return commonGBChannel;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "拉框放大/缩小控制参数")
|
||||
public class DragZoomParam {
|
||||
|
||||
@MessageElement("Length")
|
||||
@Schema(description = "播放窗口长度像素值(必选)")
|
||||
protected Integer length;
|
||||
|
||||
@MessageElement("Width")
|
||||
@Schema(description = "播放窗口宽度像素值(必选)")
|
||||
protected Integer width;
|
||||
|
||||
@MessageElement("MidPointX")
|
||||
@Schema(description = "拉框中心的横轴坐标像素值(必选)")
|
||||
protected Integer midPointX;
|
||||
|
||||
@MessageElement("MidPointY")
|
||||
@Schema(description = "拉框中心的纵轴坐标像素值(必选)")
|
||||
protected Integer midPointY;
|
||||
|
||||
@MessageElement("LengthX")
|
||||
@Schema(description = "拉框长度像素值(必选)")
|
||||
protected Integer lengthX;
|
||||
|
||||
@MessageElement("LengthY")
|
||||
@Schema(description = "拉框宽度像素值(必选)")
|
||||
protected Integer lengthY;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 设备信息查询响应
|
||||
@ -9,6 +10,7 @@ import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
|
||||
* @version 1.0
|
||||
* @date 2022/6/28 14:55
|
||||
*/
|
||||
@Data
|
||||
public class DragZoomRequest {
|
||||
/**
|
||||
* 序列号
|
||||
@ -20,124 +22,9 @@ public class DragZoomRequest {
|
||||
private String deviceId;
|
||||
|
||||
@MessageElement(value = "DragZoomIn")
|
||||
private DragZoom dragZoomIn;
|
||||
private DragZoomParam dragZoomIn;
|
||||
|
||||
@MessageElement(value = "DragZoomOut")
|
||||
private DragZoom dragZoomOut;
|
||||
private DragZoomParam dragZoomOut;
|
||||
|
||||
/**
|
||||
* 基本参数
|
||||
*/
|
||||
public static class DragZoom {
|
||||
/**
|
||||
* 播放窗口长度像素值
|
||||
*/
|
||||
@MessageElement("Length")
|
||||
protected Integer length;
|
||||
/**
|
||||
* 播放窗口宽度像素值
|
||||
*/
|
||||
@MessageElement("Width")
|
||||
protected Integer width;
|
||||
/**
|
||||
* 拉框中心的横轴坐标像素值
|
||||
*/
|
||||
@MessageElement("MidPointX")
|
||||
protected Integer midPointX;
|
||||
/**
|
||||
* 拉框中心的纵轴坐标像素值
|
||||
*/
|
||||
@MessageElement("MidPointY")
|
||||
protected Integer midPointY;
|
||||
/**
|
||||
* 拉框长度像素值
|
||||
*/
|
||||
@MessageElement("LengthX")
|
||||
protected Integer lengthX;
|
||||
/**
|
||||
* 拉框宽度像素值
|
||||
*/
|
||||
@MessageElement("LengthY")
|
||||
protected Integer lengthY;
|
||||
|
||||
public Integer getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Integer length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Integer getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Integer getMidPointX() {
|
||||
return midPointX;
|
||||
}
|
||||
|
||||
public void setMidPointX(Integer midPointX) {
|
||||
this.midPointX = midPointX;
|
||||
}
|
||||
|
||||
public Integer getMidPointY() {
|
||||
return midPointY;
|
||||
}
|
||||
|
||||
public void setMidPointY(Integer midPointY) {
|
||||
this.midPointY = midPointY;
|
||||
}
|
||||
|
||||
public Integer getLengthX() {
|
||||
return lengthX;
|
||||
}
|
||||
|
||||
public void setLengthX(Integer lengthX) {
|
||||
this.lengthX = lengthX;
|
||||
}
|
||||
|
||||
public Integer getLengthY() {
|
||||
return lengthY;
|
||||
}
|
||||
|
||||
public void setLengthY(Integer lengthY) {
|
||||
this.lengthY = lengthY;
|
||||
}
|
||||
}
|
||||
|
||||
public String getSn() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public void setSn(String sn) {
|
||||
this.sn = sn;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public DragZoom getDragZoomIn() {
|
||||
return dragZoomIn;
|
||||
}
|
||||
|
||||
public void setDragZoomIn(DragZoom dragZoomIn) {
|
||||
this.dragZoomIn = dragZoomIn;
|
||||
}
|
||||
|
||||
public DragZoom getDragZoomOut() {
|
||||
return dragZoomOut;
|
||||
}
|
||||
|
||||
public void setDragZoomOut(DragZoom dragZoomOut) {
|
||||
this.dragZoomOut = dragZoomOut;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,184 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 解析收到的前端控制指令
|
||||
*/
|
||||
@Data
|
||||
public class FrontEndCode {
|
||||
|
||||
|
||||
public static String encode(IFrontEndControlCode frontEndControlCode){
|
||||
return frontEndControlCode.encode();
|
||||
}
|
||||
|
||||
public static IFrontEndControlCode decode(@NotNull String cmdStr) {
|
||||
if (cmdStr.length() != 16) {
|
||||
return null;
|
||||
}
|
||||
String cmdCodeStr = cmdStr.substring(6, 8);
|
||||
int cmdCode = Integer.parseInt(cmdCodeStr, 16);
|
||||
if (cmdCode < 39) {
|
||||
// PTZ指令
|
||||
FrontEndControlCodeForPTZ codeForPTZ = new FrontEndControlCodeForPTZ();
|
||||
int zoomOut = cmdCode >> 5 & 1;
|
||||
if (zoomOut == 1) {
|
||||
codeForPTZ.setZoom(0);
|
||||
}
|
||||
int zoomIn = cmdCode >> 4 & 1;
|
||||
if (zoomIn == 1) {
|
||||
codeForPTZ.setZoom(1);
|
||||
}
|
||||
int tiltUp = cmdCode >> 3 & 1;
|
||||
if (tiltUp == 1) {
|
||||
codeForPTZ.setTilt(0);
|
||||
}
|
||||
int tiltDown = cmdCode >> 2 & 1;
|
||||
if (tiltDown == 1) {
|
||||
codeForPTZ.setTilt(1);
|
||||
}
|
||||
int panLeft = cmdCode >> 1 & 1;
|
||||
if (panLeft == 1) {
|
||||
codeForPTZ.setPan(0);
|
||||
}
|
||||
int panRight = cmdCode & 1;
|
||||
if (panRight == 1) {
|
||||
codeForPTZ.setPan(1);
|
||||
}
|
||||
String param1Str = cmdStr.substring(8, 10);
|
||||
codeForPTZ.setPanSpeed(Integer.parseInt(param1Str, 16));
|
||||
String param2Str = cmdStr.substring(10, 12);
|
||||
codeForPTZ.setTiltSpeed(Integer.parseInt(param2Str, 16));
|
||||
String param3Str = cmdStr.substring(12, 13);
|
||||
codeForPTZ.setZoomSpeed(Integer.parseInt(param3Str, 16));
|
||||
return codeForPTZ;
|
||||
}else if (cmdCode < 74) {
|
||||
// FI指令
|
||||
FrontEndControlCodeForFI codeForFI = new FrontEndControlCodeForFI();
|
||||
int irisOut = cmdCode >> 3 & 1;
|
||||
if (irisOut == 1) {
|
||||
codeForFI.setIris(0);
|
||||
}
|
||||
int irisIn = cmdCode >> 2 & 1;
|
||||
if (irisIn == 1) {
|
||||
codeForFI.setIris(1);
|
||||
}
|
||||
int focusNear = cmdCode >> 1 & 1;
|
||||
if (focusNear == 1) {
|
||||
codeForFI.setFocus(0);
|
||||
}
|
||||
int focusFar = cmdCode & 1;
|
||||
if (focusFar == 1) {
|
||||
codeForFI.setFocus(1);
|
||||
}
|
||||
|
||||
String param1Str = cmdStr.substring(8, 10);
|
||||
codeForFI.setFocusSpeed(Integer.parseInt(param1Str, 16));
|
||||
String param2Str = cmdStr.substring(10, 12);
|
||||
codeForFI.setIrisSpeed(Integer.parseInt(param2Str, 16));
|
||||
return codeForFI;
|
||||
}else if (cmdCode < 131) {
|
||||
// 预置位指令
|
||||
FrontEndControlCodeForPreset codeForPreset = new FrontEndControlCodeForPreset();
|
||||
switch (cmdCode) {
|
||||
case 0x81: // 设置预置位
|
||||
codeForPreset.setCode(1);
|
||||
break;
|
||||
case 0x82: // 调用预置位
|
||||
codeForPreset.setCode(2);
|
||||
break;
|
||||
case 0x83: // 删除预置位
|
||||
codeForPreset.setCode(3);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
// 预置位编号
|
||||
String param2Str = cmdStr.substring(10, 12);
|
||||
codeForPreset.setPresetId(Integer.parseInt(param2Str, 16));
|
||||
return codeForPreset;
|
||||
}else if (cmdCode < 136) {
|
||||
// 巡航指令
|
||||
FrontEndControlCodeForTour codeForTour = new FrontEndControlCodeForTour();
|
||||
String param3Str = cmdStr.substring(12, 13);
|
||||
switch (cmdCode) {
|
||||
case 0x84: // 加入巡航点
|
||||
codeForTour.setCode(1);
|
||||
break;
|
||||
case 0x85: // 删除一个巡航点
|
||||
codeForTour.setCode(2);
|
||||
break;
|
||||
case 0x86: // 设置巡航速度
|
||||
codeForTour.setCode(3);
|
||||
codeForTour.setTourSpeed(Integer.parseInt(param3Str, 16));
|
||||
break;
|
||||
case 0x87: // 设置巡航停留时间
|
||||
codeForTour.setCode(4);
|
||||
codeForTour.setTourTime(Integer.parseInt(param3Str, 16));
|
||||
break;
|
||||
case 0x88: // 开始巡航
|
||||
codeForTour.setCode(5);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
String param1Str = cmdStr.substring(8, 10);
|
||||
codeForTour.setTourId(Integer.parseInt(param1Str, 16));
|
||||
String param2Str = cmdStr.substring(10, 12);
|
||||
codeForTour.setPresetId(Integer.parseInt(param2Str, 16));
|
||||
return codeForTour;
|
||||
}else if (cmdCode < 138) {
|
||||
// 扫描指令
|
||||
FrontEndControlCodeForScan controlCodeForScan = new FrontEndControlCodeForScan();
|
||||
String param2Str = cmdStr.substring(10, 11);
|
||||
int param2Code = Integer.parseInt(param2Str, 16);
|
||||
switch (cmdCode) {
|
||||
case 0x89:
|
||||
switch (param2Code) {
|
||||
case 0x00: // 开始自动扫描
|
||||
controlCodeForScan.setCode(1);
|
||||
break;
|
||||
case 0x01: // 设置自动扫描左边界
|
||||
controlCodeForScan.setCode(2);
|
||||
break;
|
||||
case 0x02: // 设置自动扫描右边界
|
||||
controlCodeForScan.setCode(3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x8A: // 删除一个巡航点
|
||||
controlCodeForScan.setCode(4);
|
||||
String param3Str = cmdStr.substring(12, 13);
|
||||
controlCodeForScan.setScanSpeed(Integer.parseInt(param3Str, 16));
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
String param1Str = cmdStr.substring(8, 10);
|
||||
controlCodeForScan.setScanId(Integer.parseInt(param1Str, 16));
|
||||
return controlCodeForScan;
|
||||
}else if (cmdCode < 141) {
|
||||
// 辅助开关
|
||||
FrontEndControlCodeForAuxiliary codeForAuxiliary = new FrontEndControlCodeForAuxiliary();
|
||||
switch (cmdCode) {
|
||||
case 0x8C: // 开
|
||||
codeForAuxiliary.setCode(1);
|
||||
break;
|
||||
case 0x8D: // 关
|
||||
codeForAuxiliary.setCode(2);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
// 预置位编号
|
||||
String param2Str = cmdStr.substring(10, 12);
|
||||
codeForAuxiliary.setAuxiliaryId(Integer.parseInt(param2Str, 16));
|
||||
return codeForAuxiliary;
|
||||
}else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class FrontEndControlCodeForAuxiliary implements IFrontEndControlCode {
|
||||
|
||||
private final FrontEndControlType type = FrontEndControlType.AUXILIARY;
|
||||
|
||||
@Override
|
||||
public FrontEndControlType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助开关控制指令: 1为开, 2为关, 3为设置自动扫描右边界, 4为设置自动扫描速度
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 辅助开关编号
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer auxiliaryId;
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class FrontEndControlCodeForFI implements IFrontEndControlCode {
|
||||
|
||||
private final FrontEndControlType type = FrontEndControlType.FI;
|
||||
|
||||
@Override
|
||||
public FrontEndControlType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 光圈,0为缩小 1为放大
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer iris;
|
||||
|
||||
/**
|
||||
* 聚焦 0 近, 1远
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer focus;
|
||||
|
||||
/**
|
||||
* 聚焦速度
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer focusSpeed;
|
||||
|
||||
/**
|
||||
* 光圈速度
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer irisSpeed;
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class FrontEndControlCodeForPTZ implements IFrontEndControlCode {
|
||||
|
||||
private final FrontEndControlType type = FrontEndControlType.PTZ;
|
||||
|
||||
@Override
|
||||
public FrontEndControlType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 镜头变倍,0为缩小 1为放大
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer zoom;
|
||||
|
||||
/**
|
||||
* 云台垂直方向控制 0 为上, 1为下
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer tilt;
|
||||
|
||||
/**
|
||||
* 云台水平方向控制 0 为左, 1为右
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer pan;
|
||||
|
||||
/**
|
||||
* 水平控制速度相对值
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer panSpeed;
|
||||
|
||||
/**
|
||||
* 垂直控制速度相对值
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer tiltSpeed;
|
||||
|
||||
/**
|
||||
* 变倍控制速度相对值
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer zoomSpeed;
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class FrontEndControlCodeForPreset implements IFrontEndControlCode {
|
||||
|
||||
private final FrontEndControlType type = FrontEndControlType.PRESET;
|
||||
|
||||
@Override
|
||||
public FrontEndControlType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预置位指令: 1为设置预置位, 2为调用预置位, 3为删除预置位
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 预置位编号
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer presetId;
|
||||
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class FrontEndControlCodeForScan implements IFrontEndControlCode {
|
||||
|
||||
private final FrontEndControlType type = FrontEndControlType.SCAN;
|
||||
|
||||
@Override
|
||||
public FrontEndControlType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预置位指令: 1为开始自动扫描, 2为设置自动扫描左边界, 3为设置自动扫描右边界, 4为设置自动扫描速度
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 自动扫描速度
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer scanSpeed;
|
||||
|
||||
/**
|
||||
* 扫描组号
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer scanId;
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class FrontEndControlCodeForTour implements IFrontEndControlCode {
|
||||
|
||||
private final FrontEndControlType type = FrontEndControlType.TOUR;
|
||||
|
||||
@Override
|
||||
public FrontEndControlType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 巡航指令: 1为加入巡航点, 2为删除一个巡航点, 3为设置巡航速度, 4为设置巡航停留时间, 5为开始巡航
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer code;
|
||||
|
||||
/**
|
||||
* 巡航点
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer tourId;
|
||||
|
||||
/**
|
||||
* 巡航停留时间
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer tourTime;
|
||||
|
||||
/**
|
||||
* 巡航速度
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer tourSpeed;
|
||||
|
||||
/**
|
||||
* 预置位编号
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private Integer presetId;
|
||||
|
||||
@Override
|
||||
public String encode() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
public enum FrontEndControlType {
|
||||
|
||||
PTZ,FI,PRESET,TOUR,SCAN,AUXILIARY
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
public interface IFrontEndControlCode {
|
||||
|
||||
FrontEndControlType getType();
|
||||
String encode();
|
||||
}
|
||||
@ -4,7 +4,7 @@ import lombok.Data;
|
||||
|
||||
// 从INVITE消息中解析需要的信息
|
||||
@Data
|
||||
public class InviteInfo {
|
||||
public class InviteMessageInfo {
|
||||
private String requesterId;
|
||||
private String targetChannelId;
|
||||
private String sourceChannelId;
|
||||
@ -127,4 +127,7 @@ public class Platform {
|
||||
|
||||
@Schema(description = "保密属性(必选)缺省为0;0-不涉密,1-涉密")
|
||||
private int secrecy = 0;
|
||||
|
||||
@Schema(description = "执行注册的服务ID")
|
||||
private String serverId;
|
||||
}
|
||||
|
||||
@ -27,6 +27,11 @@ public class SsrcTransaction {
|
||||
*/
|
||||
private String callId;
|
||||
|
||||
/**
|
||||
* 关联的流应用名
|
||||
*/
|
||||
private String app;
|
||||
|
||||
/**
|
||||
* 关联的流ID
|
||||
*/
|
||||
@ -52,12 +57,13 @@ public class SsrcTransaction {
|
||||
*/
|
||||
private InviteSessionType type;
|
||||
|
||||
public static SsrcTransaction buildForDevice(String deviceId, Integer channelId, String callId, String stream,
|
||||
public static SsrcTransaction buildForDevice(String deviceId, Integer channelId, String callId, String app, String stream,
|
||||
String ssrc, String mediaServerId, SIPResponse response, InviteSessionType type) {
|
||||
SsrcTransaction ssrcTransaction = new SsrcTransaction();
|
||||
ssrcTransaction.setDeviceId(deviceId);
|
||||
ssrcTransaction.setChannelId(channelId);
|
||||
ssrcTransaction.setCallId(callId);
|
||||
ssrcTransaction.setApp(app);
|
||||
ssrcTransaction.setStream(stream);
|
||||
ssrcTransaction.setMediaServerId(mediaServerId);
|
||||
ssrcTransaction.setSsrc(ssrc);
|
||||
@ -65,13 +71,14 @@ public class SsrcTransaction {
|
||||
ssrcTransaction.setType(type);
|
||||
return ssrcTransaction;
|
||||
}
|
||||
public static SsrcTransaction buildForPlatform(String platformId, Integer channelId, String callId, String stream,
|
||||
public static SsrcTransaction buildForPlatform(String platformId, Integer channelId, String callId, String app,String stream,
|
||||
String ssrc, String mediaServerId, SIPResponse response, InviteSessionType type) {
|
||||
SsrcTransaction ssrcTransaction = new SsrcTransaction();
|
||||
ssrcTransaction.setPlatformId(platformId);
|
||||
ssrcTransaction.setChannelId(channelId);
|
||||
ssrcTransaction.setCallId(callId);
|
||||
ssrcTransaction.setStream(stream);
|
||||
ssrcTransaction.setApp(app);
|
||||
ssrcTransaction.setMediaServerId(mediaServerId);
|
||||
ssrcTransaction.setSsrc(ssrc);
|
||||
ssrcTransaction.setSipTransactionInfo(new SipTransactionInfo(response));
|
||||
|
||||
@ -3,7 +3,10 @@ package com.genersoft.iot.vmp.gb28181.controller;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.IndustryCodeType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.NetworkIdentificationType;
|
||||
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToGroupByGbDeviceParam;
|
||||
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToGroupParam;
|
||||
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToRegionByGbDeviceParam;
|
||||
@ -29,7 +32,6 @@ import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.sip.message.Response;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
@ -139,6 +141,56 @@ public class CommonChannelController {
|
||||
return channelService.queryListByCivilCode(page, count, query, online, channelType, civilCode);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "存在行政区划但无法挂载的通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@Parameter(name = "query", description = "查询内容")
|
||||
@Parameter(name = "online", description = "是否在线")
|
||||
@Parameter(name = "channelType", description = "通道类型, 0:国标设备,1:推流设备,2:拉流代理")
|
||||
@GetMapping("/civilCode/unusual/list")
|
||||
public PageInfo<CommonGBChannel> queryListByCivilCodeForUnusual(int page, int count,
|
||||
@RequestParam(required = false) String query,
|
||||
@RequestParam(required = false) Boolean online,
|
||||
@RequestParam(required = false) Integer channelType){
|
||||
if (ObjectUtils.isEmpty(query)){
|
||||
query = null;
|
||||
}
|
||||
return channelService.queryListByCivilCodeForUnusual(page, count, query, online, channelType);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "存在父节点编号但无法挂载的通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@Parameter(name = "query", description = "查询内容")
|
||||
@Parameter(name = "online", description = "是否在线")
|
||||
@Parameter(name = "channelType", description = "通道类型, 0:国标设备,1:推流设备,2:拉流代理")
|
||||
@GetMapping("/parent/unusual/list")
|
||||
public PageInfo<CommonGBChannel> queryListByParentForUnusual(int page, int count,
|
||||
@RequestParam(required = false) String query,
|
||||
@RequestParam(required = false) Boolean online,
|
||||
@RequestParam(required = false) Integer channelType){
|
||||
if (ObjectUtils.isEmpty(query)){
|
||||
query = null;
|
||||
}
|
||||
return channelService.queryListByParentForUnusual(page, count, query, online, channelType);
|
||||
}
|
||||
|
||||
@Operation(summary = "清除存在行政区划但无法挂载的通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "param", description = "清理参数, all为true清理所有异常数据。 否则按照传入的设备Id清理", required = true)
|
||||
@PostMapping("/civilCode/unusual/clear")
|
||||
public void clearChannelCivilCode(@RequestBody ChannelToRegionParam param){
|
||||
channelService.clearChannelCivilCode(param.getAll(), param.getChannelIds());
|
||||
}
|
||||
|
||||
@Operation(summary = "清除存在分组节点但无法挂载的通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "param", description = "清理参数, all为true清理所有异常数据。 否则按照传入的设备Id清理", required = true)
|
||||
@PostMapping("/parent/unusual/clear")
|
||||
public void clearChannelParent(@RequestBody ChannelToRegionParam param){
|
||||
channelService.clearChannelParent(param.getAll(), param.getChannelIds());
|
||||
}
|
||||
|
||||
@Operation(summary = "获取关联业务分组通道列表", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@ -244,7 +296,7 @@ public class CommonChannelController {
|
||||
} catch (MalformedURLException e) {
|
||||
host=request.getLocalAddr();
|
||||
}
|
||||
streamInfo.channgeStreamIp(host);
|
||||
streamInfo.changeStreamIp(host);
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(streamInfo.getMediaServer().getTranscodeSuffix())
|
||||
&& !"null".equalsIgnoreCase(streamInfo.getMediaServer().getTranscodeSuffix())) {
|
||||
@ -261,7 +313,7 @@ public class CommonChannelController {
|
||||
result.setResult(WVPResult.fail(code, msg));
|
||||
}
|
||||
};
|
||||
channelPlayService.play(channel, null, callback);
|
||||
channelPlayService.play(channel, null, userSetting.getRecordSip(), callback);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,30 +7,22 @@
|
||||
|
||||
package com.genersoft.iot.vmp.gb28181.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.BasicParam;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
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.RequestMessage;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.text.ParseException;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@Tag(name = "国标设备配置")
|
||||
@RestController
|
||||
@ -40,117 +32,60 @@ public class DeviceConfig {
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private SIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
/**
|
||||
* 看守位控制命令API接口
|
||||
* @param deviceId 设备ID
|
||||
* @param channelId 通道ID
|
||||
* @param name 名称
|
||||
* @param expiration 到期时间
|
||||
* @param heartBeatInterval 心跳间隔
|
||||
* @param heartBeatCount 心跳计数
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/basicParam/{deviceId}")
|
||||
@GetMapping("/basicParam")
|
||||
@Operation(summary = "基本配置设置命令", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "name", description = "名称")
|
||||
@Parameter(name = "expiration", description = "到期时间")
|
||||
@Parameter(name = "heartBeatInterval", description = "心跳间隔")
|
||||
@Parameter(name = "heartBeatCount", description = "心跳计数")
|
||||
public DeferredResult<String> homePositionApi(@PathVariable String deviceId,
|
||||
String channelId,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String expiration,
|
||||
@RequestParam(required = false) String heartBeatInterval,
|
||||
@RequestParam(required = false) String heartBeatCount) {
|
||||
@Parameter(name = "basicParam", description = "基础配置参数", required = true)
|
||||
public DeferredResult<WVPResult<String>> homePositionApi(BasicParam basicParam) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("报警复位API调用");
|
||||
log.debug("基本配置设置命令API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONFIG + deviceId + channelId;
|
||||
try {
|
||||
cmder.deviceBasicConfigCmd(device, channelId, name, expiration, heartBeatInterval, heartBeatCount, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(String.format("设备配置操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 设备配置: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
DeferredResult<String> result = new DeferredResult<String>(3 * 1000L);
|
||||
result.onTimeout(() -> {
|
||||
log.warn(String.format("设备配置操作超时, 设备未返回应答指令"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("DeviceID", deviceId);
|
||||
json.put("Status", "Timeout");
|
||||
json.put("Description", "设备配置操作超时, 设备未返回应答指令");
|
||||
msg.setData(json); //("看守位控制操作超时, 设备未返回应答指令");
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(basicParam.getDeviceId(), "设备ID必须存在");
|
||||
|
||||
Device device = deviceService.getDeviceByDeviceId(basicParam.getDeviceId());
|
||||
Assert.notNull(device, "设备不存在");
|
||||
|
||||
DeferredResult<WVPResult<String>> deferredResult = new DeferredResult<>();
|
||||
deviceService.deviceBasicConfig(device, basicParam, (code, msg, data) -> {
|
||||
deferredResult.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
resultHolder.put(key, uuid, result);
|
||||
return result;
|
||||
|
||||
deferredResult.onTimeout(() -> {
|
||||
log.warn("[设备配置] 超时, {}", device.getDeviceId());
|
||||
deferredResult.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "超时"));
|
||||
});
|
||||
return deferredResult;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备配置查询请求API接口
|
||||
* @param deviceId 设备ID
|
||||
* @param configType 配置类型
|
||||
* @param channelId 通道ID
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "设备配置查询请求", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Operation(summary = "设备配置查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "configType", description = "配置类型")
|
||||
@GetMapping("/query/{deviceId}/{configType}")
|
||||
public DeferredResult<String> configDownloadApi(@PathVariable String deviceId,
|
||||
@PathVariable String configType,
|
||||
@RequestParam(required = false) String channelId) {
|
||||
@Parameter(name = "configType", description = "配置类型, 可选值," +
|
||||
"基本参数配置:BasicParam," +
|
||||
"视频参数范围:VideoParamOpt, " +
|
||||
"SVAC编码配置:SVACEncodeConfig, " +
|
||||
"SVAC解码配置:SVACDecodeConfig。" +
|
||||
"可同时查询多个配置类型,各类型以“/”分隔,")
|
||||
@GetMapping("/query")
|
||||
public DeferredResult<WVPResult<Object>> configDownloadApi(String deviceId,String configType,
|
||||
@RequestParam(required = false) String channelId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("设备状态查询API调用");
|
||||
log.debug("设备配置查询请求API调用");
|
||||
}
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_CONFIGDOWNLOAD + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
try {
|
||||
cmder.deviceConfigQuery(device, channelId, configType, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(String.format("获取设备配置失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备配置: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
DeferredResult<String> result = new DeferredResult<String > (3 * 1000L);
|
||||
result.onTimeout(()->{
|
||||
log.warn(String.format("获取设备配置超时"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData("Timeout. Device did not response to this command.");
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
|
||||
DeferredResult<WVPResult<Object>> deferredResult = new DeferredResult<>();
|
||||
|
||||
deviceService.deviceConfigQuery(device, channelId, configType, (code, msg, data) -> {
|
||||
deferredResult.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
resultHolder.put(key, uuid, result);
|
||||
return result;
|
||||
|
||||
deferredResult.onTimeout(() -> {
|
||||
log.warn("[获取设备配置] 超时, {}", device.getDeviceId());
|
||||
deferredResult.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "超时"));
|
||||
});
|
||||
return deferredResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,13 +7,8 @@
|
||||
|
||||
package com.genersoft.iot.vmp.gb28181.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
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.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
@ -23,16 +18,10 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.text.ParseException;
|
||||
import java.util.UUID;
|
||||
|
||||
@Tag(name = "国标设备控制")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@ -42,18 +31,8 @@ public class DeviceControl {
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private ISIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
/**
|
||||
* 远程启动控制命令API接口
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
@Operation(summary = "远程启动控制命令", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Operation(summary = "远程启动", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@GetMapping("/teleboot/{deviceId}")
|
||||
public void teleBootApi(@PathVariable String deviceId) {
|
||||
@ -61,194 +40,104 @@ public class DeviceControl {
|
||||
log.debug("设备远程启动API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
try {
|
||||
cmder.teleBootCmd(device);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 远程启动: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
Assert.notNull(device, "设备不存在");
|
||||
deviceService.teleboot(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 录像控制命令API接口
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param recordCmdStr Record:手动录像,StopRecord:停止手动录像
|
||||
* @param channelId 通道编码(可选)
|
||||
*/
|
||||
|
||||
@Operation(summary = "录像控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "recordCmdStr", description = "命令, 可选值:Record(手动录像),StopRecord(停止手动录像)", required = true)
|
||||
@GetMapping("/record/{deviceId}/{recordCmdStr}")
|
||||
public DeferredResult<ResponseEntity<WVPResult<String>>> recordApi(@PathVariable String deviceId,
|
||||
@PathVariable String recordCmdStr, String channelId) {
|
||||
@GetMapping("/record")
|
||||
public DeferredResult<WVPResult<String>> recordApi(String deviceId, String recordCmdStr, String channelId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("开始/停止录像API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
|
||||
DeferredResult<ResponseEntity<WVPResult<String>>> result = new DeferredResult<>(3 * 1000L);
|
||||
result.onTimeout(() -> {
|
||||
log.warn(String.format("开始/停止录像操作超时, 设备未返回应答指令"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setKey(key);
|
||||
msg.setId(uuid);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
resultHolder.invokeAllResult(msg);
|
||||
});
|
||||
if (resultHolder.exist(key, null)){
|
||||
return result;
|
||||
}
|
||||
resultHolder.put(key, uuid, result);
|
||||
try {
|
||||
cmder.recordCmd(device, channelId, recordCmdStr, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg)));
|
||||
resultHolder.invokeAllResult(msg);
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 开始/停止录像: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> deferredResult = new DeferredResult<>();
|
||||
|
||||
return result;
|
||||
deviceService.record(device, channelId, recordCmdStr, (code, msg, data) -> {
|
||||
deferredResult.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
deferredResult.onTimeout(() -> {
|
||||
log.warn("[开始/停止录像] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
deferredResult.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
return deferredResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 报警布防/撤防命令API接口
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param guardCmdStr SetGuard:布防,ResetGuard:撤防
|
||||
*/
|
||||
@Operation(summary = "布防/撤防命令", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Operation(summary = "布防/撤防", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "guardCmdStr", description = "命令, 可选值:SetGuard(布防),ResetGuard(撤防)", required = true)
|
||||
@GetMapping("/guard/{deviceId}/{guardCmdStr}")
|
||||
public DeferredResult<WVPResult<String>> guardApi(@PathVariable String deviceId, @PathVariable String guardCmdStr) {
|
||||
@GetMapping("/guard")
|
||||
public DeferredResult<WVPResult<String>> guardApi(String deviceId, String guardCmdStr) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("布防/撤防API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + deviceId;
|
||||
String uuid =UUID.randomUUID().toString();
|
||||
try {
|
||||
cmder.guardCmd(device, guardCmdStr, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg)));
|
||||
resultHolder.invokeResult(msg);
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>(3 * 1000L);
|
||||
resultHolder.put(key, uuid, result);
|
||||
result.onTimeout(() -> {
|
||||
log.warn(String.format("布防/撤防操作超时, 设备未返回应答指令"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setKey(key);
|
||||
msg.setId(uuid);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>();
|
||||
deviceService.guard(device, guardCmdStr, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[布防/撤防] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 报警复位API接口
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param alarmMethod 报警方式(可选)
|
||||
* @param alarmType 报警类型(可选)
|
||||
*/
|
||||
@Operation(summary = "报警复位", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "alarmMethod", description = "报警方式")
|
||||
@Parameter(name = "alarmType", description = "报警类型")
|
||||
@GetMapping("/reset_alarm/{deviceId}")
|
||||
public DeferredResult<ResponseEntity<WVPResult<String>>> resetAlarmApi(@PathVariable String deviceId, String channelId,
|
||||
@Parameter(name = "alarmMethod", description = "报警方式, 报警方式条件(可选),取值0为全部,1为电话报警,2为设备报警,3为短信报警,4为\n" +
|
||||
"GPS报警,5为视频报警,6为设备故障报警,7其他报警;可以为直接组合如12为电话报警或设备报警")
|
||||
@Parameter(name = "alarmType", description = "报警类型, " +
|
||||
"报警类型。" +
|
||||
"报警方式为2时,不携带 AlarmType为默认的报警设备报警," +
|
||||
"携带 AlarmType取值及对应报警类型如下:" +
|
||||
"1-视频丢失报警;2-设备防拆报警;3-存储设备磁盘满报警;4-设备高温报警;5-设备低温报警。" +
|
||||
"报警方式为5时,取值如下:" +
|
||||
"1-人工视频报警;2-运动目标检测报警;3-遗留物检测报警;4-物体移除检测报警;5-绊线检测报警;" +
|
||||
"6-入侵检测报警;7-逆行检测报警;8-徘徊检测报警;9-流量统计报警;10-密度检测报警;" +
|
||||
"11-视频异常检测报警;12-快速移动报警。" +
|
||||
"报警方式为6时,取值如下:" +
|
||||
"1-存储设备磁盘故障报警;2-存储设备风扇故障报警")
|
||||
@GetMapping("/reset_alarm")
|
||||
public DeferredResult<WVPResult<String>> resetAlarm(String deviceId, String channelId,
|
||||
@RequestParam(required = false) String alarmMethod,
|
||||
@RequestParam(required = false) String alarmType) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("报警复位API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + deviceId + channelId;
|
||||
try {
|
||||
cmder.alarmCmd(device, alarmMethod, alarmType, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("操作失败,错误码: %s, %s", event.statusCode, event.msg)));
|
||||
resultHolder.invokeResult(msg);
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 报警复位: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
DeferredResult<ResponseEntity<WVPResult<String>>> result = new DeferredResult<>(3 * 1000L);
|
||||
result.onTimeout(() -> {
|
||||
log.warn(String.format("报警复位操作超时, 设备未返回应答指令"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>();
|
||||
deviceService.resetAlarm(device, channelId, alarmMethod, alarmType, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[布防/撤防] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
resultHolder.put(key, uuid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制关键帧API接口
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param channelId 通道ID
|
||||
*/
|
||||
@Operation(summary = "强制关键帧", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号")
|
||||
@GetMapping("/i_frame/{deviceId}")
|
||||
public JSONObject iFrame(@PathVariable String deviceId,
|
||||
@RequestParam(required = false) String channelId) {
|
||||
@GetMapping("/i_frame")
|
||||
public void iFrame(String deviceId, @RequestParam(required = false) String channelId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("强制关键帧API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
try {
|
||||
cmder.iFrameCmd(device, channelId);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 强制关键帧: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("DeviceID", deviceId);
|
||||
json.put("ChannelID", channelId);
|
||||
json.put("Result", "OK");
|
||||
return json;
|
||||
Assert.notNull(device, "设备不存在");
|
||||
deviceService.iFrame(device, channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 看守位控制命令API接口
|
||||
*
|
||||
* @param deviceId 设备ID
|
||||
* @param enabled 看守位使能1:开启,0:关闭
|
||||
* @param resetTime 自动归位时间间隔(可选)
|
||||
* @param presetIndex 调用预置位编号(可选)
|
||||
* @param channelId 通道编码(可选)
|
||||
*/
|
||||
@Operation(summary = "看守位控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@ -260,99 +149,54 @@ public class DeviceControl {
|
||||
@RequestParam(required = false) Integer resetTime,
|
||||
@RequestParam(required = false) Integer presetIndex) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("报警复位API调用");
|
||||
log.debug("看守位控制API调用");
|
||||
}
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICECONTROL + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
try {
|
||||
cmder.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("操作失败,错误码: %s, %s", event.statusCode, event.msg)));
|
||||
resultHolder.invokeResult(msg);
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 看守位控制: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>(3 * 1000L);
|
||||
result.onTimeout(() -> {
|
||||
log.warn(String.format("看守位控制操作超时, 设备未返回应答指令"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答")); //("看守位控制操作超时, 设备未返回应答指令");
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>();
|
||||
deviceService.homePosition(device, channelId, enabled, resetTime, presetIndex, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[看守位控制] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
resultHolder.put(key, uuid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉框放大
|
||||
* @param deviceId 设备id
|
||||
* @param channelId 通道id
|
||||
* @param length 播放窗口长度像素值
|
||||
* @param width 播放窗口宽度像素值
|
||||
* @param midpointx 拉框中心的横轴坐标像素值
|
||||
* @param midpointy 拉框中心的纵轴坐标像素值
|
||||
* @param lengthx 拉框长度像素值
|
||||
* @param lengthy 拉框宽度像素值
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "拉框放大", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "length", description = "播放窗口长度像素值", required = true)
|
||||
@Parameter(name = "width", description = "播放窗口宽度像素值", required = true)
|
||||
@Parameter(name = "midpointx", description = "拉框中心的横轴坐标像素值", required = true)
|
||||
@Parameter(name = "midpointy", description = "拉框中心的纵轴坐标像素值", required = true)
|
||||
@Parameter(name = "lengthx", description = "拉框长度像素值", required = true)
|
||||
@Parameter(name = "lengthy", description = "lengthy", required = true)
|
||||
@Parameter(name = "lengthy", description = "拉框宽度像素值", required = true)
|
||||
@GetMapping("drag_zoom/zoom_in")
|
||||
public void dragZoomIn(@RequestParam String deviceId,
|
||||
@RequestParam(required = false) String channelId,
|
||||
public DeferredResult<WVPResult<String>> dragZoomIn(@RequestParam String deviceId, String channelId,
|
||||
@RequestParam int length,
|
||||
@RequestParam int width,
|
||||
@RequestParam int midpointx,
|
||||
@RequestParam int midpointy,
|
||||
@RequestParam int lengthx,
|
||||
@RequestParam int lengthy) throws RuntimeException {
|
||||
@RequestParam int lengthy) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("设备拉框放大 API调用,deviceId:%s ,channelId:%s ,length:%d ,width:%d ,midpointx:%d ,midpointy:%d ,lengthx:%d ,lengthy:%d",deviceId, channelId, length, width, midpointx, midpointy,lengthx, lengthy));
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
cmdXml.append("<DragZoomIn>\r\n");
|
||||
cmdXml.append("<Length>" + length+ "</Length>\r\n");
|
||||
cmdXml.append("<Width>" + width+ "</Width>\r\n");
|
||||
cmdXml.append("<MidPointX>" + midpointx+ "</MidPointX>\r\n");
|
||||
cmdXml.append("<MidPointY>" + midpointy+ "</MidPointY>\r\n");
|
||||
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
||||
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
||||
cmdXml.append("</DragZoomIn>\r\n");
|
||||
try {
|
||||
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 拉框放大: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>();
|
||||
deviceService.dragZoomIn(device, channelId, length, width, midpointx, midpointy, lengthx,lengthy, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[设备拉框放大] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉框缩小
|
||||
* @param deviceId 设备id
|
||||
* @param channelId 通道id
|
||||
* @param length 播放窗口长度像素值
|
||||
* @param width 播放窗口宽度像素值
|
||||
* @param midpointx 拉框中心的横轴坐标像素值
|
||||
* @param midpointy 拉框中心的纵轴坐标像素值
|
||||
* @param lengthx 拉框长度像素值
|
||||
* @param lengthy 拉框宽度像素值
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "拉框缩小", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号")
|
||||
@ -363,7 +207,7 @@ public class DeviceControl {
|
||||
@Parameter(name = "lengthx", description = "拉框长度像素值", required = true)
|
||||
@Parameter(name = "lengthy", description = "拉框宽度像素值", required = true)
|
||||
@GetMapping("/drag_zoom/zoom_out")
|
||||
public void dragZoomOut(@RequestParam String deviceId,
|
||||
public DeferredResult<WVPResult<String>> dragZoomOut(@RequestParam String deviceId,
|
||||
@RequestParam(required = false) String channelId,
|
||||
@RequestParam int length,
|
||||
@RequestParam int width,
|
||||
@ -376,20 +220,15 @@ public class DeviceControl {
|
||||
log.debug(String.format("设备拉框缩小 API调用,deviceId:%s ,channelId:%s ,length:%d ,width:%d ,midpointx:%d ,midpointy:%d ,lengthx:%d ,lengthy:%d",deviceId, channelId, length, width, midpointx, midpointy,lengthx, lengthy));
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
cmdXml.append("<DragZoomOut>\r\n");
|
||||
cmdXml.append("<Length>" + length+ "</Length>\r\n");
|
||||
cmdXml.append("<Width>" + width+ "</Width>\r\n");
|
||||
cmdXml.append("<MidPointX>" + midpointx+ "</MidPointX>\r\n");
|
||||
cmdXml.append("<MidPointY>" + midpointy+ "</MidPointY>\r\n");
|
||||
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
||||
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
||||
cmdXml.append("</DragZoomOut>\r\n");
|
||||
try {
|
||||
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 拉框缩小: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>();
|
||||
deviceService.dragZoomOut(device, channelId, length, width, midpointx, midpointy, lengthx,lengthy, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[设备拉框放大] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
@ -14,8 +15,8 @@ import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask;
|
||||
import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask;
|
||||
import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
@ -27,9 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.apache.ibatis.annotations.Options;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -37,17 +36,13 @@ import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.text.ParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Tag(name = "国标设备查询", description = "国标设备查询")
|
||||
@SuppressWarnings("rawtypes")
|
||||
@ -61,24 +56,25 @@ public class DeviceQuery {
|
||||
|
||||
@Autowired
|
||||
private IInviteStreamService inviteStreamService;
|
||||
|
||||
@Autowired
|
||||
private SIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private ISIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private DynamicTask dynamicTask;
|
||||
|
||||
/**
|
||||
* 使用ID查询国标设备
|
||||
* @param deviceId 国标ID
|
||||
* @return 国标设备
|
||||
*/
|
||||
@Autowired
|
||||
private IRedisRpcService redisRpcService;
|
||||
|
||||
@Operation(summary = "查询国标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@GetMapping("/devices/{deviceId}")
|
||||
@ -87,12 +83,7 @@ public class DeviceQuery {
|
||||
return deviceService.getDeviceByDeviceId(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询国标设备
|
||||
* @param page 当前页
|
||||
* @param count 每页查询数量
|
||||
* @return 分页国标列表
|
||||
*/
|
||||
|
||||
@Operation(summary = "分页查询国标设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||
@ -107,9 +98,7 @@ public class DeviceQuery {
|
||||
return deviceService.getAll(page, count, query, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询通道数
|
||||
*/
|
||||
|
||||
@GetMapping("/devices/{deviceId}/channels")
|
||||
@Operation(summary = "分页查询通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@ -130,9 +119,7 @@ public class DeviceQuery {
|
||||
return deviceChannelService.queryChannelsByDeviceId(deviceId, query, channelType, online, page, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步设备通道
|
||||
*/
|
||||
|
||||
@Operation(summary = "同步设备通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@GetMapping("/devices/{deviceId}/sync")
|
||||
@ -142,37 +129,11 @@ public class DeviceQuery {
|
||||
log.debug("设备通道信息同步API调用,deviceId:" + deviceId);
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
boolean status = deviceService.isSyncRunning(deviceId);
|
||||
// 已存在则返回进度
|
||||
if (deviceService.isSyncRunning(deviceId)) {
|
||||
SyncStatus channelSyncStatus = deviceService.getChannelSyncStatus(deviceId);
|
||||
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);
|
||||
|
||||
WVPResult<SyncStatus> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(0);
|
||||
wvpResult.setMsg("开始同步");
|
||||
return wvpResult;
|
||||
return deviceService.devicesSync(device);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除设备
|
||||
* @param deviceId 设备id
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "移除设备", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@DeleteMapping("/devices/{deviceId}/delete")
|
||||
@ -207,17 +168,6 @@ public class DeviceQuery {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询子目录通道
|
||||
* @param deviceId 通道id
|
||||
* @param channelId 通道id
|
||||
* @param page 当前页
|
||||
* @param count 每页条数
|
||||
* @param query 查询内容
|
||||
* @param online 是否在线
|
||||
* @param channelType 通道类型
|
||||
* @return 子通道列表
|
||||
*/
|
||||
@Operation(summary = "分页查询子目录通道", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@ -241,7 +191,7 @@ public class DeviceQuery {
|
||||
return deviceChannelPageResult;
|
||||
}
|
||||
|
||||
return deviceChannelService.getSubChannels(deviceChannel.getDeviceDbId(), channelId, query, channelType, online, page, count);
|
||||
return deviceChannelService.getSubChannels(deviceChannel.getDataDeviceId(), channelId, query, channelType, online, page, count);
|
||||
}
|
||||
|
||||
@Operation(summary = "开启/关闭通道的音频", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@ -259,13 +209,15 @@ public class DeviceQuery {
|
||||
public void updateChannelStreamIdentification(DeviceChannel channel){
|
||||
deviceChannelService.updateChannelStreamIdentification(channel);
|
||||
}
|
||||
@Operation(summary = "获取单个通道详情", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备的国标编码", required = true)
|
||||
@Parameter(name = "channelDeviceId", description = "通道的国标编码", required = true)
|
||||
@GetMapping("/channel/one")
|
||||
public DeviceChannel getChannel(String deviceId, String channelDeviceId){
|
||||
return deviceChannelService.getOne(deviceId, channelDeviceId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改数据流传输模式
|
||||
* @param deviceId 设备id
|
||||
* @param streamMode 数据流传输模式
|
||||
* @return
|
||||
*/
|
||||
@Operation(summary = "修改数据流传输模式", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "streamMode", description = "数据流传输模式, 取值:" +
|
||||
@ -277,11 +229,7 @@ public class DeviceQuery {
|
||||
deviceService.updateCustomDevice(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加设备信息
|
||||
* @param device 设备信息
|
||||
* @return
|
||||
*/
|
||||
|
||||
@Operation(summary = "添加设备信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "device", description = "设备", required = true)
|
||||
@PostMapping("/device/add/")
|
||||
@ -299,11 +247,7 @@ public class DeviceQuery {
|
||||
deviceService.addDevice(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新设备信息
|
||||
* @param device 设备信息
|
||||
* @return
|
||||
*/
|
||||
|
||||
@Operation(summary = "更新设备信息", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "device", description = "设备", required = true)
|
||||
@PostMapping("/device/update/")
|
||||
@ -314,72 +258,37 @@ public class DeviceQuery {
|
||||
deviceService.updateCustomDevice(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备状态查询请求API接口
|
||||
*
|
||||
* @param deviceId 设备id
|
||||
*/
|
||||
@Operation(summary = "设备状态查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@GetMapping("/devices/{deviceId}/status")
|
||||
public DeferredResult<ResponseEntity<String>> deviceStatusApi(@PathVariable String deviceId) {
|
||||
public DeferredResult<WVPResult<String>> deviceStatusApi(@PathVariable String deviceId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("设备状态查询API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId;
|
||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>(2*1000L);
|
||||
if(device == null) {
|
||||
result.setResult(new ResponseEntity(String.format("设备%s不存在", deviceId),HttpStatus.OK));
|
||||
return result;
|
||||
}
|
||||
try {
|
||||
cmder.deviceStatusQuery(device, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(String.format("获取设备状态失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备状态: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
result.onTimeout(()->{
|
||||
log.warn(String.format("获取设备状态超时"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData("Timeout. Device did not response to this command.");
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<String>> result = new DeferredResult<>();
|
||||
deviceService.deviceStatus(device, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[设备状态查询] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_DEVICESTATUS + deviceId, uuid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备报警查询请求API接口
|
||||
* @param deviceId 设备id
|
||||
* @param startPriority 报警起始级别(可选)
|
||||
* @param endPriority 报警终止级别(可选)
|
||||
* @param alarmMethod 报警方式条件(可选)
|
||||
* @param alarmType 报警类型
|
||||
* @param startTime 报警发生起始时间(可选)
|
||||
* @param endTime 报警发生终止时间(可选)
|
||||
* @return true = 命令发送成功
|
||||
*/
|
||||
@Operation(summary = "设备报警查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "startPriority", description = "报警起始级别")
|
||||
@Parameter(name = "endPriority", description = "报警终止级别")
|
||||
@Parameter(name = "alarmMethod", description = "报警方式条件")
|
||||
@Parameter(name = "startPriority", description = "报警起始级别, 0为全部,1为一级警情,2为二级警情,3为三级警情,4为四级警情")
|
||||
@Parameter(name = "endPriority", description = "报警终止级别, ,0为全部,1为一级警情,2为二级警情,3为三级警情,4为四级警情")
|
||||
@Parameter(name = "alarmMethod", description = "报警方式条件,取值0为全部,1为电话报警,2为设备报警,3为短信报警,4为GPS报警," +
|
||||
"5为视频报警,6为设备故障报警,7其他报警;可以为直接组合如12为电话报警或设备报警")
|
||||
@Parameter(name = "alarmType", description = "报警类型")
|
||||
@Parameter(name = "startTime", description = "报警发生起始时间")
|
||||
@Parameter(name = "endTime", description = "报警发生终止时间")
|
||||
@GetMapping("/alarm/{deviceId}")
|
||||
public DeferredResult<ResponseEntity<String>> alarmApi(@PathVariable String deviceId,
|
||||
@GetMapping("/alarm")
|
||||
public DeferredResult<WVPResult<Object>> alarmApi(String deviceId,
|
||||
@RequestParam(required = false) String startPriority,
|
||||
@RequestParam(required = false) String endPriority,
|
||||
@RequestParam(required = false) String alarmMethod,
|
||||
@ -390,31 +299,35 @@ public class DeviceQuery {
|
||||
log.debug("设备报警查询API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId;
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
try {
|
||||
cmder.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(String.format("设备报警查询失败,错误码: %s, %s",event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 设备报警查询: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String >> (3 * 1000L);
|
||||
result.onTimeout(()->{
|
||||
log.warn(String.format("设备报警查询超时"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData("设备报警查询超时");
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<Object>> result = new DeferredResult<>();
|
||||
deviceService.alarm(device, startPriority,endPriority ,alarmMethod ,alarmType ,startTime ,endTime, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[设备报警查询] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Operation(summary = "设备信息查询", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@GetMapping("/info")
|
||||
public DeferredResult<WVPResult<Object>> deviceInfo(String deviceId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("设备信息查询API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<Object>> result = new DeferredResult<>();
|
||||
deviceService.deviceInfo(device, (code, msg, data) -> {
|
||||
result.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
result.onTimeout(() -> {
|
||||
log.warn("[设备信息查询] 操作超时, 设备未返回应答指令, {}", deviceId);
|
||||
result.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "操作超时, 设备未应答"));
|
||||
});
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_ALARM + deviceId, uuid, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -489,4 +402,21 @@ public class DeviceQuery {
|
||||
public DeviceChannel getRawChannel(int id) {
|
||||
return deviceChannelService.getRawChannel(id);
|
||||
}
|
||||
|
||||
@GetMapping("/subscribe/catalog")
|
||||
@Operation(summary = "开启/关闭目录订阅")
|
||||
@Parameter(name = "id", description = "通道的Id", required = true)
|
||||
@Parameter(name = "cycle", description = "订阅周期", required = true)
|
||||
public void subscribeCatalog(int id, int cycle) {
|
||||
deviceService.subscribeCatalog(id, cycle);
|
||||
}
|
||||
|
||||
@GetMapping("/subscribe/mobile-position")
|
||||
@Operation(summary = "开启/关闭移动位置订阅")
|
||||
@Parameter(name = "id", description = "通道的Id", required = true)
|
||||
@Parameter(name = "cycle", description = "订阅周期", required = true)
|
||||
@Parameter(name = "interval", description = "报送间隔", required = true)
|
||||
public void subscribeMobilePosition(int id, int cycle, int interval) {
|
||||
deviceService.subscribeMobilePosition(id, cycle, interval);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package com.genersoft.iot.vmp.gb28181.controller;
|
||||
|
||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
@ -32,10 +32,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.text.ParseException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Tag(name = "国标录像")
|
||||
@Slf4j
|
||||
@ -72,7 +70,7 @@ public class GBRecordController {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("录像信息查询 API调用,deviceId:%s ,startTime:%s, endTime:%s",deviceId, startTime, endTime));
|
||||
}
|
||||
DeferredResult<WVPResult<RecordInfo>> result = new DeferredResult<>();
|
||||
DeferredResult<WVPResult<RecordInfo>> result = new DeferredResult<>(Long.valueOf(userSetting.getRecordInfoTimeout()), TimeUnit.MILLISECONDS);
|
||||
if (!DateUtil.verification(startTime, DateUtil.formatter)){
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "startTime格式为" + DateUtil.PATTERN);
|
||||
}
|
||||
@ -81,35 +79,25 @@ public class GBRecordController {
|
||||
}
|
||||
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
// 指定超时时间 1分钟30秒
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
int sn = (int)((Math.random()*9+1)*100000);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn;
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
try {
|
||||
cmder.recordInfoQuery(device, channelId, startTime, endTime, sn, null, null, null, (eventResult -> {
|
||||
WVPResult<RecordInfo> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||
wvpResult.setMsg("查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg);
|
||||
msg.setData(wvpResult);
|
||||
resultHolder.invokeResult(msg);
|
||||
}));
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 查询录像: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), deviceId + " 不存在");
|
||||
}
|
||||
|
||||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(key, uuid, result);
|
||||
DeviceChannel channel = channelService.getOneForSource(device.getId(), channelId);
|
||||
if (channel == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), channelId + " 不存在");
|
||||
}
|
||||
channelService.queryRecordInfo(device, channel, startTime, endTime, (code, msg, data)->{
|
||||
WVPResult<RecordInfo> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(code);
|
||||
wvpResult.setMsg(msg);
|
||||
wvpResult.setData(data);
|
||||
result.setResult(wvpResult);
|
||||
});
|
||||
result.onTimeout(()->{
|
||||
msg.setData("timeout");
|
||||
WVPResult<RecordInfo> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||
wvpResult.setMsg("timeout");
|
||||
msg.setData(wvpResult);
|
||||
resultHolder.invokeResult(msg);
|
||||
result.setResult(wvpResult);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@ -159,7 +147,7 @@ public class GBRecordController {
|
||||
if (data != null) {
|
||||
StreamInfo streamInfo = (StreamInfo)data;
|
||||
if (userSetting.getUseSourceIpAsStreamIp()) {
|
||||
streamInfo.channgeStreamIp(request.getLocalAddr());
|
||||
streamInfo.changeStreamIp(request.getLocalAddr());
|
||||
}
|
||||
wvpResult.setData(new StreamContent(streamInfo));
|
||||
}
|
||||
@ -179,7 +167,7 @@ public class GBRecordController {
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "stream", description = "流ID", required = true)
|
||||
@GetMapping("/download/stop/{deviceId}/{channelId}/{stream}")
|
||||
public void playStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
|
||||
public void downloadStop(@PathVariable String deviceId, @PathVariable String channelId, @PathVariable String stream) {
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("设备历史媒体下载停止 API调用,deviceId/channelId:%s_%s", deviceId, channelId));
|
||||
@ -191,14 +179,13 @@ public class GBRecordController {
|
||||
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + "未找到");
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + " 未找到");
|
||||
}
|
||||
|
||||
try {
|
||||
cmder.streamByeCmd(device, channelId, stream, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.warn("[停止历史媒体下载]停止历史媒体下载,发送BYE失败 {}", e.getMessage());
|
||||
DeviceChannel deviceChannel = channelService.getOneForSource(deviceId, channelId);
|
||||
if (deviceChannel == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "通道:" + channelId + " 未找到");
|
||||
}
|
||||
playService.stop(InviteSessionType.DOWNLOAD, device, deviceChannel, stream);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取历史媒体下载进度", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
|
||||
@ -19,6 +19,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
|
||||
@ -91,31 +92,22 @@ public class PlayController {
|
||||
Assert.notNull(deviceId, "设备不存在");
|
||||
DeviceChannel channel = deviceChannelService.getOne(deviceId, channelId);
|
||||
Assert.notNull(channel, "通道不存在");
|
||||
MediaServer newMediaServerItem = playService.getNewMediaServerItem(device);
|
||||
|
||||
RequestMessage requestMessage = new RequestMessage();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
|
||||
requestMessage.setKey(key);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
requestMessage.setId(uuid);
|
||||
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
||||
|
||||
result.onTimeout(()->{
|
||||
log.info("[点播等待超时] deviceId:{}, channelId:{}, ", deviceId, channelId);
|
||||
// 释放rtpserver
|
||||
WVPResult<StreamInfo> wvpResult = new WVPResult<>();
|
||||
WVPResult<StreamContent> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(ErrorCode.ERROR100.getCode());
|
||||
wvpResult.setMsg("点播超时");
|
||||
requestMessage.setData(wvpResult);
|
||||
resultHolder.invokeAllResult(requestMessage);
|
||||
result.setResult(wvpResult);
|
||||
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
||||
deviceChannelService.stopPlay(channel.getId());
|
||||
});
|
||||
|
||||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(key, uuid, result);
|
||||
|
||||
playService.play(newMediaServerItem, deviceId, channelId, null, (code, msg, streamInfo) -> {
|
||||
ErrorCallback<StreamInfo> callback = (code, msg, streamInfo) -> {
|
||||
WVPResult<StreamContent> wvpResult = new WVPResult<>();
|
||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
||||
@ -131,10 +123,10 @@ public class PlayController {
|
||||
} catch (MalformedURLException e) {
|
||||
host=request.getLocalAddr();
|
||||
}
|
||||
streamInfo.channgeStreamIp(host);
|
||||
streamInfo.changeStreamIp(host);
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(newMediaServerItem.getTranscodeSuffix()) && !"null".equalsIgnoreCase(newMediaServerItem.getTranscodeSuffix())) {
|
||||
streamInfo.setStream(streamInfo.getStream() + "_" + newMediaServerItem.getTranscodeSuffix());
|
||||
if (!ObjectUtils.isEmpty(streamInfo.getMediaServer().getTranscodeSuffix()) && !"null".equalsIgnoreCase(streamInfo.getMediaServer().getTranscodeSuffix())) {
|
||||
streamInfo.setStream(streamInfo.getStream() + "_" + streamInfo.getMediaServer().getTranscodeSuffix());
|
||||
}
|
||||
wvpResult.setData(new StreamContent(streamInfo));
|
||||
}else {
|
||||
@ -145,10 +137,9 @@ public class PlayController {
|
||||
wvpResult.setCode(code);
|
||||
wvpResult.setMsg(msg);
|
||||
}
|
||||
requestMessage.setData(wvpResult);
|
||||
// 此处必须释放所有请求
|
||||
resultHolder.invokeAllResult(requestMessage);
|
||||
});
|
||||
result.setResult(wvpResult);
|
||||
};
|
||||
playService.play(device, channel, callback);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -207,16 +198,8 @@ public class PlayController {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("语音广播API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到设备: " + deviceId);
|
||||
}
|
||||
DeviceChannel channel = deviceChannelService.getOne(deviceId, channelId);
|
||||
if (channel == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到通道: " + channelId);
|
||||
}
|
||||
|
||||
return playService.audioBroadcast(device, channel, broadcastMode);
|
||||
return playService.audioBroadcast(deviceId, channelId, broadcastMode);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ public class PlaybackController {
|
||||
} catch (MalformedURLException e) {
|
||||
host=request.getLocalAddr();
|
||||
}
|
||||
streamInfo.channgeStreamIp(host);
|
||||
streamInfo.changeStreamIp(host);
|
||||
}
|
||||
wvpResult.setData(new StreamContent(streamInfo));
|
||||
}
|
||||
@ -156,7 +156,7 @@ public class PlaybackController {
|
||||
}
|
||||
DeviceChannel deviceChannel = channelService.getOneForSource(deviceId, channelId);
|
||||
if (deviceChannel == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "通道:" + deviceChannel + " 未找到");
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "通道:" + channelId + " 未找到");
|
||||
}
|
||||
playService.stop(InviteSessionType.PLAYBACK, device, deviceChannel, stream);
|
||||
}
|
||||
@ -166,8 +166,7 @@ public class PlaybackController {
|
||||
@Parameter(name = "streamId", description = "回放流ID", required = true)
|
||||
@GetMapping("/pause/{streamId}")
|
||||
public void playPause(@PathVariable String streamId) {
|
||||
log.info("playPause: "+streamId);
|
||||
|
||||
log.info("[回放暂停] streamId: {}", streamId);
|
||||
try {
|
||||
playService.pauseRtp(streamId);
|
||||
} catch (ServiceException e) {
|
||||
|
||||
@ -5,25 +5,24 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPTZService;
|
||||
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.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.text.ParseException;
|
||||
import java.util.UUID;
|
||||
|
||||
@Tag(name = "前端设备控制")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@ -36,6 +35,9 @@ public class PtzController {
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Autowired
|
||||
private IPTZService ptzService;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
@ -45,30 +47,29 @@ public class PtzController {
|
||||
@Parameter(name = "cmdCode", description = "指令码(对应国标文档指令格式中的字节4)", required = true)
|
||||
@Parameter(name = "parameter1", description = "数据一(对应国标文档指令格式中的字节5, 范围0-255)", required = true)
|
||||
@Parameter(name = "parameter2", description = "数据二(对应国标文档指令格式中的字节6, 范围0-255)", required = true)
|
||||
@Parameter(name = "combindCode2", description = "组合码二(对应国标文档指令格式中的字节7, 范围0-16)", required = true)
|
||||
@Parameter(name = "combindCode2", description = "组合码二(对应国标文档指令格式中的字节7, 范围0-15)", required = true)
|
||||
@GetMapping("/common/{deviceId}/{channelId}")
|
||||
public void frontEndCommand(@PathVariable String deviceId,@PathVariable String channelId,Integer cmdCode, Integer parameter1, Integer parameter2, Integer combindCode2){
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("设备云台控制 API调用,deviceId:%s ,channelId:%s ,cmdCode:%d parameter1:%d parameter2:%d",deviceId, channelId, cmdCode, parameter1, parameter2));
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
|
||||
if (parameter1 == null || parameter1 < 0 || parameter1 > 255) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter1 为 1-255的数字");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter1 为 0-255的数字");
|
||||
}
|
||||
if (parameter2 == null || parameter2 < 0 || parameter2 > 255) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter1 为 1-255的数字");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "parameter2 为 0-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());
|
||||
if (combindCode2 == null || combindCode2 < 0 || combindCode2 > 15) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "combindCode2 为 0-15的数字");
|
||||
}
|
||||
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
|
||||
Assert.notNull(device, "设备[" + deviceId + "]不存在");
|
||||
|
||||
ptzService.frontEndCommand(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
|
||||
}
|
||||
|
||||
@Operation(summary = "云台控制", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
@ -77,7 +78,7 @@ public class PtzController {
|
||||
@Parameter(name = "command", description = "控制指令,允许值: left, right, up, down, upleft, upright, downleft, downright, zoomin, zoomout, stop", required = true)
|
||||
@Parameter(name = "horizonSpeed", description = "水平速度(0-255)", required = true)
|
||||
@Parameter(name = "verticalSpeed", description = "垂直速度(0-255)", required = true)
|
||||
@Parameter(name = "zoomSpeed", description = "缩放速度(0-16)", required = true)
|
||||
@Parameter(name = "zoomSpeed", description = "缩放速度(0-15)", required = true)
|
||||
@GetMapping("/ptz/{deviceId}/{channelId}")
|
||||
public void ptz(@PathVariable String deviceId,@PathVariable String channelId, String command, Integer horizonSpeed, Integer verticalSpeed, Integer zoomSpeed){
|
||||
|
||||
@ -87,17 +88,17 @@ public class PtzController {
|
||||
if (horizonSpeed == null) {
|
||||
horizonSpeed = 100;
|
||||
}else if (horizonSpeed < 0 || horizonSpeed > 255) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "horizonSpeed 为 1-255的数字");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "horizonSpeed 为 0-255的数字");
|
||||
}
|
||||
if (verticalSpeed == null) {
|
||||
verticalSpeed = 100;
|
||||
}else if (verticalSpeed < 0 || verticalSpeed > 255) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "verticalSpeed 为 1-255的数字");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "verticalSpeed 为 0-255的数字");
|
||||
}
|
||||
if (zoomSpeed == null) {
|
||||
zoomSpeed = 16;
|
||||
}else if (zoomSpeed < 0 || zoomSpeed > 16) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "zoomSpeed 为 1-255的数字");
|
||||
}else if (zoomSpeed < 0 || zoomSpeed > 15) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "zoomSpeed 为 0-15的数字");
|
||||
}
|
||||
|
||||
int cmdCode = 0;
|
||||
@ -156,6 +157,12 @@ public class PtzController {
|
||||
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(), "speed 为 0-255的数字");
|
||||
}
|
||||
|
||||
int cmdCode = 0x40;
|
||||
switch (command){
|
||||
case "in":
|
||||
@ -188,7 +195,7 @@ public class PtzController {
|
||||
if (speed == null) {
|
||||
speed = 100;
|
||||
}else if (speed < 0 || speed > 255) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "verticalSpeed 为 1-255的数字");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "speed 为 0-255的数字");
|
||||
}
|
||||
|
||||
int cmdCode = 0x40;
|
||||
@ -212,40 +219,22 @@ public class PtzController {
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@GetMapping("/preset/query/{deviceId}/{channelId}")
|
||||
public DeferredResult<String> queryPreset(@PathVariable String deviceId, @PathVariable String channelId) {
|
||||
public DeferredResult<WVPResult<Object>> queryPreset(@PathVariable String deviceId, @PathVariable String channelId) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("设备预置位查询API调用");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_PRESETQUERY + (ObjectUtils.isEmpty(channelId) ? deviceId : channelId);
|
||||
DeferredResult<String> result = new DeferredResult<String> (3 * 1000L);
|
||||
result.onTimeout(()->{
|
||||
log.warn(String.format("获取设备预置位超时"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData("获取设备预置位超时");
|
||||
resultHolder.invokeResult(msg);
|
||||
Assert.notNull(device, "设备不存在");
|
||||
DeferredResult<WVPResult<Object>> deferredResult = new DeferredResult<> (3 * 1000L);
|
||||
deviceService.queryPreset(device, channelId, (code, msg, data) -> {
|
||||
deferredResult.setResult(new WVPResult<>(code, msg, data));
|
||||
});
|
||||
if (resultHolder.exist(key, null)) {
|
||||
return result;
|
||||
}
|
||||
resultHolder.put(key, uuid, result);
|
||||
try {
|
||||
cmder.presetQuery(device, channelId, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(uuid);
|
||||
msg.setKey(key);
|
||||
msg.setData(String.format("获取设备预置位失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备预置位: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
return result;
|
||||
|
||||
deferredResult.onTimeout(()->{
|
||||
log.warn("[获取设备预置位] 超时, {}", device.getDeviceId());
|
||||
deferredResult.setResult(WVPResult.fail(ErrorCode.ERROR100.getCode(), "超时"));
|
||||
});
|
||||
return deferredResult;
|
||||
}
|
||||
|
||||
@Operation(summary = "预置位指令-设置预置位", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||
|
||||
@ -124,4 +124,20 @@ public class RegionController {
|
||||
public void sync(){
|
||||
regionService.syncFromChannel();
|
||||
}
|
||||
|
||||
@Operation(summary = "根据行政区划编号从文件中查询层级和描述")
|
||||
@ResponseBody
|
||||
@GetMapping("/description")
|
||||
public String getDescription(String civilCode){
|
||||
return regionService.getDescription(civilCode);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据行政区划编号从文件中查询层级并添加")
|
||||
@ResponseBody
|
||||
@GetMapping("/addByCivilCode")
|
||||
public void addByCivilCode(String civilCode){
|
||||
regionService.addByCivilCode(civilCode);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,13 +1,21 @@
|
||||
package com.genersoft.iot.vmp.gb28181.controller.bean;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Schema(description="提交行政区划关联多个通道的参数")
|
||||
public class ChannelToRegionParam {
|
||||
|
||||
@Schema(description = "行政区划编号")
|
||||
private String civilCode;
|
||||
|
||||
@Schema(description = "选择的通道, 和all参数二选一")
|
||||
private List<Integer> channelIds;
|
||||
|
||||
@Schema(description = "所有通道, 和channelIds参数二选一")
|
||||
private Boolean all;
|
||||
|
||||
}
|
||||
|
||||
@ -20,8 +20,8 @@ public interface CommonGBChannelMapper {
|
||||
@Insert(" <script>" +
|
||||
"INSERT INTO wvp_device_channel (" +
|
||||
"gb_device_id," +
|
||||
" <if test='streamProxyId != null' > stream_proxy_id,</if>" +
|
||||
" <if test='streamPushId != null' > stream_push_id,</if>" +
|
||||
"data_type," +
|
||||
"data_device_id," +
|
||||
"create_time," +
|
||||
"update_time," +
|
||||
"gb_name," +
|
||||
@ -59,8 +59,8 @@ public interface CommonGBChannelMapper {
|
||||
"gb_svc_time_support_mode ) " +
|
||||
"VALUES (" +
|
||||
"#{gbDeviceId}, " +
|
||||
" <if test='streamProxyId != null' > #{streamProxyId},</if>" +
|
||||
" <if test='streamPushId != null' > #{streamPushId},</if>" +
|
||||
"#{dataType}, " +
|
||||
"#{dataDeviceId}, " +
|
||||
"#{createTime}, " +
|
||||
"#{updateTime}, " +
|
||||
"#{gbName}, " +
|
||||
@ -152,7 +152,7 @@ public interface CommonGBChannelMapper {
|
||||
" SET gb_status = #{status}" +
|
||||
" WHERE id = #{gbId}"+
|
||||
" </script>"})
|
||||
int updateStatusById(@Param("gbId") int gbId, @Param("status") int status);
|
||||
int updateStatusById(@Param("gbId") int gbId, @Param("status") String status);
|
||||
|
||||
@Update("<script> " +
|
||||
"<foreach collection='commonGBChannels' index='index' item='item' separator=';'> " +
|
||||
@ -168,8 +168,8 @@ public interface CommonGBChannelMapper {
|
||||
@Insert(" <script>" +
|
||||
"INSERT INTO wvp_device_channel (" +
|
||||
"gb_device_id," +
|
||||
"stream_proxy_id, " +
|
||||
"stream_push_id," +
|
||||
"data_type, " +
|
||||
"data_device_id," +
|
||||
"create_time," +
|
||||
"update_time," +
|
||||
"gb_name," +
|
||||
@ -207,7 +207,7 @@ public interface CommonGBChannelMapper {
|
||||
"gb_svc_time_support_mode ) " +
|
||||
"VALUES" +
|
||||
"<foreach collection='commonGBChannels' index='index' item='item' separator=','> " +
|
||||
"(#{item.gbDeviceId}, #{item.streamProxyId}, #{item.streamPushId},#{item.createTime},#{item.updateTime}," +
|
||||
"(#{item.gbDeviceId}, #{item.dataType}, #{item.dataDeviceId},#{item.createTime},#{item.updateTime}," +
|
||||
"#{item.gbName},#{item.gbManufacturer}, #{item.gbModel}," +
|
||||
"#{item.gbOwner},#{item.gbCivilCode},#{item.gbBlock}, #{item.gbAddress}, #{item.gbParental}, #{item.gbParentId},#{item.gbSafetyWay}, " +
|
||||
"#{item.gbRegisterWay},#{item.gbCertNum},#{item.gbCertifiable},#{item.gbErrCode},#{item.gbEndTime}, #{item.gbSecrecy},#{item.gbIpAddress}," +
|
||||
@ -235,9 +235,9 @@ public interface CommonGBChannelMapper {
|
||||
" gb_ptz_type = null, gb_position_type = null, gb_room_type = null, gb_use_type = null, gb_supply_light_type = null, " +
|
||||
" gb_direction_type = null, gb_resolution = null, gb_business_group_id = null, gb_download_speed = null, gb_svc_space_support_mod = null, " +
|
||||
" gb_svc_time_support_mode = null" +
|
||||
" WHERE id = #{id} and device_db_id = #{gbDeviceDbId}"+
|
||||
" WHERE id = #{id} and data_type = #{dataType} and data_device_id = #{dataDeviceId}"+
|
||||
" </script>"})
|
||||
void reset(@Param("id") int id, @Param("gbDeviceDbId") int gbDeviceDbId, @Param("updateTime") String updateTime);
|
||||
void reset(@Param("id") int id, @Param("dataType") Integer dataType, @Param("dataDeviceId") int dataDeviceId, @Param("updateTime") String updateTime);
|
||||
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByIds")
|
||||
@ -250,21 +250,15 @@ public interface CommonGBChannelMapper {
|
||||
"</script>"})
|
||||
void batchDelete(List<CommonGBChannel> channelListInDb);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByStreamPushId")
|
||||
CommonGBChannel queryByStreamPushId(@Param("streamPushId") Integer streamPushId);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByStreamProxyId")
|
||||
CommonGBChannel queryByStreamProxyId(@Param("streamProxyId") Integer streamProxyId);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryListByCivilCode")
|
||||
List<CommonGBChannel> queryListByCivilCode(@Param("query") String query, @Param("online") Boolean online,
|
||||
@Param("channelType") Integer channelType, @Param("civilCode") String civilCode);
|
||||
@Param("dataType") Integer dataType, @Param("civilCode") String civilCode);
|
||||
|
||||
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryListByParentId")
|
||||
List<CommonGBChannel> queryListByParentId(@Param("query") String query, @Param("online") Boolean online,
|
||||
@Param("channelType") Integer channelType, @Param("groupDeviceId") String groupDeviceId);
|
||||
@Param("dataType") Integer dataType, @Param("groupDeviceId") String groupDeviceId);
|
||||
|
||||
|
||||
|
||||
@ -313,18 +307,26 @@ public interface CommonGBChannelMapper {
|
||||
" </script>"})
|
||||
int removeCivilCodeByChannels(List<CommonGBChannel> channelList);
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
" UPDATE wvp_device_channel " +
|
||||
" SET gb_civil_code = null, civil_code = null" +
|
||||
" WHERE id in "+
|
||||
" <foreach collection='channelIdList' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
|
||||
" </script>"})
|
||||
int removeCivilCodeByChannelIds(List<Integer> channelIdList);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByCivilCode")
|
||||
List<CommonGBChannel> queryByCivilCode(@Param("civilCode") String civilCode);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByGbDeviceIds")
|
||||
List<CommonGBChannel> queryByGbDeviceIds(List<Integer> deviceIds);
|
||||
List<CommonGBChannel> queryByGbDeviceIds(@Param("dataType") Integer dataType, List<Integer> deviceIds);
|
||||
|
||||
@Select(value = {" <script>" +
|
||||
" select id from wvp_device_channel " +
|
||||
" where channel_type = 0 and device_db_id in "+
|
||||
" where channel_type = 0 and data_type = #{dataType} and data_device_id in "+
|
||||
" <foreach collection='deviceIds' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
|
||||
" </script>"})
|
||||
List<Integer> queryByGbDeviceIdsForIds(List<Integer> deviceIds);
|
||||
List<Integer> queryByGbDeviceIdsForIds(@Param("dataType") Integer dataType, List<Integer> deviceIds);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByGroupList")
|
||||
List<CommonGBChannel> queryByGroupList(List<Group> groupList);
|
||||
@ -446,19 +448,20 @@ public interface CommonGBChannelMapper {
|
||||
int updateCivilCodeByChannelList(@Param("civilCode") String civilCode, List<CommonGBChannel> channelList);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryListByStreamPushList")
|
||||
List<CommonGBChannel> queryListByStreamPushList(List<StreamPush> streamPushList);
|
||||
List<CommonGBChannel> queryListByStreamPushList(@Param("dataType") Integer dataType, List<StreamPush> streamPushList);
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
" <foreach collection='channels' item='item' separator=';' >" +
|
||||
" UPDATE wvp_device_channel " +
|
||||
" SET gb_longitude=#{item.gbLongitude}, gb_latitude=#{item.gbLatitude} " +
|
||||
" WHERE stream_push_id IS NOT NULL AND gb_device_id=#{item.gbDeviceId} "+
|
||||
" WHERE data_type = #{dataType} AND gb_device_id=#{item.gbDeviceId} "+
|
||||
"</foreach>"+
|
||||
" </script>"})
|
||||
void updateGpsByDeviceIdForStreamPush(List<CommonGBChannel> channels);
|
||||
void updateGpsByDeviceIdForStreamPush(@Param("dataType") Integer dataType, List<CommonGBChannel> channels);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryList")
|
||||
List<CommonGBChannel> queryList(@Param("query") String query, @Param("online") Boolean online, @Param("hasRecordPlan") Boolean hasRecordPlan, @Param("channelType") Integer channelType);
|
||||
List<CommonGBChannel> queryList(@Param("query") String query, @Param("online") Boolean online,
|
||||
@Param("hasRecordPlan") Boolean hasRecordPlan, @Param("dataType") Integer dataType);
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
" UPDATE wvp_device_channel " +
|
||||
@ -493,9 +496,8 @@ public interface CommonGBChannelMapper {
|
||||
@Select("<script>" +
|
||||
" select " +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" wdc.record_plan_id,\n" +
|
||||
@ -542,12 +544,32 @@ public interface CommonGBChannelMapper {
|
||||
" <if test='online == false'> AND coalesce(wdc.gb_status, wdc.status) = 'OFF'</if> " +
|
||||
" <if test='hasLink == true'> AND wdc.record_plan_id = #{planId}</if> " +
|
||||
" <if test='hasLink == false'> AND wdc.record_plan_id is null</if> " +
|
||||
" <if test='channelType == 0'> AND wdc.device_db_id is not null</if> " +
|
||||
" <if test='channelType == 1'> AND wdc.stream_push_id is not null</if> " +
|
||||
" <if test='channelType == 2'> AND wdc.stream_proxy_id is not null</if> " +
|
||||
" <if test='dataType != null'> AND wdc.data_type = #{dataType}</if> " +
|
||||
"</script>")
|
||||
List<CommonGBChannel> queryForRecordPlanForWebList(@Param("planId") Integer planId, @Param("query") String query,
|
||||
@Param("channelType") Integer channelType, @Param("online") Boolean online,
|
||||
@Param("dataType") Integer dataType, @Param("online") Boolean online,
|
||||
@Param("hasLink") Boolean hasLink);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryByDataId")
|
||||
CommonGBChannel queryByDataId(@Param("dataType") Integer dataType, @Param("dataDeviceId") Integer dataDeviceId);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryListByCivilCodeForUnusual")
|
||||
List<CommonGBChannel> queryListByCivilCodeForUnusual(@Param("query") String query, @Param("online") Boolean online, @Param("dataType")Integer dataType);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryAllForUnusualCivilCode")
|
||||
List<Integer> queryAllForUnusualCivilCode();
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryListByParentForUnusual")
|
||||
List<CommonGBChannel> queryListByParentForUnusual(@Param("query") String query, @Param("online") Boolean online, @Param("dataType")Integer dataType);
|
||||
|
||||
@SelectProvider(type = ChannelProvider.class, method = "queryAllForUnusualParent")
|
||||
List<Integer> queryAllForUnusualParent();
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
" UPDATE wvp_device_channel " +
|
||||
" SET gb_parent_id = null, gb_business_group_id = null, parent_id = null, business_group_id = null" +
|
||||
" WHERE id in "+
|
||||
" <foreach collection='channelIdsForClear' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
|
||||
" </script>"})
|
||||
void removeParentIdByChannelIds(List<Integer> channelIdsForClear);
|
||||
}
|
||||
|
||||
@ -21,13 +21,13 @@ public interface DeviceChannelMapper {
|
||||
|
||||
@Insert("<script> " +
|
||||
"insert into wvp_device_channel " +
|
||||
"(device_id, device_db_id, name, manufacturer, model, owner, civil_code, block, " +
|
||||
"(device_id, data_type, data_device_id, name, manufacturer, model, owner, civil_code, block, " +
|
||||
"address, parental, parent_id, safety_way, register_way, cert_num, certifiable, err_code, end_time, secrecy, " +
|
||||
"ip_address, port, password, status, longitude, latitude, ptz_type, position_type, room_type, use_type, " +
|
||||
"supply_light_type, direction_type, resolution, business_group_id, download_speed, svc_space_support_mod, " +
|
||||
"svc_time_support_mode, create_time, update_time, sub_count, stream_id, has_audio, gps_time, stream_identification, channel_type) " +
|
||||
"values " +
|
||||
"(#{deviceId}, #{deviceDbId}, #{name}, #{manufacturer}, #{model}, #{owner}, #{civilCode}, #{block}, " +
|
||||
"(#{deviceId}, #{dataType}, #{dataDeviceId}, #{name}, #{manufacturer}, #{model}, #{owner}, #{civilCode}, #{block}, " +
|
||||
"#{address}, #{parental}, #{parentId}, #{safetyWay}, #{registerWay}, #{certNum}, #{certifiable}, #{errCode}, #{endTime}, #{secrecy}, " +
|
||||
"#{ipAddress}, #{port}, #{password}, #{status}, #{longitude}, #{latitude}, #{ptzType}, #{positionType}, #{roomType}, #{useType}, " +
|
||||
"#{supplyLightType}, #{directionType}, #{resolution}, #{businessGroupId}, #{downloadSpeed}, #{svcSpaceSupportMod}," +
|
||||
@ -40,7 +40,8 @@ public interface DeviceChannelMapper {
|
||||
"UPDATE wvp_device_channel " +
|
||||
"SET update_time=#{updateTime}" +
|
||||
", device_id=#{deviceId}" +
|
||||
", device_db_id=#{deviceDbId}" +
|
||||
", data_type=#{dataType}" +
|
||||
", data_device_id=#{dataDeviceId}" +
|
||||
", name=#{name}" +
|
||||
", manufacturer=#{manufacturer}" +
|
||||
", model=#{model}" +
|
||||
@ -85,22 +86,22 @@ public interface DeviceChannelMapper {
|
||||
int update(DeviceChannel channel);
|
||||
|
||||
@SelectProvider(type = DeviceChannelProvider.class, method = "queryChannels")
|
||||
List<DeviceChannel> queryChannels(@Param("deviceDbId") int deviceDbId, @Param("civilCode") String civilCode,
|
||||
List<DeviceChannel> queryChannels(@Param("dataDeviceId") int dataDeviceId, @Param("civilCode") String civilCode,
|
||||
@Param("businessGroupId") String businessGroupId, @Param("parentChannelId") String parentChannelId,
|
||||
@Param("query") String query, @Param("hasSubChannel") Boolean hasSubChannel,
|
||||
@Param("online") Boolean online, @Param("channelIds") List<String> channelIds);
|
||||
|
||||
@SelectProvider(type = DeviceChannelProvider.class, method = "queryChannelsByDeviceDbId")
|
||||
List<DeviceChannel> queryChannelsByDeviceDbId(@Param("deviceDbId") int deviceDbId);
|
||||
List<DeviceChannel> queryChannelsByDeviceDbId(@Param("dataDeviceId") int dataDeviceId);
|
||||
|
||||
@Select(value = {" <script> " +
|
||||
"select id from wvp_device_channel where device_db_id in " +
|
||||
@Select("<script> " +
|
||||
"select id from wvp_device_channel where data_type =1 and data_device_id in " +
|
||||
" <foreach item='item' index='index' collection='deviceDbIds' open='(' separator=',' close=')'> #{item} </foreach>" +
|
||||
" </script>"})
|
||||
" </script>")
|
||||
List<Integer> queryChaneIdListByDeviceDbIds(List<Integer> deviceDbIds);
|
||||
|
||||
@Delete("DELETE FROM wvp_device_channel WHERE device_db_id=#{deviceId}")
|
||||
int cleanChannelsByDeviceId(@Param("deviceId") int deviceId);
|
||||
@Delete("DELETE FROM wvp_device_channel WHERE data_type =1 and data_device_id=#{dataDeviceId}")
|
||||
int cleanChannelsByDeviceId(@Param("dataDeviceId") int dataDeviceId);
|
||||
|
||||
@Delete("DELETE FROM wvp_device_channel WHERE id=#{id}")
|
||||
int del(@Param("id") int id);
|
||||
@ -141,8 +142,8 @@ public interface DeviceChannelMapper {
|
||||
" coalesce(dc.gb_business_group_id, dc.business_group_id) as business_group_id " +
|
||||
" from " +
|
||||
" wvp_device_channel dc " +
|
||||
" LEFT JOIN wvp_device de ON dc.device_db_id = de.id " +
|
||||
" WHERE 1=1" +
|
||||
" LEFT JOIN wvp_device de ON dc.data_device_id = de.id " +
|
||||
" WHERE dc.data_type = 1 " +
|
||||
" <if test='deviceId != null'> AND de.device_id = #{deviceId} </if> " +
|
||||
" <if test='query != null'> AND (dc.device_id LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
|
||||
" <if test='parentChannelId != null'> AND dc.parent_id=#{parentChannelId} </if> " +
|
||||
@ -155,7 +156,7 @@ public interface DeviceChannelMapper {
|
||||
"</foreach> </if>" +
|
||||
"ORDER BY dc.device_id ASC" +
|
||||
" </script>"})
|
||||
List<DeviceChannelExtend> queryChannelsWithDeviceInfo(@Param("deviceId") String deviceId, @Param("parentChannelId") String parentChannelId, @Param("query") String query, @Param("hasSubChannel") Boolean hasSubChannel, @Param("online") Boolean online, @Param("channelIds") List<String> channelIds);
|
||||
List<DeviceChannelExtend> queryChannelsWithDeviceInfo( @Param("deviceId") String deviceId, @Param("parentChannelId") String parentChannelId, @Param("query") String query, @Param("hasSubChannel") Boolean hasSubChannel, @Param("online") Boolean online, @Param("channelIds") List<String> channelIds);
|
||||
|
||||
@Update(value = {"UPDATE wvp_device_channel SET stream_id=#{streamId} WHERE id=#{channelId}"})
|
||||
void startPlay(@Param("channelId") Integer channelId, @Param("streamId") String streamId);
|
||||
@ -172,9 +173,9 @@ public interface DeviceChannelMapper {
|
||||
" pgc.platform_id as platform_id,\n" +
|
||||
" pgc.catalog_id as catalog_id " +
|
||||
" FROM wvp_device_channel dc " +
|
||||
" LEFT JOIN wvp_device de ON dc.device_db_id = de.id " +
|
||||
" LEFT JOIN wvp_device de ON dc.data_device_id = de.id " +
|
||||
" LEFT JOIN wvp_platform_channel pgc on pgc.device_channel_id = dc.id " +
|
||||
" WHERE 1=1 " +
|
||||
" WHERE dc.data_type = 1 " +
|
||||
" <if test='query != null'> " +
|
||||
"AND " +
|
||||
"(COALESCE(dc.gb_device_id, dc.device_id) LIKE concat('%',#{query},'%') " +
|
||||
@ -195,14 +196,14 @@ public interface DeviceChannelMapper {
|
||||
|
||||
@Insert("<script> " +
|
||||
"insert into wvp_device_channel " +
|
||||
"(device_id, device_db_id, name, manufacturer, model, owner, civil_code, block, " +
|
||||
"(device_id, data_type, data_device_id, name, manufacturer, model, owner, civil_code, block, " +
|
||||
"address, parental, parent_id, safety_way, register_way, cert_num, certifiable, err_code, end_time, secrecy, " +
|
||||
"ip_address, port, password, status, longitude, latitude, ptz_type, position_type, room_type, use_type, " +
|
||||
"supply_light_type, direction_type, resolution, business_group_id, download_speed, svc_space_support_mod, " +
|
||||
"svc_time_support_mode, create_time, update_time, sub_count, stream_id, has_audio, gps_time, stream_identification, channel_type) " +
|
||||
"values " +
|
||||
"<foreach collection='addChannels' index='index' item='item' separator=','> " +
|
||||
"(#{item.deviceId}, #{item.deviceDbId}, #{item.name}, #{item.manufacturer}, #{item.model}, #{item.owner}, #{item.civilCode}, #{item.block}, " +
|
||||
"(#{item.deviceId}, #{item.dataType}, #{item.dataDeviceId}, #{item.name}, #{item.manufacturer}, #{item.model}, #{item.owner}, #{item.civilCode}, #{item.block}, " +
|
||||
"#{item.address}, #{item.parental}, #{item.parentId}, #{item.safetyWay}, #{item.registerWay}, #{item.certNum}, #{item.certifiable}, #{item.errCode}, #{item.endTime}, #{item.secrecy}, " +
|
||||
"#{item.ipAddress}, #{item.port}, #{item.password}, #{item.status}, #{item.longitude}, #{item.latitude}, #{item.ptzType}, #{item.positionType}, #{item.roomType}, #{item.useType}, " +
|
||||
"#{item.supplyLightType}, #{item.directionType}, #{item.resolution}, #{item.businessGroupId}, #{item.downloadSpeed}, #{item.svcSpaceSupportMod}," +
|
||||
@ -221,7 +222,8 @@ public interface DeviceChannelMapper {
|
||||
" wvp_device_channel" +
|
||||
" SET update_time=#{item.updateTime}" +
|
||||
", device_id=#{item.deviceId}" +
|
||||
", device_db_id=#{item.deviceDbId}" +
|
||||
", data_type=#{item.dataType}" +
|
||||
", data_device_id=#{item.dataDeviceId}" +
|
||||
", name=#{item.name}" +
|
||||
", manufacturer=#{item.manufacturer}" +
|
||||
", model=#{item.model}" +
|
||||
@ -273,7 +275,8 @@ public interface DeviceChannelMapper {
|
||||
" wvp_device_channel" +
|
||||
" SET update_time=#{item.updateTime}" +
|
||||
", device_id=#{item.deviceId}" +
|
||||
", device_db_id=#{item.deviceDbId}" +
|
||||
", data_type=#{item.dataType}" +
|
||||
", data_device_id=#{item.dataDeviceId}" +
|
||||
", name=#{item.name}" +
|
||||
", manufacturer=#{item.manufacturer}" +
|
||||
", model=#{item.model}" +
|
||||
@ -313,7 +316,7 @@ public interface DeviceChannelMapper {
|
||||
", gps_time=#{item.gpsTime}" +
|
||||
", stream_identification=#{item.streamIdentification}" +
|
||||
", channel_type=#{item.channelType}" +
|
||||
" WHERE device_db_id = #{item.deviceDbId} and device_id=#{item.deviceId}" +
|
||||
" WHERE data_type = #{item.dataType} and data_device_id = #{item.dataDeviceId} and device_id=#{item.deviceId}" +
|
||||
"</foreach>" +
|
||||
"</script>"})
|
||||
int batchUpdateForNotify(List<DeviceChannel> updateChannels);
|
||||
@ -322,9 +325,9 @@ public interface DeviceChannelMapper {
|
||||
" set sub_count = (select *" +
|
||||
" from (select count(0)" +
|
||||
" from wvp_device_channel" +
|
||||
" where device_db_id = #{deviceDbId} and parent_id = #{channelId}) as temp)" +
|
||||
" where device_db_id = #{deviceDbId} and device_id = #{channelId}")
|
||||
int updateChannelSubCount(@Param("deviceDbId") int deviceDbId, @Param("channelId") String channelId);
|
||||
" where data_type = 1 and data_device_id = #{dataDeviceId} and parent_id = #{channelId}) as temp)" +
|
||||
" where data_type = 1 and data_device_id = #{dataDeviceId} and device_id = #{channelId}")
|
||||
int updateChannelSubCount(@Param("dataDeviceId") int dataDeviceId, @Param("channelId") String channelId);
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
" UPDATE wvp_device_channel " +
|
||||
@ -338,7 +341,7 @@ public interface DeviceChannelMapper {
|
||||
|
||||
@Select("select " +
|
||||
" id,\n" +
|
||||
" device_db_id,\n" +
|
||||
" data_device_id,\n" +
|
||||
" create_time,\n" +
|
||||
" update_time,\n" +
|
||||
" sub_count,\n" +
|
||||
@ -381,11 +384,11 @@ public interface DeviceChannelMapper {
|
||||
" download_speed,\n" +
|
||||
" svc_space_support_mod,\n" +
|
||||
" svc_time_support_mode\n" +
|
||||
" from wvp_device_channel where device_db_id = #{deviceDbId}")
|
||||
List<DeviceChannel> queryAllChannelsForRefresh(@Param("deviceDbId") int deviceDbId);
|
||||
" from wvp_device_channel where data_type = 1 and data_device_id = #{dataDeviceId}")
|
||||
List<DeviceChannel> queryAllChannelsForRefresh(@Param("dataDeviceId") int dataDeviceId);
|
||||
|
||||
@Select("select de.* from wvp_device de left join wvp_device_channel dc on de.device_id = dc.device_id where dc.device_id=#{channelId}")
|
||||
List<Device> getDeviceByChannelDeviceId(String channelId);
|
||||
@Select("select de.* from wvp_device de left join wvp_device_channel dc on de.device_id = dc.device_id where dc.data_type = 1 and dc.device_id=#{channelId}")
|
||||
List<Device> getDeviceByChannelDeviceId(@Param("channelId") String channelId);
|
||||
|
||||
|
||||
@Delete({"<script>" +
|
||||
@ -397,7 +400,7 @@ public interface DeviceChannelMapper {
|
||||
|
||||
@Update({"<script>" +
|
||||
"<foreach collection='channels' item='item' separator=';'>" +
|
||||
"UPDATE wvp_device_channel SET status=#{item.status} WHERE device_id=#{item.deviceId}" +
|
||||
"UPDATE wvp_device_channel SET status=#{item.status} WHERE data_type = #{item.dataType} and device_id=#{item.deviceId}" +
|
||||
"</foreach>" +
|
||||
"</script>"})
|
||||
int batchUpdateStatus(List<DeviceChannel> channels);
|
||||
@ -427,7 +430,7 @@ public interface DeviceChannelMapper {
|
||||
"<if test='item.latitude != null'>, latitude=#{item.latitude}</if>" +
|
||||
"<if test='item.gpsTime != null'>, gps_time=#{item.gpsTime}</if>" +
|
||||
"<if test='item.id > 0'>WHERE id=#{item.id}</if>" +
|
||||
"<if test='item.id == 0'>WHERE device_db_id=#{item.deviceDbId} AND device_id=#{item.deviceId}</if>" +
|
||||
"<if test='item.id == 0'>WHERE data_type = #{item.dataType} and data_device_id=#{item.dataDeviceId} AND device_id=#{item.deviceId}</if>" +
|
||||
"</foreach>" +
|
||||
"</script>"})
|
||||
void batchUpdatePosition(List<DeviceChannel> channelList);
|
||||
@ -438,7 +441,7 @@ public interface DeviceChannelMapper {
|
||||
@Select(value = {" <script>" +
|
||||
" SELECT " +
|
||||
" id,\n" +
|
||||
" device_db_id,\n" +
|
||||
" data_device_id,\n" +
|
||||
" create_time,\n" +
|
||||
" update_time,\n" +
|
||||
" sub_count,\n" +
|
||||
@ -487,13 +490,13 @@ public interface DeviceChannelMapper {
|
||||
DeviceChannel getOneForSource(@Param("id") int id);
|
||||
|
||||
@SelectProvider(type = DeviceChannelProvider.class, method = "getOneByDeviceId")
|
||||
DeviceChannel getOneByDeviceId(@Param("deviceDbId") int deviceDbId, @Param("channelId") String channelId);
|
||||
DeviceChannel getOneByDeviceId(@Param("dataDeviceId") int dataDeviceId, @Param("channelId") String channelId);
|
||||
|
||||
|
||||
@Select(value = {" <script>" +
|
||||
" SELECT " +
|
||||
" id,\n" +
|
||||
" device_db_id,\n" +
|
||||
" data_device_id,\n" +
|
||||
" create_time,\n" +
|
||||
" update_time,\n" +
|
||||
" sub_count,\n" +
|
||||
@ -537,9 +540,9 @@ public interface DeviceChannelMapper {
|
||||
" svc_space_support_mod,\n" +
|
||||
" svc_time_support_mode\n" +
|
||||
" from wvp_device_channel " +
|
||||
" where device_db_id=#{deviceDbId} and coalesce(gb_device_id, device_id) = #{channelId}" +
|
||||
" where data_type = 1 and data_device_id=#{dataDeviceId} and coalesce(gb_device_id, device_id) = #{channelId}" +
|
||||
" </script>"})
|
||||
DeviceChannel getOneByDeviceIdForSource(@Param("deviceDbId") int deviceDbId, @Param("channelId") String channelId);
|
||||
DeviceChannel getOneByDeviceIdForSource(@Param("dataDeviceId") int dataDeviceId, @Param("channelId") String channelId);
|
||||
|
||||
|
||||
@Update(value = {"UPDATE wvp_device_channel SET stream_id=null WHERE id=#{channelId}"})
|
||||
@ -559,7 +562,7 @@ public interface DeviceChannelMapper {
|
||||
"</script>")
|
||||
void updateStreamGPS(List<GPSMsgInfo> gpsMsgInfoList);
|
||||
|
||||
@Update("UPDATE wvp_device_channel SET status=#{status} WHERE device_db_id=#{deviceDbId} AND device_id=#{deviceId}")
|
||||
@Update("UPDATE wvp_device_channel SET status=#{status} WHERE data_type=#{dataType} and data_device_id=#{dataDeviceId} AND device_id=#{deviceId}")
|
||||
void updateStatus(DeviceChannel channel);
|
||||
|
||||
|
||||
@ -568,7 +571,7 @@ public interface DeviceChannelMapper {
|
||||
" wvp_device_channel" +
|
||||
" SET update_time=#{updateTime}" +
|
||||
", device_id=#{deviceId}" +
|
||||
", device_db_id=#{deviceDbId}" +
|
||||
", data_device_id=#{dataDeviceId}" +
|
||||
", name=#{name}" +
|
||||
", manufacturer=#{manufacturer}" +
|
||||
", model=#{model}" +
|
||||
@ -616,7 +619,7 @@ public interface DeviceChannelMapper {
|
||||
@Select(value = {" <script>" +
|
||||
" SELECT " +
|
||||
" id,\n" +
|
||||
" device_db_id,\n" +
|
||||
" data_device_id,\n" +
|
||||
" create_time,\n" +
|
||||
" update_time,\n" +
|
||||
" sub_count,\n" +
|
||||
@ -660,7 +663,7 @@ public interface DeviceChannelMapper {
|
||||
" svc_space_support_mod,\n" +
|
||||
" svc_time_support_mode\n" +
|
||||
" from wvp_device_channel " +
|
||||
" where device_db_id=#{deviceDbId} and device_id = #{channelId}" +
|
||||
" where data_type = 1 and data_device_id=#{dataDeviceId} and device_id = #{channelId}" +
|
||||
" </script>"})
|
||||
DeviceChannel getOneBySourceChannelId(int deviceDbId, String channelId);
|
||||
DeviceChannel getOneBySourceChannelId(@Param("dataDeviceId") int dataDeviceId, @Param("channelId") String channelId);
|
||||
}
|
||||
|
||||
@ -43,11 +43,12 @@ public interface DeviceMapper {
|
||||
"as_message_channel," +
|
||||
"geo_coord_sys," +
|
||||
"on_line," +
|
||||
"server_id,"+
|
||||
"media_server_id," +
|
||||
"broadcast_push_after_ack," +
|
||||
"(SELECT count(0) FROM wvp_device_channel dc WHERE dc.device_db_id= de.id) as channel_count "+
|
||||
"(SELECT count(0) FROM wvp_device_channel dc WHERE dc.data_type = 1 and dc.data_device_id= de.id) as channel_count "+
|
||||
" FROM wvp_device de WHERE de.device_id = #{deviceId}")
|
||||
Device getDeviceByDeviceId(String deviceId);
|
||||
Device getDeviceByDeviceId( @Param("deviceId") String deviceId);
|
||||
|
||||
@Insert("INSERT INTO wvp_device (" +
|
||||
"device_id, " +
|
||||
@ -66,7 +67,9 @@ public interface DeviceMapper {
|
||||
"expires," +
|
||||
"register_time," +
|
||||
"keepalive_time," +
|
||||
"keepalive_interval_time," +
|
||||
"heart_beat_interval," +
|
||||
"heart_beat_count," +
|
||||
"position_capability," +
|
||||
"create_time," +
|
||||
"update_time," +
|
||||
"charset," +
|
||||
@ -78,6 +81,7 @@ public interface DeviceMapper {
|
||||
"as_message_channel,"+
|
||||
"broadcast_push_after_ack,"+
|
||||
"geo_coord_sys,"+
|
||||
"server_id,"+
|
||||
"on_line"+
|
||||
") VALUES (" +
|
||||
"#{deviceId}," +
|
||||
@ -96,7 +100,9 @@ public interface DeviceMapper {
|
||||
"#{expires}," +
|
||||
"#{registerTime}," +
|
||||
"#{keepaliveTime}," +
|
||||
"#{keepaliveIntervalTime}," +
|
||||
"#{heartBeatInterval}," +
|
||||
"#{heartBeatCount}," +
|
||||
"#{positionCapability}," +
|
||||
"#{createTime}," +
|
||||
"#{updateTime}," +
|
||||
"#{charset}," +
|
||||
@ -108,6 +114,7 @@ public interface DeviceMapper {
|
||||
"#{asMessageChannel}," +
|
||||
"#{broadcastPushAfterAck}," +
|
||||
"#{geoCoordSys}," +
|
||||
"#{serverId}," +
|
||||
"#{onLine}" +
|
||||
")")
|
||||
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
|
||||
@ -128,8 +135,11 @@ public interface DeviceMapper {
|
||||
"<if test=\"onLine != null\">, on_line=#{onLine}</if>" +
|
||||
"<if test=\"registerTime != null\">, register_time=#{registerTime}</if>" +
|
||||
"<if test=\"keepaliveTime != null\">, keepalive_time=#{keepaliveTime}</if>" +
|
||||
"<if test=\"keepaliveIntervalTime != null\">, keepalive_interval_time=#{keepaliveIntervalTime}</if>" +
|
||||
"<if test=\"heartBeatInterval != null\">, heart_beat_interval=#{heartBeatInterval}</if>" +
|
||||
"<if test=\"positionCapability != null\">, position_capability=#{positionCapability}</if>" +
|
||||
"<if test=\"heartBeatCount != null\">, heart_beat_count=#{heartBeatCount}</if>" +
|
||||
"<if test=\"expires != null\">, expires=#{expires}</if>" +
|
||||
"<if test=\"serverId != null\">, server_id=#{serverId}</if>" +
|
||||
"WHERE device_id=#{deviceId}"+
|
||||
" </script>"})
|
||||
int update(Device device);
|
||||
@ -167,13 +177,13 @@ public interface DeviceMapper {
|
||||
"geo_coord_sys,"+
|
||||
"on_line,"+
|
||||
"media_server_id,"+
|
||||
"(SELECT count(0) FROM wvp_device_channel dc WHERE dc.device_db_id= de.id) as channel_count " +
|
||||
"(SELECT count(0) FROM wvp_device_channel dc WHERE dc.data_type = #{dataType} and dc.data_device_id= de.id) as channel_count " +
|
||||
"FROM wvp_device de" +
|
||||
"<if test=\"onLine != null\"> where de.on_line=${onLine}</if>"+
|
||||
"<if test='online != null'> where de.on_line=${online}</if>"+
|
||||
" order by de.create_time desc "+
|
||||
" </script>"
|
||||
)
|
||||
List<Device> getDevices(Boolean onLine);
|
||||
List<Device> getDevices(@Param("dataType") Integer dataType, @Param("online") Boolean online);
|
||||
|
||||
@Delete("DELETE FROM wvp_device WHERE device_id=#{deviceId}")
|
||||
int del(String deviceId);
|
||||
@ -207,9 +217,43 @@ public interface DeviceMapper {
|
||||
"as_message_channel,"+
|
||||
"broadcast_push_after_ack,"+
|
||||
"geo_coord_sys,"+
|
||||
"server_id,"+
|
||||
"on_line"+
|
||||
" FROM wvp_device WHERE on_line = true")
|
||||
List<Device> getOnlineDevices();
|
||||
@Select("SELECT " +
|
||||
"id, " +
|
||||
"device_id, " +
|
||||
"coalesce(custom_name, name) as name, " +
|
||||
"password, " +
|
||||
"manufacturer, " +
|
||||
"model, " +
|
||||
"firmware, " +
|
||||
"transport," +
|
||||
"stream_mode," +
|
||||
"ip," +
|
||||
"sdp_ip,"+
|
||||
"local_ip,"+
|
||||
"port,"+
|
||||
"host_address,"+
|
||||
"expires,"+
|
||||
"register_time,"+
|
||||
"keepalive_time,"+
|
||||
"create_time,"+
|
||||
"update_time,"+
|
||||
"charset,"+
|
||||
"subscribe_cycle_for_catalog,"+
|
||||
"subscribe_cycle_for_mobile_position,"+
|
||||
"mobile_position_submission_interval,"+
|
||||
"subscribe_cycle_for_alarm,"+
|
||||
"ssrc_check,"+
|
||||
"as_message_channel,"+
|
||||
"broadcast_push_after_ack,"+
|
||||
"geo_coord_sys,"+
|
||||
"server_id,"+
|
||||
"on_line"+
|
||||
" FROM wvp_device WHERE on_line = true and server_id = #{serverId}")
|
||||
List<Device> getOnlineDevicesByServerId(@Param("serverId") String serverId);
|
||||
|
||||
@Select("SELECT " +
|
||||
"id,"+
|
||||
@ -247,9 +291,8 @@ public interface DeviceMapper {
|
||||
@Update(value = {" <script>" +
|
||||
"UPDATE wvp_device " +
|
||||
"SET update_time=#{updateTime}, custom_name=#{name} , password=#{password}, stream_mode=#{streamMode}" +
|
||||
", ip=#{ip}, sdp_ip=#{sdpIp}, port=#{port}, charset=#{charset}, subscribe_cycle_for_catalog=#{subscribeCycleForCatalog}" +
|
||||
", subscribe_cycle_for_mobile_position=#{subscribeCycleForMobilePosition}, mobile_position_submission_interval=#{mobilePositionSubmissionInterval}" +
|
||||
", subscribe_cycle_for_alarm=#{subscribeCycleForAlarm}, ssrc_check=#{ssrcCheck}, as_message_channel=#{asMessageChannel}" +
|
||||
", ip=#{ip}, sdp_ip=#{sdpIp}, port=#{port}, charset=#{charset}" +
|
||||
", ssrc_check=#{ssrcCheck}, as_message_channel=#{asMessageChannel}" +
|
||||
", broadcast_push_after_ack=#{broadcastPushAfterAck}, geo_coord_sys=#{geoCoordSys}, media_server_id=#{mediaServerId}" +
|
||||
" WHERE id=#{id}"+
|
||||
" </script>"})
|
||||
@ -269,6 +312,7 @@ public interface DeviceMapper {
|
||||
"geo_coord_sys,"+
|
||||
"on_line,"+
|
||||
"stream_mode," +
|
||||
"server_id," +
|
||||
"media_server_id"+
|
||||
") VALUES (" +
|
||||
"#{deviceId}," +
|
||||
@ -284,6 +328,7 @@ public interface DeviceMapper {
|
||||
"#{geoCoordSys}," +
|
||||
"#{onLine}," +
|
||||
"#{streamMode}," +
|
||||
"#{serverId}," +
|
||||
"#{mediaServerId}" +
|
||||
")")
|
||||
void addCustomDevice(Device device);
|
||||
@ -326,7 +371,8 @@ public interface DeviceMapper {
|
||||
"geo_coord_sys,"+
|
||||
"on_line,"+
|
||||
"media_server_id,"+
|
||||
"(SELECT count(0) FROM wvp_device_channel dc WHERE dc.device_db_id= de.id) as channel_count " +
|
||||
"server_id,"+
|
||||
"(SELECT count(0) FROM wvp_device_channel dc WHERE dc.data_type = #{dataType} and dc.data_device_id= de.id) as channel_count " +
|
||||
" FROM wvp_device de" +
|
||||
" where 1 = 1 "+
|
||||
" <if test='status != null'> AND de.on_line=${status}</if>"+
|
||||
@ -337,7 +383,7 @@ public interface DeviceMapper {
|
||||
"</if> " +
|
||||
" order by create_time desc "+
|
||||
" </script>")
|
||||
List<Device> getDeviceList(@Param("query") String query, @Param("status") Boolean status);
|
||||
List<Device> getDeviceList(@Param("dataType") Integer dataType, @Param("query") String query, @Param("status") Boolean status);
|
||||
|
||||
@Select("select * from wvp_device_channel where id = #{id}")
|
||||
DeviceChannel getRawChannel(@Param("id") int id);
|
||||
@ -345,10 +391,23 @@ public interface DeviceMapper {
|
||||
@Select("select * from wvp_device where id = #{id}")
|
||||
Device query(@Param("id") Integer id);
|
||||
|
||||
@Select("select wd.* from wvp_device wd left join wvp_device_channel wdc on wd.id = wdc.device_db_id where wdc.id = #{channelId}")
|
||||
Device queryByChannelId(@Param("channelId") Integer channelId);
|
||||
@Select("select wd.* from wvp_device wd left join wvp_device_channel wdc on wdc.data_type = #{dataType} and wd.id = wdc.data_device_id where wdc.id = #{channelId}")
|
||||
Device queryByChannelId(@Param("dataType") Integer dataType, @Param("channelId") Integer channelId);
|
||||
|
||||
@Select("select wd.* from wvp_device wd left join wvp_device_channel wdc on wd.id = wdc.device_db_id where wdc.device_id = #{channelDeviceId}")
|
||||
Device getDeviceBySourceChannelDeviceId(@Param("channelDeviceId") String channelDeviceId);
|
||||
@Select("select wd.* from wvp_device wd left join wvp_device_channel wdc on wdc.data_type = #{dataType} and wd.id = wdc.data_device_id where wdc.device_id = #{channelDeviceId}")
|
||||
Device getDeviceBySourceChannelDeviceId(@Param("dataType") Integer dataType, @Param("channelDeviceId") String channelDeviceId);
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
" UPDATE wvp_device " +
|
||||
" SET subscribe_cycle_for_catalog=#{subscribeCycleForCatalog}" +
|
||||
" WHERE id=#{id}"+
|
||||
" </script>"})
|
||||
void updateSubscribeCatalog(Device device);
|
||||
|
||||
@Update(value = {" <script>" +
|
||||
"UPDATE wvp_device " +
|
||||
"SET subscribe_cycle_for_mobile_position=#{subscribeCycleForMobilePosition}, mobile_position_submission_interval=#{mobilePositionSubmissionInterval}" +
|
||||
" WHERE id=#{id}"+
|
||||
" </script>"})
|
||||
void updateSubscribeMobilePosition(Device device);
|
||||
}
|
||||
|
||||
@ -58,16 +58,18 @@ public interface PlatformChannelMapper {
|
||||
"where dc.channel_type = 0 and dc.channel_id = #{channelId} and pgc.platform_id=#{platformId}")
|
||||
List<Device> queryDeviceInfoByPlatformIdAndChannelId(@Param("platformId") String platformId, @Param("channelId") String channelId);
|
||||
|
||||
@Select("SELECT pgc.platform_id from wvp_platform_channel pgc left join wvp_device_channel dc on dc.id = pgc.device_channel_id WHERE dc.channel_type = 0 and dc.device_id=#{channelId}")
|
||||
List<Integer> queryParentPlatformByChannelId(@Param("channelId") String channelId);
|
||||
@Select(" SELECT wp.* from wvp_platform_channel pgc " +
|
||||
" left join wvp_device_channel dc on dc.id = pgc.device_channel_id " +
|
||||
" left join wvp_platform wp on wp.id = pgc.platform_id" +
|
||||
" WHERE dc.channel_type = 0 and dc.device_id=#{channelId}")
|
||||
List<Platform> queryParentPlatformByChannelId(@Param("channelId") String channelId);
|
||||
|
||||
@Select("<script>" +
|
||||
" select " +
|
||||
" wpgc.id ,\n" +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type ,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" wpgc.custom_device_id, \n" +
|
||||
@ -149,19 +151,16 @@ public interface PlatformChannelMapper {
|
||||
" <if test='online == false'> AND coalesce(wpgc.status, wdc.gb_status, wdc.status) = 'OFF'</if> " +
|
||||
" <if test='hasShare == true'> AND wpgc.platform_id = #{platformId}</if> " +
|
||||
" <if test='hasShare == false'> AND wpgc.platform_id is null</if> " +
|
||||
" <if test='channelType == 0'> AND wdc.device_db_id is not null</if> " +
|
||||
" <if test='channelType == 1'> AND wdc.stream_push_id is not null</if> " +
|
||||
" <if test='channelType == 2'> AND wdc.stream_proxy_id is not null</if> " +
|
||||
" <if test='dataType != null'> AND wdc.data_type = #{dataType}</if> " +
|
||||
"</script>")
|
||||
List<PlatformChannel> queryForPlatformForWebList(@Param("platformId") Integer platformId, @Param("query") String query,
|
||||
@Param("channelType") Integer channelType, @Param("online") Boolean online,
|
||||
@Param("dataType") Integer dataType, @Param("online") Boolean online,
|
||||
@Param("hasShare") Boolean hasShare);
|
||||
|
||||
@Select("select\n" +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" coalesce(wpgc.custom_device_id, wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
|
||||
@ -209,9 +208,8 @@ public interface PlatformChannelMapper {
|
||||
@Select("<script>" +
|
||||
" select " +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" coalesce(wpgc.custom_device_id, wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
|
||||
@ -260,9 +258,8 @@ public interface PlatformChannelMapper {
|
||||
@Select("<script>" +
|
||||
" select " +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" coalesce(wpgc.custom_device_id, wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
|
||||
@ -485,9 +482,8 @@ public interface PlatformChannelMapper {
|
||||
@Select("<script>" +
|
||||
" select " +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" coalesce(wpgc.custom_device_id, wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
|
||||
|
||||
@ -16,11 +16,11 @@ public interface PlatformMapper {
|
||||
@Insert("INSERT INTO wvp_platform (enable, name, server_gb_id, server_gb_domain, server_ip, server_port,device_gb_id,device_ip,"+
|
||||
" device_port,username,password,expires,keep_timeout,transport,character_set,ptz,rtcp,status,catalog_group, update_time," +
|
||||
" create_time, as_message_channel, send_stream_ip, auto_push_channel, catalog_with_platform,catalog_with_group,catalog_with_region, "+
|
||||
" civil_code,manufacturer,model,address,register_way,secrecy) " +
|
||||
" civil_code,manufacturer,model,address,register_way,secrecy,server_id) " +
|
||||
" VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIp}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " +
|
||||
" #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, #{status}, #{catalogGroup},#{updateTime}," +
|
||||
" #{createTime}, #{asMessageChannel}, #{sendStreamIp}, #{autoPushChannel}, #{catalogWithPlatform}, #{catalogWithGroup},#{catalogWithRegion}, " +
|
||||
" #{civilCode}, #{manufacturer}, #{model}, #{address}, #{registerWay}, #{secrecy})")
|
||||
" #{civilCode}, #{manufacturer}, #{model}, #{address}, #{registerWay}, #{secrecy}, #{serverId})")
|
||||
int add(Platform parentPlatform);
|
||||
|
||||
@Update("UPDATE wvp_platform " +
|
||||
@ -55,6 +55,7 @@ public interface PlatformMapper {
|
||||
" model=#{model}, " +
|
||||
" address=#{address}, " +
|
||||
" register_way=#{registerWay}, " +
|
||||
" server_id=#{serverId}, " +
|
||||
" secrecy=#{secrecy} " +
|
||||
"WHERE id=#{id}")
|
||||
int update(Platform parentPlatform);
|
||||
@ -76,8 +77,8 @@ public interface PlatformMapper {
|
||||
" </script>")
|
||||
List<Platform> queryList(@Param("query") String query);
|
||||
|
||||
@Select("SELECT * FROM wvp_platform WHERE enable=#{enable} ")
|
||||
List<Platform> getEnableParentPlatformList(boolean enable);
|
||||
@Select("SELECT * FROM wvp_platform WHERE server_id=#{serverId} and enable=#{enable} ")
|
||||
List<Platform> queryEnableParentPlatformList(@Param("serverId") String serverId, @Param("enable") boolean enable);
|
||||
|
||||
@Select("SELECT * FROM wvp_platform WHERE enable=true and as_message_channel=true")
|
||||
List<Platform> queryEnablePlatformListWithAsMessageChannel();
|
||||
@ -91,7 +92,9 @@ public interface PlatformMapper {
|
||||
@Update("UPDATE wvp_platform SET status=#{online} WHERE server_gb_id=#{platformGbID}" )
|
||||
int updateStatus(@Param("platformGbID") String platformGbID, @Param("online") boolean online);
|
||||
|
||||
@Select("SELECT * FROM wvp_platform WHERE enable=true")
|
||||
List<Platform> queryEnablePlatformList();
|
||||
@Select("SELECT server_id FROM wvp_platform WHERE enable=true and server_id != #{serverId} group by server_id")
|
||||
List<String> queryServerIdsWithEnableAndNotInServer(@Param("serverId") String serverId);
|
||||
|
||||
@Select("SELECT * FROM wvp_platform WHERE server_id = #{serverId}")
|
||||
List<Platform> queryByServerId(@Param("serverId") String serverId);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.dao;
|
||||
|
||||
import com.genersoft.iot.vmp.common.CivilCodePo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Region;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.RegionTree;
|
||||
@ -179,4 +180,12 @@ public interface RegionMapper {
|
||||
" </script>")
|
||||
Set<Region> queryNotShareRegionForPlatformByRegionList(Set<Region> allRegion, @Param("platformId") Integer platformId);
|
||||
|
||||
|
||||
@Select(" <script>" +
|
||||
" SELECT device_id " +
|
||||
" from wvp_common_region" +
|
||||
" where device_id in " +
|
||||
" <foreach collection='civilCodePoList' item='item' open='(' separator=',' close=')' > #{item.code}</foreach>" +
|
||||
" </script>")
|
||||
Set<String> queryInCivilCodePoList(List<CivilCodePo> civilCodePoList);
|
||||
}
|
||||
|
||||
@ -12,9 +12,8 @@ public class ChannelProvider {
|
||||
|
||||
public final static String BASE_SQL = "select\n" +
|
||||
" id as gb_id,\n" +
|
||||
" device_db_id as gb_device_db_id,\n" +
|
||||
" stream_push_id,\n" +
|
||||
" stream_proxy_id,\n" +
|
||||
" data_type,\n" +
|
||||
" data_device_id,\n" +
|
||||
" create_time,\n" +
|
||||
" update_time,\n" +
|
||||
" record_plan_id,\n" +
|
||||
@ -54,13 +53,56 @@ public class ChannelProvider {
|
||||
" coalesce(gb_svc_time_support_mode,svc_time_support_mode) as gb_svc_time_support_mode\n" +
|
||||
" from wvp_device_channel\n"
|
||||
;
|
||||
|
||||
public final static String BASE_SQL_TABLE_NAME = "select\n" +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" wdc.record_plan_id,\n" +
|
||||
" coalesce(wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
|
||||
" coalesce(wdc.gb_name, wdc.name) as gb_name,\n" +
|
||||
" coalesce(wdc.gb_manufacturer, wdc.manufacturer) as gb_manufacturer,\n" +
|
||||
" coalesce(wdc.gb_model, wdc.model) as gb_model,\n" +
|
||||
" coalesce(wdc.gb_owner, wdc.owner) as gb_owner,\n" +
|
||||
" coalesce(wdc.gb_civil_code, wdc.civil_code) as gb_civil_code,\n" +
|
||||
" coalesce(wdc.gb_block, wdc.block) as gb_block,\n" +
|
||||
" coalesce(wdc.gb_address, wdc.address) as gb_address,\n" +
|
||||
" coalesce(wdc.gb_parental, wdc.parental) as gb_parental,\n" +
|
||||
" coalesce(wdc.gb_parent_id, wdc.parent_id) as gb_parent_id,\n" +
|
||||
" coalesce(wdc.gb_safety_way, wdc.safety_way) as gb_safety_way,\n" +
|
||||
" coalesce(wdc.gb_register_way, wdc.register_way) as gb_register_way,\n" +
|
||||
" coalesce(wdc.gb_cert_num, wdc.cert_num) as gb_cert_num,\n" +
|
||||
" coalesce(wdc.gb_certifiable, wdc.certifiable) as gb_certifiable,\n" +
|
||||
" coalesce(wdc.gb_err_code, wdc.err_code) as gb_err_code,\n" +
|
||||
" coalesce(wdc.gb_end_time, wdc.end_time) as gb_end_time,\n" +
|
||||
" coalesce(wdc.gb_secrecy, wdc.secrecy) as gb_secrecy,\n" +
|
||||
" coalesce(wdc.gb_ip_address, wdc.ip_address) as gb_ip_address,\n" +
|
||||
" coalesce(wdc.gb_port, wdc.port) as gb_port,\n" +
|
||||
" coalesce(wdc.gb_password, wdc.password) as gb_password,\n" +
|
||||
" coalesce(wdc.gb_status, wdc.status) as gb_status,\n" +
|
||||
" coalesce(wdc.gb_longitude, wdc.longitude) as gb_longitude,\n" +
|
||||
" coalesce(wdc.gb_latitude, wdc.latitude) as gb_latitude,\n" +
|
||||
" coalesce(wdc.gb_ptz_type, wdc.ptz_type) as gb_ptz_type,\n" +
|
||||
" coalesce(wdc.gb_position_type, wdc.position_type) as gb_position_type,\n" +
|
||||
" coalesce(wdc.gb_room_type, wdc.room_type) as gb_room_type,\n" +
|
||||
" coalesce(wdc.gb_use_type, wdc.use_type) as gb_use_type,\n" +
|
||||
" coalesce(wdc.gb_supply_light_type, wdc.supply_light_type) as gb_supply_light_type,\n" +
|
||||
" coalesce(wdc.gb_direction_type, wdc.direction_type) as gb_direction_type,\n" +
|
||||
" coalesce(wdc.gb_resolution, wdc.resolution) as gb_resolution,\n" +
|
||||
" coalesce(wdc.gb_business_group_id, wdc.business_group_id) as gb_business_group_id,\n" +
|
||||
" coalesce(wdc.gb_download_speed, wdc.download_speed) as gb_download_speed,\n" +
|
||||
" coalesce(wdc.gb_svc_space_support_mod, wdc.svc_space_support_mod) as gb_svc_space_support_mod,\n" +
|
||||
" coalesce(wdc.gb_svc_time_support_mode, wdc.svc_time_support_mode) as gb_svc_time_support_mode\n" +
|
||||
" from wvp_device_channel wdc\n"
|
||||
;
|
||||
|
||||
private final static String BASE_SQL_FOR_PLATFORM =
|
||||
"select\n" +
|
||||
" wdc.id as gb_id,\n" +
|
||||
" wdc.device_db_id as gb_device_db_id,\n" +
|
||||
" wdc.stream_push_id,\n" +
|
||||
" wdc.stream_proxy_id,\n" +
|
||||
" wdc.data_type,\n" +
|
||||
" wdc.data_device_id,\n" +
|
||||
" wdc.create_time,\n" +
|
||||
" wdc.update_time,\n" +
|
||||
" coalesce(wpgc.custom_device_id, wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
|
||||
@ -109,15 +151,10 @@ public class ChannelProvider {
|
||||
return BASE_SQL + " where channel_type = 0 and id = #{gbId}";
|
||||
}
|
||||
|
||||
public String queryByStreamPushId(Map<String, Object> params ){
|
||||
return BASE_SQL + " where channel_type = 0 and stream_push_id = #{streamPushId}";
|
||||
public String queryByDataId(Map<String, Object> params ){
|
||||
return BASE_SQL + " where channel_type = 0 and data_type = #{dataType} and data_device_id = #{dataDeviceId}";
|
||||
}
|
||||
|
||||
public String queryByStreamProxyId(Map<String, Object> params ){
|
||||
return BASE_SQL + " where channel_type = 0 and stream_proxy_id = #{streamProxyId}";
|
||||
}
|
||||
|
||||
|
||||
public String queryListByCivilCode(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(BASE_SQL);
|
||||
@ -138,14 +175,8 @@ public class ChannelProvider {
|
||||
}else {
|
||||
sqlBuild.append(" AND coalesce(gb_civil_code, civil_code) is null");
|
||||
}
|
||||
if (params.get("channelType") != null) {
|
||||
if ((Integer)params.get("channelType") == 0) {
|
||||
sqlBuild.append(" AND device_db_id is not null");
|
||||
}else if ((Integer)params.get("channelType") == 1) {
|
||||
sqlBuild.append(" AND stream_push_id is not null");
|
||||
}else if ((Integer)params.get("channelType") == 2) {
|
||||
sqlBuild.append(" AND stream_proxy_id is not null");
|
||||
}
|
||||
if (params.get("dataType") != null) {
|
||||
sqlBuild.append(" AND data_type = #{dataType}");
|
||||
}
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
@ -170,15 +201,8 @@ public class ChannelProvider {
|
||||
}else {
|
||||
sqlBuild.append(" AND coalesce(gb_parent_id, parent_id) is null");
|
||||
}
|
||||
|
||||
if (params.get("channelType") != null) {
|
||||
if ((Integer)params.get("channelType") == 0) {
|
||||
sqlBuild.append(" AND device_db_id is not null");
|
||||
}else if ((Integer)params.get("channelType") == 1) {
|
||||
sqlBuild.append(" AND stream_push_id is not null");
|
||||
}else if ((Integer)params.get("channelType") == 2) {
|
||||
sqlBuild.append(" AND stream_proxy_id is not null");
|
||||
}
|
||||
if (params.get("dataType") != null) {
|
||||
sqlBuild.append(" AND data_type = #{dataType}");
|
||||
}
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
@ -201,15 +225,8 @@ public class ChannelProvider {
|
||||
if (params.get("hasRecordPlan") != null && (Boolean)params.get("hasRecordPlan")) {
|
||||
sqlBuild.append(" AND record_plan_id > 0");
|
||||
}
|
||||
|
||||
if (params.get("channelType") != null) {
|
||||
if ((Integer)params.get("channelType") == 0) {
|
||||
sqlBuild.append(" AND device_db_id is not null");
|
||||
}else if ((Integer)params.get("channelType") == 1) {
|
||||
sqlBuild.append(" AND stream_push_id is not null");
|
||||
}else if ((Integer)params.get("channelType") == 2) {
|
||||
sqlBuild.append(" AND stream_proxy_id is not null");
|
||||
}
|
||||
if (params.get("dataType") != null) {
|
||||
sqlBuild.append(" AND data_type = #{dataType}");
|
||||
}
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
@ -253,7 +270,7 @@ public class ChannelProvider {
|
||||
public String queryByGbDeviceIds(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(BASE_SQL);
|
||||
sqlBuild.append("where channel_type = 0 and device_db_id in ( ");
|
||||
sqlBuild.append("where channel_type = 0 and data_type = #{dataType} and data_device_id in ( ");
|
||||
|
||||
Collection<Integer> ids = (Collection<Integer>)params.get("deviceIds");
|
||||
boolean first = true;
|
||||
@ -356,7 +373,7 @@ public class ChannelProvider {
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(BASE_SQL);
|
||||
|
||||
sqlBuild.append(" where channel_type = 0 and stream_push_id in ( ");
|
||||
sqlBuild.append(" where channel_type = 0 and data_type = #{dataType} and data_device_id in ( ");
|
||||
Collection<StreamPush> ids = (Collection<StreamPush>)params.get("streamPushList");
|
||||
boolean first = true;
|
||||
for (StreamPush streamPush : ids) {
|
||||
@ -391,4 +408,68 @@ public class ChannelProvider {
|
||||
sqlBuild.append(" where wpgc.platform_id = #{platformId} and coalesce(wpgc.custom_civil_code, wdc.gb_civil_code, wdc.civil_code) = #{civilCode}");
|
||||
return sqlBuild.toString() ;
|
||||
}
|
||||
|
||||
public String queryListByCivilCodeForUnusual(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(BASE_SQL_TABLE_NAME);
|
||||
sqlBuild.append(" left join (select wcr.device_id from wvp_common_region wcr) temp on temp.device_id = coalesce(wdc.gb_civil_code, wdc.civil_code)" +
|
||||
" where coalesce(wdc.gb_civil_code, wdc.civil_code) is not null and temp.device_id is null ");
|
||||
sqlBuild.append(" AND wdc.channel_type = 0 ");
|
||||
if (params.get("query") != null) {
|
||||
sqlBuild.append(" AND (coalesce(wdc.gb_device_id, wdc.device_id) LIKE concat('%',#{query},'%') escape '/'" +
|
||||
" OR coalesce(wdc.gb_name, wdc.name) LIKE concat('%',#{query},'%') escape '/' )")
|
||||
;
|
||||
}
|
||||
if (params.get("online") != null && (Boolean)params.get("online")) {
|
||||
sqlBuild.append(" AND coalesce(wdc.gb_status, wdc.status) = 'ON'");
|
||||
}
|
||||
if (params.get("online") != null && !(Boolean)params.get("online")) {
|
||||
sqlBuild.append(" AND coalesce(wdc.gb_status, wdc.status) = 'OFF'");
|
||||
}
|
||||
if (params.get("dataType") != null) {
|
||||
sqlBuild.append(" AND wdc.data_type = #{dataType}");
|
||||
}
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
|
||||
public String queryListByParentForUnusual(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(BASE_SQL_TABLE_NAME);
|
||||
sqlBuild.append(" left join (select wcg.device_id from wvp_common_group wcg) temp on temp.device_id = coalesce(wdc.gb_parent_id, wdc.parent_id)" +
|
||||
" where coalesce(wdc.gb_parent_id, wdc.parent_id) is not null and temp.device_id is null ");
|
||||
sqlBuild.append(" AND wdc.channel_type = 0 ");
|
||||
if (params.get("query") != null) {
|
||||
sqlBuild.append(" AND (coalesce(wdc.gb_device_id, wdc.device_id) LIKE concat('%',#{query},'%') escape '/'" +
|
||||
" OR coalesce(wdc.gb_name, wdc.name) LIKE concat('%',#{query},'%') escape '/' )")
|
||||
;
|
||||
}
|
||||
if (params.get("online") != null && (Boolean)params.get("online")) {
|
||||
sqlBuild.append(" AND coalesce(wdc.gb_status, wdc.status) = 'ON'");
|
||||
}
|
||||
if (params.get("online") != null && !(Boolean)params.get("online")) {
|
||||
sqlBuild.append(" AND coalesce(wdc.gb_status, wdc.status) = 'OFF'");
|
||||
}
|
||||
if (params.get("dataType") != null) {
|
||||
sqlBuild.append(" AND wdc.data_type = #{dataType}");
|
||||
}
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
|
||||
public String queryAllForUnusualCivilCode(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append("select wdc.id from wvp_device_channel wdc ");
|
||||
sqlBuild.append(" left join (select wcr.device_id from wvp_common_region wcr) temp on temp.device_id = coalesce(wdc.gb_civil_code, wdc.civil_code)" +
|
||||
" where coalesce(wdc.gb_civil_code, wdc.civil_code) is not null and temp.device_id is null ");
|
||||
sqlBuild.append(" AND wdc.channel_type = 0 ");
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
|
||||
public String queryAllForUnusualParent(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append("select wdc.id from wvp_device_channel wdc ");
|
||||
sqlBuild.append(" left join (select wcg.device_id from wvp_common_group wcg) temp on temp.device_id = coalesce(wdc.gb_parent_id, wdc.parent_id)" +
|
||||
" where coalesce(wdc.gb_parent_id, wdc.parent_id) is not null and temp.device_id is null ");
|
||||
sqlBuild.append(" AND wdc.channel_type = 0 ");
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.dao.provider;
|
||||
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.util.List;
|
||||
@ -10,7 +11,7 @@ public class DeviceChannelProvider {
|
||||
public String getBaseSelectSql(){
|
||||
return "SELECT " +
|
||||
" dc.id,\n" +
|
||||
" dc.device_db_id,\n" +
|
||||
" dc.data_device_id,\n" +
|
||||
" dc.create_time,\n" +
|
||||
" dc.update_time,\n" +
|
||||
" dc.sub_count,\n" +
|
||||
@ -60,7 +61,7 @@ public class DeviceChannelProvider {
|
||||
public String queryChannels(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(getBaseSelectSql());
|
||||
sqlBuild.append(" where dc.device_db_id = #{deviceDbId} ");
|
||||
sqlBuild.append(" where data_type = " + ChannelDataType.GB28181.value + " and dc.data_device_id = #{dataDeviceId} ");
|
||||
if (params.get("businessGroupId") != null ) {
|
||||
sqlBuild.append(" AND coalesce(dc.gb_business_group_id, dc.business_group_id)=#{businessGroupId} AND coalesce(dc.gb_parent_id, dc.parent_id) is null");
|
||||
}else if (params.get("parentChannelId") != null ) {
|
||||
@ -107,14 +108,14 @@ public class DeviceChannelProvider {
|
||||
public String queryChannelsByDeviceDbId(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(getBaseSelectSql());
|
||||
sqlBuild.append(" where dc.device_db_id = #{deviceDbId}");
|
||||
sqlBuild.append(" where data_type = " + ChannelDataType.GB28181.value + " and dc.data_device_id = #{dataDeviceId}");
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
|
||||
public String queryAllChannels(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(getBaseSelectSql());
|
||||
sqlBuild.append(" where dc.device_db_id = #{deviceDbId}");
|
||||
sqlBuild.append(" where data_type = " + ChannelDataType.GB28181.value + " and dc.data_device_id = #{dataDeviceId}");
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
|
||||
@ -128,33 +129,25 @@ public class DeviceChannelProvider {
|
||||
public String getOneByDeviceId(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(getBaseSelectSql());
|
||||
sqlBuild.append(" where dc.device_db_id=#{deviceDbId} and coalesce(dc.gb_device_id, dc.device_id) = #{channelId}");
|
||||
sqlBuild.append(" where data_type = " + ChannelDataType.GB28181.value + " and dc.data_device_id=#{dataDeviceId} and coalesce(dc.gb_device_id, dc.device_id) = #{channelId}");
|
||||
return sqlBuild.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String queryByDeviceId(Map<String, Object> params ){
|
||||
return getBaseSelectSql() + " where channel_type = 0 and coalesce(gb_device_id, device_id) = #{gbDeviceId}";
|
||||
return getBaseSelectSql() + " where data_type = " + ChannelDataType.GB28181.value + " and channel_type = 0 and coalesce(gb_device_id, device_id) = #{gbDeviceId}";
|
||||
}
|
||||
|
||||
public String queryById(Map<String, Object> params ){
|
||||
return getBaseSelectSql() + " where channel_type = 0 and id = #{gbId}";
|
||||
}
|
||||
|
||||
public String queryByStreamPushId(Map<String, Object> params ){
|
||||
return getBaseSelectSql() + " where channel_type = 0 and stream_push_id = #{streamPushId}";
|
||||
}
|
||||
|
||||
public String queryByStreamProxyId(Map<String, Object> params ){
|
||||
return getBaseSelectSql() + " where channel_type = 0 and stream_proxy_id = #{streamProxyId}";
|
||||
return getBaseSelectSql() + " where data_type = " + ChannelDataType.GB28181.value + " and channel_type = 0 and id = #{gbId}";
|
||||
}
|
||||
|
||||
|
||||
public String queryList(Map<String, Object> params ){
|
||||
StringBuilder sqlBuild = new StringBuilder();
|
||||
sqlBuild.append(getBaseSelectSql());
|
||||
sqlBuild.append(" where channel_type = 0 ");
|
||||
sqlBuild.append(" where channel_type = 0 and data_type = " + ChannelDataType.GB28181.value);
|
||||
if (params.get("query") != null) {
|
||||
sqlBuild.append(" AND (coalesce(gb_device_id, device_id) LIKE concat('%',#{query},'%')" +
|
||||
" OR coalesce(gb_name, name) LIKE concat('%',#{query},'%') )")
|
||||
|
||||
@ -1,19 +1,21 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.device.RequestTimeoutEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent;
|
||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent;
|
||||
import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.TimeoutEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -29,7 +31,13 @@ public class EventPublisher {
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private IRedisRpcService redisRpcService;
|
||||
|
||||
/**
|
||||
* 设备报警事件
|
||||
* @param deviceAlarm
|
||||
@ -53,27 +61,25 @@ public class EventPublisher {
|
||||
}
|
||||
|
||||
|
||||
public void catalogEventPublish(Integer platformId, CommonGBChannel deviceChannel, String type) {
|
||||
public void catalogEventPublish(Platform platform, CommonGBChannel deviceChannel, String type) {
|
||||
List<CommonGBChannel> deviceChannelList = new ArrayList<>();
|
||||
deviceChannelList.add(deviceChannel);
|
||||
catalogEventPublish(platformId, deviceChannelList, type);
|
||||
catalogEventPublish(platform, deviceChannelList, type);
|
||||
}
|
||||
|
||||
|
||||
public void requestTimeOut(TimeoutEvent timeoutEvent) {
|
||||
RequestTimeoutEvent requestTimeoutEvent = new RequestTimeoutEvent(this);
|
||||
requestTimeoutEvent.setTimeoutEvent(timeoutEvent);
|
||||
applicationEventPublisher.publishEvent(requestTimeoutEvent);
|
||||
public void catalogEventPublish(Platform platform, List<CommonGBChannel> deviceChannels, String type) {
|
||||
catalogEventPublish(platform, deviceChannels, type, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param platformId
|
||||
* @param deviceChannels
|
||||
* @param type
|
||||
*/
|
||||
public void catalogEventPublish(Integer platformId, List<CommonGBChannel> deviceChannels, String type) {
|
||||
public void catalogEventPublish(Platform platform, List<CommonGBChannel> deviceChannels, String type, boolean share) {
|
||||
if (platform != null && !userSetting.getServerId().equals(platform.getServerId())) {
|
||||
// 指定了上级平台的推送,则发送到指定的设备,未指定的则全部发送, 接收后各自处理自己的
|
||||
CatalogEvent outEvent = new CatalogEvent(this);
|
||||
outEvent.setChannels(deviceChannels);
|
||||
outEvent.setType(type);
|
||||
outEvent.setPlatform(platform);
|
||||
redisRpcService.catalogEventPublish(platform.getServerId(), outEvent);
|
||||
return;
|
||||
}
|
||||
CatalogEvent outEvent = new CatalogEvent(this);
|
||||
List<CommonGBChannel> channels = new ArrayList<>();
|
||||
if (deviceChannels.size() > 1) {
|
||||
@ -90,20 +96,19 @@ public class EventPublisher {
|
||||
}
|
||||
outEvent.setChannels(channels);
|
||||
outEvent.setType(type);
|
||||
outEvent.setPlatformId(platformId);
|
||||
outEvent.setPlatform(platform);
|
||||
applicationEventPublisher.publishEvent(outEvent);
|
||||
if (platform == null && share) {
|
||||
// 如果没指定上级平台,则推送消息到所有在线的wvp处理自己含有的平台的目录更新
|
||||
redisRpcService.catalogEventPublish(null, outEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void mobilePositionEventPublish(MobilePosition mobilePosition) {
|
||||
MobilePositionEvent event = new MobilePositionEvent(this);
|
||||
event.setMobilePosition(mobilePosition);
|
||||
applicationEventPublisher.publishEvent(event);
|
||||
}
|
||||
|
||||
public void recordEndEventPush(RecordInfo recordInfo) {
|
||||
RecordEndEvent outEvent = new RecordEndEvent(this);
|
||||
outEvent.setRecordInfo(recordInfo);
|
||||
applicationEventPublisher.publishEvent(outEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
73
src/main/java/com/genersoft/iot/vmp/gb28181/event/MessageSubscribe.java
Executable file
73
src/main/java/com/genersoft/iot/vmp/gb28181/event/MessageSubscribe.java
Executable file
@ -0,0 +1,73 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.event.sip.MessageEvent;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.DelayQueue;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MessageSubscribe {
|
||||
|
||||
private final Map<String, MessageEvent<?>> subscribes = new ConcurrentHashMap<>();
|
||||
|
||||
private final DelayQueue<MessageEvent<?>> delayQueue = new DelayQueue<>();
|
||||
|
||||
@Scheduled(fixedDelay = 200) //每200毫秒执行
|
||||
public void execute(){
|
||||
while (!delayQueue.isEmpty()) {
|
||||
try {
|
||||
MessageEvent<?> take = delayQueue.take();
|
||||
// 出现超时异常
|
||||
if(take.getCallback() != null) {
|
||||
take.getCallback().run(ErrorCode.ERROR486.getCode(), "消息超时未回复", null);
|
||||
}
|
||||
subscribes.remove(take.getKey());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addSubscribe(MessageEvent<?> event) {
|
||||
MessageEvent<?> messageEvent = subscribes.get(event.getKey());
|
||||
if (messageEvent != null) {
|
||||
subscribes.remove(event.getKey());
|
||||
delayQueue.remove(messageEvent);
|
||||
}
|
||||
subscribes.put(event.getKey(), event);
|
||||
delayQueue.offer(event);
|
||||
}
|
||||
|
||||
public MessageEvent<?> getSubscribe(String key) {
|
||||
return subscribes.get(key);
|
||||
}
|
||||
|
||||
public void removeSubscribe(String key) {
|
||||
if(key == null){
|
||||
return;
|
||||
}
|
||||
MessageEvent<?> messageEvent = subscribes.get(key);
|
||||
if (messageEvent != null) {
|
||||
subscribes.remove(key);
|
||||
delayQueue.remove(messageEvent);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty(){
|
||||
return subscribes.isEmpty();
|
||||
}
|
||||
|
||||
public Integer size() {
|
||||
return subscribes.size();
|
||||
}
|
||||
}
|
||||
@ -29,24 +29,24 @@ public class SipSubscribe {
|
||||
|
||||
private final DelayQueue<SipEvent> delayQueue = new DelayQueue<>();
|
||||
|
||||
|
||||
@Scheduled(fixedDelay = 200) //每200毫秒执行
|
||||
public void execute(){
|
||||
if (delayQueue.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
SipEvent take = delayQueue.take();
|
||||
// 出现超时异常
|
||||
if(take.getErrorEvent() != null) {
|
||||
EventResult<Object> eventResult = new EventResult<>();
|
||||
eventResult.type = EventResultType.timeout;
|
||||
eventResult.msg = "消息超时未回复";
|
||||
eventResult.statusCode = -1024;
|
||||
take.getErrorEvent().response(eventResult);
|
||||
while (!delayQueue.isEmpty()) {
|
||||
try {
|
||||
SipEvent take = delayQueue.take();
|
||||
// 出现超时异常
|
||||
if(take.getErrorEvent() != null) {
|
||||
EventResult<Object> eventResult = new EventResult<>();
|
||||
eventResult.type = EventResultType.timeout;
|
||||
eventResult.msg = "消息超时未回复";
|
||||
eventResult.statusCode = -1024;
|
||||
take.getErrorEvent().response(eventResult);
|
||||
}
|
||||
subscribes.remove(take.getKey());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
subscribes.remove(take.getKey());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +78,9 @@ public class SipSubscribe {
|
||||
// 消息发送失败
|
||||
cmdSendFailEvent,
|
||||
// 消息发送失败
|
||||
failedToGetPort
|
||||
failedToGetPort,
|
||||
// 收到失败的回复
|
||||
failedResult
|
||||
}
|
||||
|
||||
public static class EventResult<EventObject>{
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.device;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import javax.sip.TimeoutEvent;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
public class RequestTimeoutEvent extends ApplicationEvent {
|
||||
public RequestTimeoutEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
|
||||
private TimeoutEvent timeoutEvent;
|
||||
|
||||
public TimeoutEvent getTimeoutEvent() {
|
||||
return timeoutEvent;
|
||||
}
|
||||
|
||||
public void setTimeoutEvent(TimeoutEvent timeoutEvent) {
|
||||
this.timeoutEvent = timeoutEvent;
|
||||
}
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.device;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.ClientTransaction;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Component
|
||||
public class RequestTimeoutEventImpl implements ApplicationListener<RequestTimeoutEvent> {
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(RequestTimeoutEvent event) {
|
||||
ClientTransaction clientTransaction = event.getTimeoutEvent().getClientTransaction();
|
||||
if (clientTransaction != null) {
|
||||
Request request = clientTransaction.getRequest();
|
||||
if (request != null) {
|
||||
String host = ((SipURI) request.getRequestURI()).getHost();
|
||||
int port = ((SipURI) request.getRequestURI()).getPort();
|
||||
Device device = deviceService.getDeviceByHostAndPort(host, port);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
deviceService.offline(device.getDeviceId(), "等待消息超时");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,8 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.record;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
@ -9,24 +10,18 @@ import org.springframework.context.ApplicationEvent;
|
||||
* @author: pan
|
||||
* @data: 2022-02-23
|
||||
*/
|
||||
|
||||
public class RecordEndEvent extends ApplicationEvent {
|
||||
@Setter
|
||||
@Getter
|
||||
public class RecordInfoEndEvent extends ApplicationEvent {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public RecordEndEvent(Object source) {
|
||||
public RecordInfoEndEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
private RecordInfo recordInfo;
|
||||
|
||||
public RecordInfo getRecordInfo() {
|
||||
return recordInfo;
|
||||
}
|
||||
|
||||
public void setRecordInfo(RecordInfo recordInfo) {
|
||||
this.recordInfo = recordInfo;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.record;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @description: 录像查询结束时间
|
||||
* @author: pan
|
||||
* @data: 2022-02-23
|
||||
*/
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class RecordInfoEvent extends ApplicationEvent {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public RecordInfoEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
private RecordInfo recordInfo;
|
||||
}
|
||||
@ -15,15 +15,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RecordEndEventListener implements ApplicationListener<RecordEndEvent> {
|
||||
public class RecordInfoEventListener implements ApplicationListener<RecordInfoEvent> {
|
||||
|
||||
private Map<String, RecordEndEventHandler> handlerMap = new ConcurrentHashMap<>();
|
||||
private final Map<String, RecordEndEventHandler> handlerMap = new ConcurrentHashMap<>();
|
||||
public interface RecordEndEventHandler{
|
||||
void handler(RecordInfo recordInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(RecordEndEvent event) {
|
||||
public void onApplicationEvent(RecordInfoEvent event) {
|
||||
String deviceId = event.getRecordInfo().getDeviceId();
|
||||
String channelId = event.getRecordInfo().getChannelId();
|
||||
int count = event.getRecordInfo().getCount();
|
||||
@ -45,9 +45,6 @@ public class RecordEndEventListener implements ApplicationListener<RecordEndEven
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param device
|
||||
* @param channelId
|
||||
* @param recordEndEventHandler
|
||||
*/
|
||||
public void addEndEventHandler(String device, String channelId, RecordEndEventHandler recordEndEventHandler) {
|
||||
log.info("录像查询事件添加监听,deviceId:{}, channelId: {}", device, channelId);
|
||||
@ -55,8 +52,6 @@ public class RecordEndEventListener implements ApplicationListener<RecordEndEven
|
||||
}
|
||||
/**
|
||||
* 添加
|
||||
* @param device
|
||||
* @param channelId
|
||||
*/
|
||||
public void delEndEventHandler(String device, String channelId) {
|
||||
log.info("录像查询事件移除监听,deviceId:{}, channelId: {}", device, channelId);
|
||||
@ -0,0 +1,56 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.sip;
|
||||
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import lombok.Data;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Data
|
||||
public class MessageEvent<T> implements Delayed {
|
||||
/**
|
||||
* 超时时间(单位: 毫秒)
|
||||
*/
|
||||
private long delay;
|
||||
|
||||
private String cmdType;
|
||||
|
||||
private String sn;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String result;
|
||||
|
||||
private T t;
|
||||
|
||||
private ErrorCallback<T> callback;
|
||||
|
||||
@Override
|
||||
public long getDelay(@NotNull TimeUnit unit) {
|
||||
return unit.convert(delay - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull Delayed o) {
|
||||
return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
public String getKey(){
|
||||
return cmdType + sn;
|
||||
}
|
||||
|
||||
public static <T> MessageEvent<T> getInstance(String cmdType, String sn, String deviceId, Long delay, ErrorCallback<T> callback){
|
||||
MessageEvent<T> messageEvent = new MessageEvent<>();
|
||||
messageEvent.cmdType = cmdType;
|
||||
messageEvent.sn = sn;
|
||||
messageEvent.deviceId = deviceId;
|
||||
messageEvent.callback = callback;
|
||||
if (delay == null) {
|
||||
messageEvent.delay = System.currentTimeMillis() + 1000;
|
||||
}else {
|
||||
messageEvent.delay = System.currentTimeMillis() + delay;
|
||||
}
|
||||
return messageEvent;
|
||||
}
|
||||
}
|
||||
@ -32,13 +32,13 @@ public class SipEvent implements Delayed {
|
||||
sipEvent.setKey(key);
|
||||
sipEvent.setOkEvent(okEvent);
|
||||
sipEvent.setErrorEvent(errorEvent);
|
||||
sipEvent.setDelay(delay);
|
||||
sipEvent.setDelay(System.currentTimeMillis() + delay);
|
||||
return sipEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay(@NotNull TimeUnit unit) {
|
||||
return unit.convert(delay, TimeUnit.MILLISECONDS);
|
||||
return unit.convert(delay - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.subscribe.catalog;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class CatalogEvent extends ApplicationEvent {
|
||||
|
||||
public CatalogEvent(Object source) {
|
||||
@ -48,16 +51,10 @@ public class CatalogEvent extends ApplicationEvent {
|
||||
*/
|
||||
public static final String UPDATE = "UPDATE";
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private List<CommonGBChannel> channels;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private String type;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private Integer platformId;
|
||||
private Platform platform;
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.event.subscribe.catalog;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder;
|
||||
@ -7,6 +8,7 @@ import com.genersoft.iot.vmp.gb28181.bean.SubscribeInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
@ -15,10 +17,7 @@ import org.springframework.stereotype.Component;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* catalog事件
|
||||
@ -30,9 +29,6 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
||||
@Autowired
|
||||
private IPlatformChannelService platformChannelService;
|
||||
|
||||
@Autowired
|
||||
private IPlatformService platformService;
|
||||
|
||||
@Autowired
|
||||
private ISIPCommanderForPlatform sipCommanderFroPlatform;
|
||||
|
||||
@ -46,11 +42,8 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
||||
|
||||
Map<String, List<Platform>> parentPlatformMap = new HashMap<>();
|
||||
Map<String, CommonGBChannel> channelMap = new HashMap<>();
|
||||
if (event.getPlatformId() != null) {
|
||||
parentPlatform = platformService.queryOne(event.getPlatformId());
|
||||
if (parentPlatform == null) {
|
||||
return;
|
||||
}
|
||||
if (event.getPlatform() != null) {
|
||||
parentPlatform = event.getPlatform();
|
||||
subscribe = subscribeHolder.getCatalogSubscribe(parentPlatform.getServerGBId());
|
||||
if (subscribe == null) {
|
||||
return;
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.common.enums.DeviceControlType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
||||
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelReduce;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
|
||||
import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.dom4j.Element;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -125,4 +130,11 @@ public interface IDeviceChannelService {
|
||||
List<DeviceChannel> queryChaneListByDeviceDbId(Integer deviceDbId);
|
||||
|
||||
List<Integer> queryChaneIdListByDeviceDbIds(List<Integer> deviceDbId);
|
||||
|
||||
void handlePtzCmd(@NotNull Integer dataDeviceId, @NotNull Integer gbId, Element rootElement, DeviceControlType type, ErrorCallback<String> callback);
|
||||
|
||||
void queryRecordInfo(Device device, DeviceChannel channel, String startTime, String endTime, ErrorCallback<RecordInfo> object);
|
||||
|
||||
void queryRecordInfo(CommonGBChannel channel, String startTime, String endTime, ErrorCallback<RecordInfo> object);
|
||||
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service;
|
||||
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SyncStatus;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import java.util.List;
|
||||
@ -86,7 +86,7 @@ public interface IDeviceService {
|
||||
* 获取所有在线设备
|
||||
* @return 设备列表
|
||||
*/
|
||||
List<Device> getAllOnlineDevice();
|
||||
List<Device> getAllOnlineDevice(String serverId);
|
||||
|
||||
List<Device> getAllByStatus(Boolean status);
|
||||
|
||||
@ -101,7 +101,7 @@ public interface IDeviceService {
|
||||
* 检查设备状态
|
||||
* @param device 设备信息
|
||||
*/
|
||||
void checkDeviceStatus(Device device);
|
||||
Boolean getDeviceStatus(Device device);
|
||||
|
||||
/**
|
||||
* 根据IP和端口获取设备信息
|
||||
@ -161,4 +161,40 @@ public interface IDeviceService {
|
||||
Device getDeviceByChannelId(Integer channelId);
|
||||
|
||||
Device getDeviceBySourceChannelDeviceId(String requesterId);
|
||||
|
||||
void subscribeCatalog(int id, int cycle);
|
||||
|
||||
void subscribeMobilePosition(int id, int cycle, int interval);
|
||||
|
||||
WVPResult<SyncStatus> devicesSync(Device device);
|
||||
|
||||
void deviceBasicConfig(Device device, BasicParam basicParam, ErrorCallback<String> callback);
|
||||
|
||||
void deviceConfigQuery(Device device, String channelId, String configType, ErrorCallback<Object> callback);
|
||||
|
||||
void teleboot(Device device);
|
||||
|
||||
void record(Device device, String channelId, String recordCmdStr, ErrorCallback<String> callback);
|
||||
|
||||
void guard(Device device, String guardCmdStr, ErrorCallback<String> callback);
|
||||
|
||||
void resetAlarm(Device device, String channelId, String alarmMethod, String alarmType, ErrorCallback<String> callback);
|
||||
|
||||
void iFrame(Device device, String channelId);
|
||||
|
||||
void homePosition(Device device, String channelId, Boolean enabled, Integer resetTime, Integer presetIndex, ErrorCallback<String> callback);
|
||||
|
||||
void dragZoomIn(Device device, String channelId, int length, int width, int midpointx, int midpointy, int lengthx, int lengthy, ErrorCallback<String> callback);
|
||||
|
||||
void dragZoomOut(Device device, String channelId, int length, int width, int midpointx, int midpointy, int lengthx, int lengthy, ErrorCallback<String> callback);
|
||||
|
||||
void deviceStatus(Device device, ErrorCallback<String> callback);
|
||||
|
||||
void updateDeviceHeartInfo(Device device);
|
||||
|
||||
void alarm(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime, ErrorCallback<Object> callback);
|
||||
|
||||
void deviceInfo(Device device, ErrorCallback<Object> callback);
|
||||
|
||||
void queryPreset(Device device, String channelId, ErrorCallback<Object> callback);
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.FrontEndControlCodeForPTZ;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
|
||||
public interface IGbChannelControlService {
|
||||
|
||||
|
||||
void ptz(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback);
|
||||
void fi(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback);
|
||||
void preset(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback);
|
||||
void tour(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback);
|
||||
void scan(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback);
|
||||
void auxiliary(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback);
|
||||
}
|
||||
@ -1,20 +1,33 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service;
|
||||
|
||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.InviteInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.InviteMessageInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
|
||||
public interface IGbChannelPlayService {
|
||||
|
||||
void start(CommonGBChannel channel, InviteInfo inviteInfo, Platform platform, ErrorCallback<StreamInfo> callback);
|
||||
void start(CommonGBChannel channel, InviteMessageInfo inviteInfo, Platform platform, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void play(CommonGBChannel channel, Platform platform, ErrorCallback<StreamInfo> callback);
|
||||
void stopPlay(InviteSessionType type, CommonGBChannel channel, String stream);
|
||||
|
||||
void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
||||
void play(CommonGBChannel channel, Platform platform, Boolean record, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void playProxy(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
||||
void playGbDeviceChannel(CommonGBChannel channel, Boolean record, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void stopPlayDeviceChannel(InviteSessionType type, CommonGBChannel channel, String stream);
|
||||
|
||||
void playProxy(CommonGBChannel channel, Boolean record, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void stopPlayProxy(CommonGBChannel channel);
|
||||
|
||||
void playPush(CommonGBChannel channel, String platformDeviceId, String platformName, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void stopPlayPush(CommonGBChannel channel);
|
||||
|
||||
void pauseRtp(String streamId);
|
||||
|
||||
void resumeRtp(String streamId);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
@ -87,4 +88,13 @@ public interface IGbChannelService {
|
||||
|
||||
PageInfo<CommonGBChannel> queryList(int page, int count, String query, Boolean online, Boolean hasRecordPlan, Integer channelType);
|
||||
|
||||
void queryRecordInfo(CommonGBChannel channel, String startTime, String endTime, ErrorCallback<RecordInfo> callback);
|
||||
|
||||
PageInfo<CommonGBChannel> queryListByCivilCodeForUnusual(int page, int count, String query, Boolean online, Integer channelType);
|
||||
|
||||
void clearChannelCivilCode(Boolean all, List<Integer> channelIds);
|
||||
|
||||
PageInfo<CommonGBChannel> queryListByParentForUnusual(int page, int count, String query, Boolean online, Integer channelType);
|
||||
|
||||
void clearChannelParent(Boolean all, List<Integer> channelIds);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service;
|
||||
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Preset;
|
||||
|
||||
@ -18,4 +19,6 @@ public interface IPTZService {
|
||||
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);
|
||||
|
||||
void frontEndCommand(CommonGBChannel channel, Integer cmdCode, Integer parameter1, Integer parameter2, Integer combindCode2);
|
||||
}
|
||||
|
||||
@ -43,6 +43,8 @@ public interface IPlatformChannelService {
|
||||
|
||||
CommonGBChannel queryChannelByPlatformIdAndChannelId(Integer platformId, Integer channelId);
|
||||
|
||||
List<CommonGBChannel> queryChannelByPlatformIdAndChannelIds(Integer platformId, List<Integer> channelIds);
|
||||
|
||||
void checkRegionAdd(List<CommonGBChannel> channelList);
|
||||
|
||||
void checkRegionRemove(List<CommonGBChannel> channelList, List<Region> regionList);
|
||||
|
||||
@ -69,25 +69,20 @@ public interface IPlatformService {
|
||||
|
||||
/**
|
||||
* 向上级发送语音喊话的消息
|
||||
* @param platform 平台
|
||||
* @param channelId 通道
|
||||
* @param hookEvent hook事件
|
||||
* @param errorEvent 信令错误事件
|
||||
* @param timeoutCallback 超时事件
|
||||
*/
|
||||
void broadcastInvite(Platform platform, CommonGBChannel channelId, MediaServer mediaServerItem, HookSubscribe.Event hookEvent,
|
||||
void broadcastInvite(Platform platform, CommonGBChannel channel, String sourceId, MediaServer mediaServerItem, HookSubscribe.Event hookEvent,
|
||||
SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback) throws InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
/**
|
||||
* 语音喊话回复BYE
|
||||
*/
|
||||
void stopBroadcast(Platform platform, CommonGBChannel channel, String stream, boolean sendBye, MediaServer mediaServerItem);
|
||||
void stopBroadcast(Platform platform, CommonGBChannel channel, String app, String stream, boolean sendBye, MediaServer mediaServerItem);
|
||||
|
||||
void addSimulatedSubscribeInfo(Platform parentPlatform);
|
||||
|
||||
Platform queryOne(Integer platformId);
|
||||
|
||||
List<Platform> queryEnablePlatformList();
|
||||
List<Platform> queryEnablePlatformList(String serverId);
|
||||
|
||||
void delete(Integer platformId, CommonCallback<Object> callback);
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ public interface IPlayService {
|
||||
|
||||
SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void play(Device device, DeviceChannel channel, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, Device device, DeviceChannel channel);
|
||||
|
||||
MediaServer getNewMediaServerItem(Device device);
|
||||
@ -38,7 +40,7 @@ public interface IPlayService {
|
||||
|
||||
void zlmServerOnline(MediaServer mediaServer);
|
||||
|
||||
AudioBroadcastResult audioBroadcast(Device device, DeviceChannel deviceChannel, Boolean broadcastMode);
|
||||
AudioBroadcastResult audioBroadcast(String deviceId, String channelDeviceId, Boolean broadcastMode);
|
||||
|
||||
boolean audioBroadcastCmd(Device device, DeviceChannel channel, MediaServer mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
@ -64,10 +66,14 @@ public interface IPlayService {
|
||||
|
||||
void stop(InviteInfo inviteInfo);
|
||||
|
||||
void play(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
||||
void play(CommonGBChannel channel, Boolean record, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void stop(InviteSessionType inviteSessionType, CommonGBChannel channel, String stream);
|
||||
|
||||
void playBack(CommonGBChannel channel, Long startTime, Long stopTime, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
void download(CommonGBChannel channel, Long startTime, Long stopTime, Integer downloadSpeed, ErrorCallback<StreamInfo> callback);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -36,4 +36,8 @@ public interface IRegionService {
|
||||
boolean batchAdd(List<Region> regionList);
|
||||
|
||||
List<Region> getPath(String deviceId);
|
||||
|
||||
String getDescription(String civilCode);
|
||||
|
||||
void addByCivilCode(String civilCode);
|
||||
}
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceAlarmService;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.DeviceAlarmMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceAlarmService;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -12,7 +11,6 @@ import org.springframework.stereotype.Service;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@DS("master")
|
||||
public class DeviceAlarmServiceImpl implements IDeviceAlarmService {
|
||||
|
||||
@Autowired
|
||||
|
||||
@ -1,26 +1,29 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.common.enums.DeviceControlType;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.GbCode;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.MobilePosition;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelReduce;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.DeviceChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.DeviceMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.DeviceMobilePositionMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.PlatformChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.record.RecordInfoEndEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcPlayService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
@ -29,21 +32,35 @@ import com.genersoft.iot.vmp.web.gb28181.dto.DeviceChannelExtend;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dom4j.Element;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import java.text.ParseException;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Response;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@DS("master")
|
||||
public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
|
||||
@Autowired
|
||||
@ -73,6 +90,30 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
@Autowired
|
||||
private IPlatformChannelService platformChannelService;
|
||||
|
||||
@Autowired
|
||||
private IRedisRpcPlayService redisRpcPlayService;
|
||||
|
||||
@Autowired
|
||||
private ISIPCommander commander;
|
||||
|
||||
// 记录录像查询的结果等待
|
||||
private final Map<String, SynchronousQueue<RecordInfo>> topicSubscribers = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 监听录像查询结束事件
|
||||
*/
|
||||
@Async("taskExecutor")
|
||||
@org.springframework.context.event.EventListener
|
||||
public void onApplicationEvent(RecordInfoEndEvent event) {
|
||||
SynchronousQueue<RecordInfo> queue = topicSubscribers.get("record" + event.getRecordInfo().getSn());
|
||||
if (queue != null) {
|
||||
queue.offer(event.getRecordInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ISIPCommander cmder;
|
||||
|
||||
|
||||
@Override
|
||||
public int updateChannels(Device device, List<DeviceChannel> channels) {
|
||||
@ -84,7 +125,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
List<DeviceChannel> channelList = channelMapper.queryChannelsByDeviceDbId(device.getId());
|
||||
if (channelList.isEmpty()) {
|
||||
for (DeviceChannel channel : channels) {
|
||||
channel.setDeviceDbId(device.getId());
|
||||
channel.setDataDeviceId(device.getId());
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
||||
if (inviteInfo != null && inviteInfo.getStreamInfo() != null) {
|
||||
channel.setStreamId(inviteInfo.getStreamInfo().getStream());
|
||||
@ -96,7 +137,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
}
|
||||
}else {
|
||||
for (DeviceChannel deviceChannel : channelList) {
|
||||
channelsInStore.put(deviceChannel.getDeviceDbId() + deviceChannel.getDeviceId(), deviceChannel);
|
||||
channelsInStore.put(deviceChannel.getDataDeviceId() + deviceChannel.getDeviceId(), deviceChannel);
|
||||
}
|
||||
for (DeviceChannel channel : channels) {
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
||||
@ -105,7 +146,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
}
|
||||
String now = DateUtil.getNow();
|
||||
channel.setUpdateTime(now);
|
||||
DeviceChannel deviceChannelInDb = channelsInStore.get(channel.getDeviceDbId() + channel.getDeviceId());
|
||||
DeviceChannel deviceChannelInDb = channelsInStore.get(channel.getDataDeviceId() + channel.getDeviceId());
|
||||
if ( deviceChannelInDb != null) {
|
||||
channel.setId(deviceChannelInDb.getId());
|
||||
channel.setUpdateTime(now);
|
||||
@ -166,10 +207,8 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
|
||||
@Override
|
||||
public ResourceBaseInfo getOverview() {
|
||||
|
||||
int online = channelMapper.getOnlineCount();
|
||||
int total = channelMapper.getAllChannelCount();
|
||||
|
||||
return new ResourceBaseInfo(total, online);
|
||||
}
|
||||
|
||||
@ -324,7 +363,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
}
|
||||
for (DeviceChannel channel : channels) {
|
||||
if (channel.getParentId() != null) {
|
||||
channelMapper.updateChannelSubCount(channel.getDeviceDbId(), channel.getParentId());
|
||||
channelMapper.updateChannelSubCount(channel.getDataDeviceId(), channel.getParentId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -364,6 +403,39 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
return channelMapper.queryChaneIdListByDeviceDbIds(deviceDbIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePtzCmd(@NotNull Integer dataDeviceId, @NotNull Integer gbId, Element rootElement, DeviceControlType type, ErrorCallback<String> callback) {
|
||||
|
||||
// 根据通道ID,获取所属设备
|
||||
Device device = deviceMapper.query(dataDeviceId);
|
||||
if (device == null) {
|
||||
// 不存在则回复404
|
||||
log.warn("[INFO 消息] 通道所属设备不存在, 设备ID: {}", dataDeviceId);
|
||||
callback.run(Response.NOT_FOUND, "device not found", null);
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceChannel deviceChannel = channelMapper.getOneForSource(gbId);
|
||||
if (deviceChannel == null) {
|
||||
log.warn("[deviceControl] 未找到设备原始通道, 设备: {}({}),通道编号:{}", device.getName(),
|
||||
device.getDeviceId(), gbId);
|
||||
callback.run(Response.NOT_FOUND, "channel not found", null);
|
||||
return;
|
||||
}
|
||||
log.info("[deviceControl] 命令: {}, 设备: {}({}), 通道{}({}", type, device.getName(), device.getDeviceId(),
|
||||
deviceChannel.getName(), deviceChannel.getDeviceId());
|
||||
String cmdString = getText(rootElement, type.getVal());
|
||||
try {
|
||||
cmder.fronEndCmd(device, deviceChannel.getDeviceId(), cmdString, errorResult->{
|
||||
callback.run(errorResult.statusCode, errorResult.msg, null);
|
||||
}, errorResult->{
|
||||
callback.run(errorResult.statusCode, errorResult.msg, null);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 云台/前端: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateChannelGPS(Device device, DeviceChannel deviceChannel, MobilePosition mobilePosition) {
|
||||
if (userSetting.getSavePositionHistory()) {
|
||||
@ -487,7 +559,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
Map<String,DeviceChannel> allChannelMap = new HashMap<>();
|
||||
if (!allChannels.isEmpty()) {
|
||||
for (DeviceChannel deviceChannel : allChannels) {
|
||||
allChannelMap.put(deviceChannel.getDeviceDbId() + deviceChannel.getDeviceId(), deviceChannel);
|
||||
allChannelMap.put(deviceChannel.getDataDeviceId() + deviceChannel.getDeviceId(), deviceChannel);
|
||||
}
|
||||
}
|
||||
// 数据去重
|
||||
@ -500,16 +572,16 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
Map<String, Integer> subContMap = new HashMap<>();
|
||||
|
||||
for (DeviceChannel deviceChannel : deviceChannelList) {
|
||||
DeviceChannel channelInDb = allChannelMap.get(deviceChannel.getDeviceDbId() + deviceChannel.getDeviceId());
|
||||
DeviceChannel channelInDb = allChannelMap.get(deviceChannel.getDataDeviceId() + deviceChannel.getDeviceId());
|
||||
if (channelInDb != null) {
|
||||
deviceChannel.setStreamId(channelInDb.getStreamId());
|
||||
deviceChannel.setHasAudio(channelInDb.isHasAudio());
|
||||
deviceChannel.setId(channelInDb.getId());
|
||||
if (channelInDb.getStatus() != null && channelInDb.getStatus().equalsIgnoreCase(deviceChannel.getStatus())){
|
||||
List<Integer> ids = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getDeviceId());
|
||||
if (!CollectionUtils.isEmpty(ids)){
|
||||
ids.forEach(platformId->{
|
||||
eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.getStatus().equals("ON")? CatalogEvent.ON:CatalogEvent.OFF);
|
||||
List<Platform> platformList = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getDeviceId());
|
||||
if (!CollectionUtils.isEmpty(platformList)){
|
||||
platformList.forEach(platform->{
|
||||
eventPublisher.catalogEventPublish(platform, deviceChannel.buildCommonGBChannelForStatus(), deviceChannel.getStatus().equals("ON")? CatalogEvent.ON:CatalogEvent.OFF);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -520,7 +592,7 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
deviceChannel.setUpdateTime(DateUtil.getNow());
|
||||
addChannels.add(deviceChannel);
|
||||
}
|
||||
allChannelMap.remove(deviceChannel.getDeviceDbId() + deviceChannel.getDeviceId());
|
||||
allChannelMap.remove(deviceChannel.getDataDeviceId() + deviceChannel.getDeviceId());
|
||||
channels.add(deviceChannel);
|
||||
if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
|
||||
if (subContMap.get(deviceChannel.getParentId()) == null) {
|
||||
@ -700,6 +772,8 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
|
||||
@Override
|
||||
public void addChannel(DeviceChannel channel) {
|
||||
channel.setDataType(ChannelDataType.GB28181.value);
|
||||
channel.setDataDeviceId(channel.getDataDeviceId());
|
||||
channelMapper.add(channel);
|
||||
}
|
||||
|
||||
@ -707,4 +781,57 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||
public void updateChannelForNotify(DeviceChannel channel) {
|
||||
channelMapper.updateChannelForNotify(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryRecordInfo(Device device, DeviceChannel channel, String startTime, String endTime, ErrorCallback<RecordInfo> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())){
|
||||
redisRpcPlayService.queryRecordInfo(device.getServerId(), channel.getId(), startTime, endTime, callback);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int sn = (int)((Math.random()*9+1)*100000);
|
||||
commander.recordInfoQuery(device, channel.getDeviceId(), startTime, endTime, sn, null, null, eventResult -> {
|
||||
try {
|
||||
// 消息发送成功, 监听等待数据到来
|
||||
SynchronousQueue<RecordInfo> queue = new SynchronousQueue<>();
|
||||
topicSubscribers.put("record" + sn, queue);
|
||||
RecordInfo recordInfo = queue.poll(userSetting.getRecordInfoTimeout(), TimeUnit.MILLISECONDS);
|
||||
if (recordInfo != null) {
|
||||
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), recordInfo);
|
||||
}else {
|
||||
callback.run(ErrorCode.ERROR100.getCode(), ErrorCode.ERROR100.getMsg(), recordInfo);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
callback.run(ErrorCode.ERROR100.getCode(), e.getMessage(), null);
|
||||
} finally {
|
||||
this.topicSubscribers.remove("record" + sn);
|
||||
}
|
||||
|
||||
}, (eventResult -> {
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "查询录像失败, status: " + eventResult.statusCode + ", message: " + eventResult.msg, null);
|
||||
}));
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 查询录像: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryRecordInfo(CommonGBChannel channel, String startTime, String endTime, ErrorCallback<RecordInfo> callback) {
|
||||
if (channel.getDataType() != ChannelDataType.GB28181.value){
|
||||
// 只支持国标的语音喊话
|
||||
log.warn("[INFO 消息] 非国标设备, 通道ID: {}", channel.getGbId());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "非国标设备", null);
|
||||
return;
|
||||
}
|
||||
Device device = deviceMapper.query(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[点播] 未找到通道{}的设备信息", channel);
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "设备不存在", null);
|
||||
return;
|
||||
}
|
||||
DeviceChannel deviceChannel = getOneForSourceById(channel.getGbId());
|
||||
queryRecordInfo(device, deviceChannel, startTime, endTime, callback);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
@ -11,7 +11,6 @@ import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.DeviceChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.DeviceMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.PlatformChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
||||
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
|
||||
@ -24,22 +23,29 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.respons
|
||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.ISendRtpServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ResourceBaseInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.text.ParseException;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -47,7 +53,6 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@DS("master")
|
||||
public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
@Autowired
|
||||
@ -71,9 +76,6 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Autowired
|
||||
private PlatformChannelMapper platformChannelMapper;
|
||||
|
||||
@Autowired
|
||||
private IDeviceChannelService deviceChannelService;
|
||||
|
||||
@Autowired
|
||||
private DeviceChannelMapper deviceChannelMapper;
|
||||
|
||||
@ -95,11 +97,18 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Autowired
|
||||
private AudioBroadcastManager audioBroadcastManager;
|
||||
|
||||
@Autowired
|
||||
private IRedisRpcService redisRpcService;
|
||||
|
||||
private Device getDeviceByDeviceIdFromDb(String deviceId) {
|
||||
return deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void online(Device device, SipTransactionInfo sipTransactionInfo) {
|
||||
log.info("[设备上线] deviceId:{}->{}:{}", device.getDeviceId(), device.getIp(), device.getPort());
|
||||
Device deviceInRedis = redisCatchStorage.getDevice(device.getDeviceId());
|
||||
Device deviceInDb = deviceMapper.getDeviceByDeviceId(device.getDeviceId());
|
||||
Device deviceInDb = getDeviceByDeviceIdFromDb(device.getDeviceId());
|
||||
|
||||
String now = DateUtil.getNow();
|
||||
if (deviceInRedis != null && deviceInDb == null) {
|
||||
@ -108,9 +117,12 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
}
|
||||
device.setUpdateTime(now);
|
||||
device.setKeepaliveTime(now);
|
||||
if (device.getKeepaliveIntervalTime() == 0) {
|
||||
// 默认心跳间隔60
|
||||
device.setKeepaliveIntervalTime(60);
|
||||
if (device.getHeartBeatCount() == null) {
|
||||
// 读取设备配置, 获取心跳间隔和心跳超时次数, 在次之前暂时设置为默认值
|
||||
device.setHeartBeatCount(3);
|
||||
device.setHeartBeatInterval(60);
|
||||
device.setPositionCapability(0);
|
||||
|
||||
}
|
||||
if (sipTransactionInfo != null) {
|
||||
device.setSipTransactionInfo(sipTransactionInfo);
|
||||
@ -129,7 +141,8 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
deviceMapper.add(device);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
try {
|
||||
commander.deviceInfoQuery(device);
|
||||
commander.deviceInfoQuery(device, null);
|
||||
commander.deviceConfigQuery(device, null, "BasicParam", null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
|
||||
}
|
||||
@ -143,7 +156,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
if (userSetting.getSyncChannelOnDeviceOnline()) {
|
||||
log.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId());
|
||||
try {
|
||||
commander.deviceInfoQuery(device);
|
||||
commander.deviceInfoQuery(device, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 查询设备信息: {}", e.getMessage());
|
||||
}
|
||||
@ -176,28 +189,28 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
// 刷新过期任务
|
||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
||||
// 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
|
||||
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3);
|
||||
|
||||
//
|
||||
// try {
|
||||
// cmder.alarmSubscribe(device, 600, "0", "4", "0", "2023-7-27T00:00:00", "2023-7-28T00:00:00");
|
||||
// } catch (InvalidArgumentException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// } catch (SipException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// } catch (ParseException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "三次心跳超时"),
|
||||
device.getHeartBeatInterval() * 1000 * device.getHeartBeatCount());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void offline(String deviceId, String reason) {
|
||||
log.warn("[设备离线],{}, device:{}", reason, deviceId);
|
||||
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
Device device = getDeviceByDeviceIdFromDb(deviceId);
|
||||
if (device == null) {
|
||||
log.warn("[设备不存在] device:{}", deviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 主动查询设备状态
|
||||
Boolean deviceStatus = getDeviceStatus(device);
|
||||
if (deviceStatus != null && deviceStatus) {
|
||||
log.info("[设备离线] 主动探测发现设备在线,暂不处理 device:{}", deviceId);
|
||||
online(device, null);
|
||||
return;
|
||||
}
|
||||
log.info("[设备离线] {}, device:{}, 心跳间隔: {},心跳超时次数: {}, 上次心跳时间:{}, 上次注册时间: {}", reason, deviceId,
|
||||
device.getHeartBeatInterval(), device.getHeartBeatCount(), device.getKeepaliveTime(), device.getRegisterTime());
|
||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
|
||||
dynamicTask.stop(registerExpireTaskKey);
|
||||
if (device.isOnLine()) {
|
||||
@ -214,7 +227,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
// deviceChannelMapper.offlineByDeviceId(deviceId);
|
||||
// 离线释放所有ssrc
|
||||
List<SsrcTransaction> ssrcTransactions = sessionManager.getSsrcTransactionByDeviceId(deviceId);
|
||||
if (ssrcTransactions != null && ssrcTransactions.size() > 0) {
|
||||
if (ssrcTransactions != null && !ssrcTransactions.isEmpty()) {
|
||||
for (SsrcTransaction ssrcTransaction : ssrcTransactions) {
|
||||
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
|
||||
mediaServerService.closeRTPServer(ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream());
|
||||
@ -261,6 +274,9 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Override
|
||||
public boolean removeCatalogSubscribe(Device device, CommonCallback<Boolean> callback) {
|
||||
if (device == null || device.getSubscribeCycleForCatalog() < 0) {
|
||||
if (callback != null) {
|
||||
callback.run(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
log.info("[移除目录订阅]: {}", device.getDeviceId());
|
||||
@ -270,6 +286,16 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
if (runnable instanceof ISubscribeTask) {
|
||||
ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
|
||||
subscribeTask.stop(callback);
|
||||
}else {
|
||||
log.info("[移除目录订阅]失败,未找到订阅任务 : {}", device.getDeviceId());
|
||||
if (callback != null) {
|
||||
callback.run(false);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
log.info("[移除移动位置订阅]失败,设备已经离线 : {}", device.getDeviceId());
|
||||
if (callback != null) {
|
||||
callback.run(false);
|
||||
}
|
||||
}
|
||||
dynamicTask.stop(taskKey);
|
||||
@ -295,6 +321,9 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Override
|
||||
public boolean removeMobilePositionSubscribe(Device device, CommonCallback<Boolean> callback) {
|
||||
if (device == null || device.getSubscribeCycleForCatalog() < 0) {
|
||||
if (callback != null) {
|
||||
callback.run(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
log.info("[移除移动位置订阅]: {}", device.getDeviceId());
|
||||
@ -304,6 +333,16 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
if (runnable instanceof ISubscribeTask) {
|
||||
ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
|
||||
subscribeTask.stop(callback);
|
||||
}else {
|
||||
log.info("[移除移动位置订阅]失败,未找到订阅任务 : {}", device.getDeviceId());
|
||||
if (callback != null) {
|
||||
callback.run(false);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
log.info("[移除移动位置订阅]失败,设备已经离线 : {}", device.getDeviceId());
|
||||
if (callback != null) {
|
||||
callback.run(false);
|
||||
}
|
||||
}
|
||||
dynamicTask.stop(taskKey);
|
||||
@ -312,6 +351,13 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
@Override
|
||||
public SyncStatus getChannelSyncStatus(String deviceId) {
|
||||
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR404.getCode(), "设备不存在");
|
||||
}
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
return redisRpcService.getChannelSyncStatus(device.getServerId(), deviceId);
|
||||
}
|
||||
return catalogResponseMessageHandler.getChannelSyncProgress(deviceId);
|
||||
}
|
||||
|
||||
@ -346,7 +392,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
public Device getDeviceByDeviceId(String deviceId) {
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
if (device == null) {
|
||||
device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
device = getDeviceByDeviceIdFromDb(deviceId);
|
||||
if (device != null) {
|
||||
redisCatchStorage.updateDevice(device);
|
||||
}
|
||||
@ -355,13 +401,13 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getAllOnlineDevice() {
|
||||
return deviceMapper.getOnlineDevices();
|
||||
public List<Device> getAllOnlineDevice(String serverId) {
|
||||
return deviceMapper.getOnlineDevicesByServerId(serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getAllByStatus(Boolean status) {
|
||||
return deviceMapper.getDevices(status);
|
||||
return deviceMapper.getDevices(ChannelDataType.GB28181.value, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -372,16 +418,23 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkDeviceStatus(Device device) {
|
||||
if (device == null || !device.isOnLine()) {
|
||||
return;
|
||||
}
|
||||
public Boolean getDeviceStatus(@NotNull Device device) {
|
||||
SynchronousQueue<String> queue = new SynchronousQueue<>();
|
||||
try {
|
||||
sipCommander.deviceStatusQuery(device, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
sipCommander.deviceStatusQuery(device, ((code, msg, data) -> {
|
||||
queue.offer(msg);
|
||||
}));
|
||||
String data = queue.poll(10, TimeUnit.SECONDS);
|
||||
if (data != null && "ONLINE".equalsIgnoreCase(data.trim())) {
|
||||
return Boolean.TRUE;
|
||||
}else {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
} catch (InvalidArgumentException | SipException | ParseException | InterruptedException e) {
|
||||
log.error("[命令发送失败] 设备状态查询: {}", e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -403,7 +456,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
@Override
|
||||
public boolean isExist(String deviceId) {
|
||||
return deviceMapper.getDeviceByDeviceId(deviceId) != null;
|
||||
return getDeviceByDeviceIdFromDb(deviceId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -412,71 +465,19 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
device.setCreateTime(DateUtil.getNow());
|
||||
device.setUpdateTime(DateUtil.getNow());
|
||||
if(device.getStreamMode() == null) {
|
||||
device.setStreamMode("UDP");
|
||||
device.setStreamMode("TCP-PASSIVE");
|
||||
}
|
||||
deviceMapper.addCustomDevice(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCustomDevice(Device device) {
|
||||
// 订阅状态的修改使用一个单独方法控制,此处不再进行状态修改
|
||||
Device deviceInStore = deviceMapper.query(device.getId());
|
||||
if (deviceInStore == null) {
|
||||
log.warn("更新设备时未找到设备信息");
|
||||
return;
|
||||
}
|
||||
// 目录订阅相关的信息
|
||||
if (deviceInStore.getSubscribeCycleForCatalog() != device.getSubscribeCycleForCatalog()) {
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
// 若已开启订阅,但订阅周期不同,则先取消
|
||||
if (deviceInStore.getSubscribeCycleForCatalog() != 0) {
|
||||
removeCatalogSubscribe(deviceInStore, result->{
|
||||
// 开启订阅
|
||||
deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
|
||||
addCatalogSubscribe(deviceInStore);
|
||||
// 因为是异步执行,需要在这里更新下数据
|
||||
deviceMapper.updateCustom(deviceInStore);
|
||||
redisCatchStorage.updateDevice(deviceInStore);
|
||||
});
|
||||
}else {
|
||||
// 开启订阅
|
||||
deviceInStore.setSubscribeCycleForCatalog(device.getSubscribeCycleForCatalog());
|
||||
addCatalogSubscribe(deviceInStore);
|
||||
}
|
||||
|
||||
}else if (device.getSubscribeCycleForCatalog() == 0) {
|
||||
// 取消订阅
|
||||
deviceInStore.setSubscribeCycleForCatalog(0);
|
||||
removeCatalogSubscribe(deviceInStore, null);
|
||||
}
|
||||
}
|
||||
// 移动位置订阅相关的信息
|
||||
if (deviceInStore.getSubscribeCycleForMobilePosition() != device.getSubscribeCycleForMobilePosition()) {
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
// 若已开启订阅,但订阅周期不同,则先取消
|
||||
if (deviceInStore.getSubscribeCycleForMobilePosition() != 0) {
|
||||
removeMobilePositionSubscribe(deviceInStore, result->{
|
||||
// 开启订阅
|
||||
deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition());
|
||||
deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval());
|
||||
addMobilePositionSubscribe(deviceInStore);
|
||||
// 因为是异步执行,需要在这里更新下数据
|
||||
deviceMapper.updateCustom(deviceInStore);
|
||||
redisCatchStorage.updateDevice(deviceInStore);
|
||||
});
|
||||
}else {
|
||||
// 开启订阅
|
||||
deviceInStore.setSubscribeCycleForMobilePosition(device.getSubscribeCycleForMobilePosition());
|
||||
deviceInStore.setMobilePositionSubmissionInterval(device.getMobilePositionSubmissionInterval());
|
||||
addMobilePositionSubscribe(deviceInStore);
|
||||
}
|
||||
|
||||
}else if (device.getSubscribeCycleForMobilePosition() == 0) {
|
||||
// 取消订阅
|
||||
deviceInStore.setSubscribeCycleForMobilePosition(0);
|
||||
deviceInStore.setMobilePositionSubmissionInterval(0);
|
||||
removeMobilePositionSubscribe(deviceInStore, null);
|
||||
}
|
||||
}
|
||||
if (deviceInStore.getGeoCoordSys() != null) {
|
||||
// 坐标系变化,需要重新计算GCJ02坐标和WGS84坐标
|
||||
if (!deviceInStore.getGeoCoordSys().equals(device.getGeoCoordSys())) {
|
||||
@ -496,10 +497,8 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean delete(String deviceId) {
|
||||
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId);
|
||||
}
|
||||
Device device = getDeviceByDeviceIdFromDb(deviceId);
|
||||
Assert.notNull(device, "未找到设备");
|
||||
platformChannelMapper.delChannelForDeviceId(deviceId);
|
||||
deviceChannelMapper.cleanChannelsByDeviceId(device.getId());
|
||||
deviceMapper.del(deviceId);
|
||||
@ -527,7 +526,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
.replaceAll("%", "/%")
|
||||
.replaceAll("_", "/_");
|
||||
}
|
||||
List<Device> all = deviceMapper.getDeviceList(query, status);
|
||||
List<Device> all = deviceMapper.getDeviceList(ChannelDataType.GB28181.value, query, status);
|
||||
return new PageInfo<>(all);
|
||||
}
|
||||
|
||||
@ -538,11 +537,403 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
|
||||
@Override
|
||||
public Device getDeviceByChannelId(Integer channelId) {
|
||||
return deviceMapper.queryByChannelId(channelId);
|
||||
return deviceMapper.queryByChannelId(ChannelDataType.GB28181.value,channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device getDeviceBySourceChannelDeviceId(String channelId) {
|
||||
return deviceMapper.getDeviceBySourceChannelDeviceId(channelId);
|
||||
return deviceMapper.getDeviceBySourceChannelDeviceId(ChannelDataType.GB28181.value,channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeCatalog(int id, int cycle) {
|
||||
Device device = deviceMapper.query(id);
|
||||
Assert.notNull(device, "未找到设备");
|
||||
|
||||
if (device.getSubscribeCycleForCatalog() == cycle) {
|
||||
return;
|
||||
}
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcService.subscribeCatalog(id, cycle);
|
||||
return;
|
||||
}
|
||||
// 目录订阅相关的信息
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
// 订阅周期不同,则先取消
|
||||
removeCatalogSubscribe(device, result->{
|
||||
device.setSubscribeCycleForCatalog(cycle);
|
||||
if (cycle > 0) {
|
||||
// 开启订阅
|
||||
addCatalogSubscribe(device);
|
||||
}
|
||||
// 因为是异步执行,需要在这里更新下数据
|
||||
deviceMapper.updateSubscribeCatalog(device);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
});
|
||||
}else {
|
||||
// 开启订阅
|
||||
device.setSubscribeCycleForCatalog(cycle);
|
||||
addCatalogSubscribe(device);
|
||||
deviceMapper.updateSubscribeCatalog(device);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribeMobilePosition(int id, int cycle, int interval) {
|
||||
Device device = deviceMapper.query(id);
|
||||
Assert.notNull(device, "未找到设备");
|
||||
if (device.getSubscribeCycleForMobilePosition() == cycle) {
|
||||
return;
|
||||
}
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcService.subscribeMobilePosition(id, cycle, interval);
|
||||
return;
|
||||
}
|
||||
// 目录订阅相关的信息
|
||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||
// 订阅周期已经开启,则先取消
|
||||
removeMobilePositionSubscribe(device, result->{
|
||||
// 开启订阅
|
||||
device.setSubscribeCycleForMobilePosition(cycle);
|
||||
device.setMobilePositionSubmissionInterval(interval);
|
||||
if (cycle > 0) {
|
||||
addMobilePositionSubscribe(device);
|
||||
}
|
||||
// 因为是异步执行,需要在这里更新下数据
|
||||
deviceMapper.updateSubscribeMobilePosition(device);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
});
|
||||
}else {
|
||||
// 订阅未开启
|
||||
device.setSubscribeCycleForMobilePosition(cycle);
|
||||
device.setMobilePositionSubmissionInterval(interval);
|
||||
// 开启订阅
|
||||
addMobilePositionSubscribe(device);
|
||||
// 因为是异步执行,需要在这里更新下数据
|
||||
deviceMapper.updateSubscribeMobilePosition(device);
|
||||
redisCatchStorage.updateDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDeviceHeartInfo(Device device) {
|
||||
Device deviceInDb = deviceMapper.query(device.getId());
|
||||
if (deviceInDb == null) {
|
||||
return;
|
||||
}
|
||||
if (!Objects.equals(deviceInDb.getHeartBeatCount(), device.getHeartBeatCount())
|
||||
|| !Objects.equals(deviceInDb.getHeartBeatInterval(), device.getHeartBeatInterval())) {
|
||||
// 刷新过期任务
|
||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
||||
// 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
|
||||
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "三次心跳超时"),
|
||||
device.getHeartBeatInterval() * 1000 * device.getHeartBeatCount());
|
||||
deviceInDb.setHeartBeatCount(device.getHeartBeatCount());
|
||||
deviceInDb.setHeartBeatInterval(device.getHeartBeatInterval());
|
||||
deviceInDb.setPositionCapability(device.getPositionCapability());
|
||||
updateDevice(deviceInDb);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WVPResult<SyncStatus> devicesSync(Device device) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
return redisRpcService.devicesSync(device.getServerId(), device.getDeviceId());
|
||||
}
|
||||
// 已存在则返回进度
|
||||
if (isSyncRunning(device.getDeviceId())) {
|
||||
SyncStatus channelSyncStatus = getChannelSyncStatus(device.getDeviceId());
|
||||
WVPResult<SyncStatus> 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;
|
||||
}
|
||||
sync(device);
|
||||
WVPResult<SyncStatus> wvpResult = new WVPResult<>();
|
||||
wvpResult.setCode(0);
|
||||
wvpResult.setMsg("开始同步");
|
||||
return wvpResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceBasicConfig(Device device, BasicParam basicParam, ErrorCallback<String> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.deviceBasicConfig(device.getServerId(), device, basicParam);
|
||||
if (result.getCode() == ErrorCode.SUCCESS.getCode()) {
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.deviceBasicConfigCmd(device, basicParam, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 设备配置: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceConfigQuery(Device device, String channelId, String configType, ErrorCallback<Object> callback) {
|
||||
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.deviceConfigQuery(device.getServerId(), device, channelId, configType);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.deviceConfigQuery(device, channelId, configType, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备配置: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleboot(Device device) {
|
||||
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcService.teleboot(device.getServerId(), device);
|
||||
}
|
||||
try {
|
||||
sipCommander.teleBootCmd(device);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 远程启动: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void record(Device device, String channelId, String recordCmdStr, ErrorCallback<String> callback) {
|
||||
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.recordControl(device.getServerId(), device, channelId, recordCmdStr);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.recordCmd(device, channelId, recordCmdStr, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 开始/停止录像: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void guard(Device device, String guardCmdStr, ErrorCallback<String> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.guard(device.getServerId(), device, guardCmdStr);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.guardCmd(device, guardCmdStr, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAlarm(Device device, String channelId, String alarmMethod, String alarmType, ErrorCallback<String> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.resetAlarm(device.getServerId(), device, channelId, alarmMethod, alarmType);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sipCommander.alarmResetCmd(device, alarmMethod, alarmType, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iFrame(Device device, String channelId) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcService.iFrame(device.getServerId(), device, channelId);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.iFrameCmd(device, channelId);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 强制关键帧操作: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void homePosition(Device device, String channelId, Boolean enabled, Integer resetTime, Integer presetIndex, ErrorCallback<String> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.homePosition(device.getServerId(), device, channelId, enabled, resetTime, presetIndex);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.homePositionCmd(device, channelId, enabled, resetTime, presetIndex, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 看守位控制: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragZoomIn(Device device, String channelId, int length, int width, int midpointx, int midpointy, int lengthx, int lengthy, ErrorCallback<String> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcService.dragZoomIn(device.getServerId(), device, channelId, length, width, midpointx, midpointy, lengthx, lengthy);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
cmdXml.append("<DragZoomIn>\r\n");
|
||||
cmdXml.append("<Length>" + length+ "</Length>\r\n");
|
||||
cmdXml.append("<Width>" + width+ "</Width>\r\n");
|
||||
cmdXml.append("<MidPointX>" + midpointx+ "</MidPointX>\r\n");
|
||||
cmdXml.append("<MidPointY>" + midpointy+ "</MidPointY>\r\n");
|
||||
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
||||
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
||||
cmdXml.append("</DragZoomIn>\r\n");
|
||||
try {
|
||||
sipCommander.dragZoomCmd(device, channelId, cmdXml.toString(), callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 拉框放大: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragZoomOut(Device device, String channelId, int length, int width, int midpointx, int midpointy, int lengthx, int lengthy, ErrorCallback<String> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcService.dragZoomOut(device.getServerId(), device, channelId, length, width, midpointx, midpointy, lengthx, lengthy);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
cmdXml.append("<DragZoomOut>\r\n");
|
||||
cmdXml.append("<Length>" + length+ "</Length>\r\n");
|
||||
cmdXml.append("<Width>" + width+ "</Width>\r\n");
|
||||
cmdXml.append("<MidPointX>" + midpointx+ "</MidPointX>\r\n");
|
||||
cmdXml.append("<MidPointY>" + midpointy+ "</MidPointY>\r\n");
|
||||
cmdXml.append("<LengthX>" + lengthx+ "</LengthX>\r\n");
|
||||
cmdXml.append("<LengthY>" + lengthy+ "</LengthY>\r\n");
|
||||
cmdXml.append("</DragZoomOut>\r\n");
|
||||
try {
|
||||
sipCommander.dragZoomCmd(device, channelId, cmdXml.toString(), callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 拉框放大: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceStatus(Device device, ErrorCallback<String> callback) {
|
||||
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.deviceStatus(device.getServerId(), device);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
sipCommander.deviceStatusQuery(device, (code, msg, data) -> {
|
||||
if ("ONLINE".equalsIgnoreCase(data.trim())) {
|
||||
online(device, null);
|
||||
}else {
|
||||
offline(device.getDeviceId(), "设备状态查询结果:" + data.trim());
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.run(code, msg, data);
|
||||
}
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备状态: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void alarm(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType, String startTime, String endTime, ErrorCallback<Object> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<String> result = redisRpcService.alarm(device.getServerId(), device, startPriority, endPriority, alarmMethod, alarmType, startTime, endTime);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
String startAlarmTime = "";
|
||||
if (startTime != null) {
|
||||
startAlarmTime = DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(startTime);
|
||||
}
|
||||
String endAlarmTime = "";
|
||||
if (startTime != null) {
|
||||
endAlarmTime = DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(endTime);
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.alarmInfoQuery(device, startPriority, endPriority, alarmMethod, alarmType, startAlarmTime, endAlarmTime, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备状态: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceInfo(Device device, ErrorCallback<Object> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<Object> result = redisRpcService.deviceInfo(device.getServerId(), device);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.deviceInfoQuery(device, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 获取设备信息: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryPreset(Device device, String channelId, ErrorCallback<Object> callback) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
WVPResult<Object> result = redisRpcService.queryPreset(device.getServerId(), device, channelId);
|
||||
callback.run(result.getCode(), result.getMsg(), result.getData());
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sipCommander.presetQuery(device, channelId, callback);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 预制位查询: {}", e.getMessage());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage(), null);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.FrontEndControlCodeForPTZ;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelControlService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class GbChannelControlServiceImpl implements IGbChannelControlService {
|
||||
|
||||
@Override
|
||||
public void ptz(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback) {
|
||||
log.info("[通用通道] 云台控制, 通道: {}", channel.getGbId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preset(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback) {
|
||||
log.info("[通用通道] 预置位, 通道: {}", channel.getGbId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fi(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback) {
|
||||
log.info("[通用通道] FI指令, 通道: {}", channel.getGbId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tour(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scan(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void auxiliary(CommonGBChannel channel, FrontEndControlCodeForPTZ frontEndControlCode, ErrorCallback<String> callback) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,21 +1,27 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.exception.ServiceException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.InviteInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.PlayException;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelPlayService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlayService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||
import com.genersoft.iot.vmp.streamProxy.service.IStreamProxyPlayService;
|
||||
import com.genersoft.iot.vmp.streamPush.service.IStreamPushPlayService;
|
||||
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 javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -30,25 +36,28 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
@Autowired
|
||||
private IStreamPushPlayService streamPushPlayService;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
|
||||
@Override
|
||||
public void start(CommonGBChannel channel, InviteInfo inviteInfo, Platform platform, ErrorCallback<StreamInfo> callback) {
|
||||
if (channel == null || inviteInfo == null || callback == null) {
|
||||
public void start(CommonGBChannel channel, InviteMessageInfo inviteInfo, Platform platform, ErrorCallback<StreamInfo> callback) {
|
||||
if (channel == null || inviteInfo == null || callback == null || channel.getDataType() == null) {
|
||||
log.warn("[通用通道点播] 参数异常, channel: {}, inviteInfo: {}, callback: {}", channel != null, inviteInfo != null, callback != null);
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
}
|
||||
log.info("[点播通用通道] 类型:{}, 通道: {}({})", inviteInfo.getSessionName(), channel.getGbName(), channel.getGbDeviceId());
|
||||
if ("Play".equalsIgnoreCase(inviteInfo.getSessionName())) {
|
||||
play(channel, platform, callback);
|
||||
play(channel, platform, userSetting.getRecordSip(), callback);
|
||||
}else if ("Playback".equals(inviteInfo.getSessionName())) {
|
||||
if (channel.getGbDeviceDbId() != null) {
|
||||
if (channel.getDataType() == ChannelDataType.GB28181.value) {
|
||||
// 国标通道
|
||||
playbackGbDeviceChannel(channel, inviteInfo.getStartTime(), inviteInfo.getStopTime(), callback);
|
||||
} else if (channel.getStreamProxyId() != null) {
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PROXY.value) {
|
||||
// 拉流代理
|
||||
log.warn("[回放通用通道] 不支持回放拉流代理的录像: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.FORBIDDEN, "forbidden");
|
||||
} else if (channel.getStreamPushId() != null) {
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PUSH.value) {
|
||||
// 推流
|
||||
log.warn("[回放通用通道] 不支持回放推流的录像: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.FORBIDDEN, "forbidden");
|
||||
@ -58,7 +67,7 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
}
|
||||
}else if ("Download".equals(inviteInfo.getSessionName())) {
|
||||
if (channel.getGbDeviceDbId() != null) {
|
||||
if (channel.getDataType() == ChannelDataType.GB28181.value) {
|
||||
int downloadSpeed = 4;
|
||||
try {
|
||||
if (inviteInfo.getDownloadSpeed() != null){
|
||||
@ -68,11 +77,11 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
|
||||
// 国标通道
|
||||
downloadGbDeviceChannel(channel, inviteInfo.getStartTime(), inviteInfo.getStopTime(), downloadSpeed, callback);
|
||||
} else if (channel.getStreamProxyId() != null) {
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PROXY.value) {
|
||||
// 拉流代理
|
||||
log.warn("[下载通用通道录像] 不支持下载拉流代理的录像: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.FORBIDDEN, "forbidden");
|
||||
} else if (channel.getStreamPushId() != null) {
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PUSH.value) {
|
||||
// 推流
|
||||
log.warn("[下载通用通道录像] 不支持下载推流的录像: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.FORBIDDEN, "forbidden");
|
||||
@ -89,14 +98,32 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play(CommonGBChannel channel, Platform platform, ErrorCallback<StreamInfo> callback) {
|
||||
if (channel.getGbDeviceDbId() != null) {
|
||||
public void stopPlay(InviteSessionType type, CommonGBChannel channel, String stream) {
|
||||
if (channel.getDataType() == ChannelDataType.GB28181.value) {
|
||||
// 国标通道
|
||||
playGbDeviceChannel(channel, callback);
|
||||
} else if (channel.getStreamProxyId() != null) {
|
||||
stopPlayDeviceChannel(type, channel, stream);
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PROXY.value) {
|
||||
// 拉流代理
|
||||
playProxy(channel, callback);
|
||||
} else if (channel.getStreamPushId() != null) {
|
||||
stopPlayProxy(channel);
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PUSH.value) {
|
||||
// 推流
|
||||
stopPlayPush(channel);
|
||||
} else {
|
||||
// 通道数据异常
|
||||
log.error("[点播通用通道] 通道数据异常,无法识别通道来源: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play(CommonGBChannel channel, Platform platform, Boolean record, ErrorCallback<StreamInfo> callback) {
|
||||
if (channel.getDataType() == ChannelDataType.GB28181.value) {
|
||||
// 国标通道
|
||||
playGbDeviceChannel(channel, record, callback);
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PROXY.value) {
|
||||
// 拉流代理
|
||||
playProxy(channel, record, callback);
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PUSH.value) {
|
||||
if (platform != null) {
|
||||
// 推流
|
||||
playPush(channel, platform.getServerGBId(), platform.getName(), callback);
|
||||
@ -112,10 +139,10 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback<StreamInfo> callback){
|
||||
public void playGbDeviceChannel(CommonGBChannel channel, Boolean record, ErrorCallback<StreamInfo> callback){
|
||||
// 国标通道
|
||||
try {
|
||||
deviceChannelPlayService.play(channel, callback);
|
||||
deviceChannelPlayService.play(channel, record, callback);
|
||||
} catch (PlayException e) {
|
||||
callback.run(e.getCode(), e.getMsg(), null);
|
||||
} catch (Exception e) {
|
||||
@ -125,25 +152,40 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playProxy(CommonGBChannel channel, ErrorCallback<StreamInfo> callback){
|
||||
public void stopPlayDeviceChannel(InviteSessionType type, CommonGBChannel channel, String stream) {
|
||||
// 国标通道
|
||||
try {
|
||||
deviceChannelPlayService.stop(type, channel, stream);
|
||||
} catch (Exception e) {
|
||||
log.error("[停止点播失败] {}({})", channel.getGbName(), channel.getGbDeviceId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playProxy(CommonGBChannel channel, Boolean record, ErrorCallback<StreamInfo> callback){
|
||||
// 拉流代理通道
|
||||
try {
|
||||
StreamInfo streamInfo = streamProxyPlayService.start(channel.getStreamProxyId());
|
||||
if (streamInfo == null) {
|
||||
callback.run(Response.BUSY_HERE, "busy here", null);
|
||||
}else {
|
||||
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
}
|
||||
streamProxyPlayService.start(channel.getDataDeviceId(), record, callback);
|
||||
}catch (Exception e) {
|
||||
callback.run(Response.BUSY_HERE, "busy here", null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopPlayProxy(CommonGBChannel channel) {
|
||||
// 拉流代理通道
|
||||
try {
|
||||
streamProxyPlayService.stop(channel.getDataDeviceId());
|
||||
}catch (Exception e) {
|
||||
log.error("[停止点播失败] {}({})", channel.getGbName(), channel.getGbDeviceId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playPush(CommonGBChannel channel, String platformDeviceId, String platformName, ErrorCallback<StreamInfo> callback){
|
||||
// 推流
|
||||
try {
|
||||
streamPushPlayService.start(channel.getStreamPushId(), callback, platformDeviceId, platformName);
|
||||
streamPushPlayService.start(channel.getDataDeviceId(), callback, platformDeviceId, platformName);
|
||||
}catch (PlayException e) {
|
||||
callback.run(e.getCode(), e.getMsg(), null);
|
||||
}catch (Exception e) {
|
||||
@ -152,6 +194,16 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopPlayPush(CommonGBChannel channel) {
|
||||
// 推流
|
||||
try {
|
||||
streamPushPlayService.stop(channel.getDataDeviceId());
|
||||
}catch (Exception e) {
|
||||
log.error("[停止点播失败] {}({})", channel.getGbName(), channel.getGbDeviceId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void playbackGbDeviceChannel(CommonGBChannel channel, Long startTime, Long stopTime, ErrorCallback<StreamInfo> callback){
|
||||
try {
|
||||
deviceChannelPlayService.playBack(channel, startTime, stopTime, callback);
|
||||
@ -162,6 +214,20 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseRtp(String streamId) {
|
||||
try {
|
||||
deviceChannelPlayService.pauseRtp(streamId);
|
||||
} catch (ServiceException | InvalidArgumentException | ParseException | SipException ignore) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeRtp(String streamId) {
|
||||
try {
|
||||
deviceChannelPlayService.resumeRtp(streamId);
|
||||
} catch (ServiceException | InvalidArgumentException | ParseException | SipException ignore) {}
|
||||
}
|
||||
|
||||
private void downloadGbDeviceChannel(CommonGBChannel channel, Long startTime, Long stopTime, Integer downloadSpeed,
|
||||
ErrorCallback<StreamInfo> callback){
|
||||
try {
|
||||
@ -172,4 +238,6 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService {
|
||||
callback.run(Response.BUSY_HERE, "busy here", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.CommonGBChannelMapper;
|
||||
@ -8,8 +9,10 @@ import com.genersoft.iot.vmp.gb28181.dao.PlatformChannelMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.RegionMapper;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformChannelService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
@ -22,7 +25,11 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.util.*;
|
||||
import javax.sip.message.Response;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -46,6 +53,9 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
@Autowired
|
||||
private GroupMapper groupMapper;
|
||||
|
||||
@Autowired
|
||||
private IDeviceChannelService deviceChannelService;
|
||||
|
||||
@Override
|
||||
public CommonGBChannel queryByDeviceId(String gbDeviceId) {
|
||||
return commonGBChannelMapper.queryByDeviceId(gbDeviceId);
|
||||
@ -53,17 +63,12 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
|
||||
@Override
|
||||
public int add(CommonGBChannel commonGBChannel) {
|
||||
if (commonGBChannel.getStreamPushId() != null && commonGBChannel.getStreamPushId() > 0) {
|
||||
CommonGBChannel commonGBChannelInDb = commonGBChannelMapper.queryByStreamPushId(commonGBChannel.getStreamPushId());
|
||||
if (commonGBChannelInDb != null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "此推流已经关联通道");
|
||||
}
|
||||
if (commonGBChannel.getDataType() == null || commonGBChannel.getDataDeviceId() == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "缺少通道数据类型或通道数据关联设备ID");
|
||||
}
|
||||
if (commonGBChannel.getStreamProxyId() != null && commonGBChannel.getStreamProxyId() > 0) {
|
||||
CommonGBChannel commonGBChannelInDb = commonGBChannelMapper.queryByStreamProxyId(commonGBChannel.getStreamProxyId());
|
||||
if (commonGBChannelInDb != null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "此代理已经关联通道");
|
||||
}
|
||||
CommonGBChannel commonGBChannelInDb = commonGBChannelMapper.queryByDataId(commonGBChannel.getDataType(), commonGBChannel.getDataDeviceId());
|
||||
if (commonGBChannelInDb != null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "此推流已经关联通道");
|
||||
}
|
||||
commonGBChannel.setCreateTime(DateUtil.getNow());
|
||||
commonGBChannel.setUpdateTime(DateUtil.getNow());
|
||||
@ -113,7 +118,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
public int update(CommonGBChannel commonGBChannel) {
|
||||
log.info("[更新通道] 通道ID: {}, ", commonGBChannel.getGbId());
|
||||
if (commonGBChannel.getGbId() <= 0) {
|
||||
log.warn("[更新通道] 未找到数据库ID,更新失败, {}", commonGBChannel.getGbDeviceDbId());
|
||||
log.warn("[更新通道] 未找到数据库ID,更新失败, {}({})", commonGBChannel.getGbName(), commonGBChannel.getGbDeviceId());
|
||||
return 0;
|
||||
}
|
||||
commonGBChannel.setUpdateTime(DateUtil.getNow());
|
||||
@ -132,10 +137,10 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
@Override
|
||||
public int offline(CommonGBChannel commonGBChannel) {
|
||||
if (commonGBChannel.getGbId() <= 0) {
|
||||
log.warn("[通道离线] 未找到数据库ID,更新失败, {}", commonGBChannel.getGbDeviceDbId());
|
||||
log.warn("[通道离线] 未找到数据库ID,更新失败, {}({})", commonGBChannel.getGbName(), commonGBChannel.getGbDeviceId());
|
||||
return 0;
|
||||
}
|
||||
int result = commonGBChannelMapper.updateStatusById(commonGBChannel.getGbId(), 0);
|
||||
int result = commonGBChannelMapper.updateStatusById(commonGBChannel.getGbId(), "OFF");
|
||||
if (result > 0) {
|
||||
try {
|
||||
// 发送通知
|
||||
@ -186,10 +191,10 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
@Override
|
||||
public int online(CommonGBChannel commonGBChannel) {
|
||||
if (commonGBChannel.getGbId() <= 0) {
|
||||
log.warn("[通道上线] 未找到数据库ID,更新失败, {}", commonGBChannel.getGbDeviceDbId());
|
||||
log.warn("[通道上线] 未找到数据库ID,更新失败, {}({})", commonGBChannel.getGbName(), commonGBChannel.getGbDeviceId());
|
||||
return 0;
|
||||
}
|
||||
int result = commonGBChannelMapper.updateStatusById(commonGBChannel.getGbId(), 1);
|
||||
int result = commonGBChannelMapper.updateStatusById(commonGBChannel.getGbId(), "ON");
|
||||
if (result > 0) {
|
||||
try {
|
||||
// 发送通知
|
||||
@ -371,12 +376,12 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
log.warn("[重置国标通道] 未找到对应Id的通道: id: {}", id);
|
||||
throw new ControllerException(ErrorCode.ERROR400);
|
||||
}
|
||||
if (channel.getGbDeviceDbId() <= 0) {
|
||||
if (channel.getDataType() != ChannelDataType.GB28181.value) {
|
||||
log.warn("[重置国标通道] 非国标下级通道无法重置: id: {}", id);
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "非国标下级通道无法重置");
|
||||
}
|
||||
// 这个多加一个参数,为了防止将非国标的通道通过此方法清空内容,导致意外发生
|
||||
commonGBChannelMapper.reset(id, channel.getGbDeviceDbId(), DateUtil.getNow());
|
||||
commonGBChannelMapper.reset(id, ChannelDataType.GB28181.value, channel.getDataDeviceId(), DateUtil.getNow());
|
||||
CommonGBChannel channelNew = getOne(id);
|
||||
// 发送通过更新通知
|
||||
try {
|
||||
@ -499,7 +504,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
|
||||
@Override
|
||||
public void addChannelToRegionByGbDevice(String civilCode, List<Integer> deviceIds) {
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(deviceIds);
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(ChannelDataType.GB28181.value, deviceIds);
|
||||
if (channelList.isEmpty()) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
|
||||
}
|
||||
@ -520,7 +525,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
|
||||
@Override
|
||||
public void deleteChannelToRegionByGbDevice(List<Integer> deviceIds) {
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(deviceIds);
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(ChannelDataType.GB28181.value, deviceIds);
|
||||
if (channelList.isEmpty()) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
|
||||
}
|
||||
@ -637,7 +642,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
@Override
|
||||
@Transactional
|
||||
public void addChannelToGroupByGbDevice(String parentId, String businessGroup, List<Integer> deviceIds) {
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(deviceIds);
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(ChannelDataType.GB28181.value, deviceIds);
|
||||
if (channelList.isEmpty()) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
|
||||
}
|
||||
@ -665,7 +670,7 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
|
||||
@Override
|
||||
public void deleteChannelToGroupByGbDevice(List<Integer> deviceIds) {
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(deviceIds);
|
||||
List<CommonGBChannel> channelList = commonGBChannelMapper.queryByGbDeviceIds(ChannelDataType.GB28181.value, deviceIds);
|
||||
if (channelList.isEmpty()) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "所有通道Id不存在");
|
||||
}
|
||||
@ -707,12 +712,12 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
|
||||
@Override
|
||||
public List<CommonGBChannel> queryListByStreamPushList(List<StreamPush> streamPushList) {
|
||||
return commonGBChannelMapper.queryListByStreamPushList(streamPushList);
|
||||
return commonGBChannelMapper.queryListByStreamPushList(ChannelDataType.STREAM_PUSH.value, streamPushList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGpsByDeviceIdForStreamPush(List<CommonGBChannel> channels) {
|
||||
commonGBChannelMapper.updateGpsByDeviceIdForStreamPush(channels);
|
||||
commonGBChannelMapper.updateGpsByDeviceIdForStreamPush(ChannelDataType.STREAM_PUSH.value, channels);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -726,4 +731,70 @@ public class GbChannelServiceImpl implements IGbChannelService {
|
||||
List<CommonGBChannel> all = commonGBChannelMapper.queryList(query, online, hasRecordPlan, channelType);
|
||||
return new PageInfo<>(all);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryRecordInfo(CommonGBChannel channel, String startTime, String endTime, ErrorCallback<RecordInfo> callback) {
|
||||
if (channel.getDataType() == ChannelDataType.GB28181.value) {
|
||||
deviceChannelService.queryRecordInfo(channel, startTime, endTime, callback);
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PROXY.value) {
|
||||
// 拉流代理
|
||||
log.warn("[下载通用通道录像] 不支持下载拉流代理的录像: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.FORBIDDEN, "forbidden");
|
||||
} else if (channel.getDataType() == ChannelDataType.STREAM_PUSH.value) {
|
||||
// 推流
|
||||
log.warn("[下载通用通道录像] 不支持下载推流的录像: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.FORBIDDEN, "forbidden");
|
||||
} else {
|
||||
// 通道数据异常
|
||||
log.error("[回放通用通道] 通道数据异常,无法识别通道来源: {}({})", channel.getGbName(), channel.getGbDeviceId());
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<CommonGBChannel> queryListByCivilCodeForUnusual(int page, int count, String query, Boolean online, Integer channelType) {
|
||||
PageHelper.startPage(page, count);
|
||||
if (query != null) {
|
||||
query = query.replaceAll("/", "//")
|
||||
.replaceAll("%", "/%")
|
||||
.replaceAll("_", "/_");
|
||||
}
|
||||
List<CommonGBChannel> all = commonGBChannelMapper.queryListByCivilCodeForUnusual(query, online, channelType);
|
||||
return new PageInfo<>(all);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearChannelCivilCode(Boolean all, List<Integer> channelIds) {
|
||||
|
||||
List<Integer> channelIdsForClear;
|
||||
if (all != null && all) {
|
||||
channelIdsForClear = commonGBChannelMapper.queryAllForUnusualCivilCode();
|
||||
}else {
|
||||
channelIdsForClear = channelIds;
|
||||
}
|
||||
commonGBChannelMapper.removeCivilCodeByChannelIds(channelIdsForClear);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<CommonGBChannel> queryListByParentForUnusual(int page, int count, String query, Boolean online, Integer channelType) {
|
||||
PageHelper.startPage(page, count);
|
||||
if (query != null) {
|
||||
query = query.replaceAll("/", "//")
|
||||
.replaceAll("%", "/%")
|
||||
.replaceAll("_", "/_");
|
||||
}
|
||||
List<CommonGBChannel> all = commonGBChannelMapper.queryListByParentForUnusual(query, online, channelType);
|
||||
return new PageInfo<>(all);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearChannelParent(Boolean all, List<Integer> channelIds) {
|
||||
List<Integer> channelIdsForClear;
|
||||
if (all != null && all) {
|
||||
channelIdsForClear = commonGBChannelMapper.queryAllForUnusualParent();
|
||||
}else {
|
||||
channelIdsForClear = channelIds;
|
||||
}
|
||||
commonGBChannelMapper.removeParentIdByChannelIds(channelIdsForClear);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.gb28181.service.IGbChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IGroupService;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -47,6 +48,13 @@ public class GroupServiceImpl implements IGroupService {
|
||||
|
||||
GbCode gbCode = GbCode.decode(group.getDeviceId());
|
||||
Assert.notNull(gbCode, "设备编号不满足国标定义");
|
||||
|
||||
// 查询数据库中已经存在的.
|
||||
List<Group> groupListInDb = groupManager.queryInGroupListByDeviceId(Lists.newArrayList(group));
|
||||
if (!ObjectUtils.isEmpty(groupListInDb)){
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), String.format("该节点编号 %s 已存在", group.getDeviceId()));
|
||||
}
|
||||
|
||||
if ("215".equals(gbCode.getTypeCode())){
|
||||
// 添加业务分组
|
||||
addBusinessGroup(group);
|
||||
@ -100,6 +108,12 @@ public class GroupServiceImpl implements IGroupService {
|
||||
Group groupInDb = groupManager.queryOne(group.getId());
|
||||
Assert.notNull(groupInDb, "分组不存在");
|
||||
|
||||
// 查询数据库中已经存在的.
|
||||
List<Group> groupListInDb = groupManager.queryInGroupListByDeviceId(Lists.newArrayList(group));
|
||||
if (!ObjectUtils.isEmpty(groupListInDb) && groupListInDb.get(0).getId() != group.getId()){
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), String.format("该该节点编号 %s 已存在", group.getDeviceId()));
|
||||
}
|
||||
|
||||
group.setName(group.getName());
|
||||
group.setUpdateTime(DateUtil.getNow());
|
||||
groupManager.update(group);
|
||||
@ -209,7 +223,7 @@ public class GroupServiceImpl implements IGroupService {
|
||||
for (Platform platform : platformList) {
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platform.getId(), channel, CatalogEvent.DEL);
|
||||
eventPublisher.catalogEventPublish(platform, channel, CatalogEvent.DEL);
|
||||
}catch (Exception e) {
|
||||
log.warn("[业务分组/虚拟组织删除] 发送失败,{}", groupForDelete.getDeviceId(), e);
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.*;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
@ -28,7 +27,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@DS("master")
|
||||
public class InviteStreamServiceImpl implements IInviteStreamService {
|
||||
|
||||
private final Map<String, List<ErrorCallback<StreamInfo>>> inviteErrorCallbackMap = new ConcurrentHashMap<>();
|
||||
|
||||
@ -1,14 +1,22 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Preset;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPTZService;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcPlayService;
|
||||
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 org.springframework.util.Assert;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
@ -24,6 +32,18 @@ public class PTZServiceImpl implements IPTZService {
|
||||
@Autowired
|
||||
private SIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private IRedisRpcPlayService redisRpcPlayService;
|
||||
|
||||
@Autowired
|
||||
private IDeviceChannelService deviceChannelService;
|
||||
|
||||
@Autowired
|
||||
private IDeviceService deviceService;
|
||||
|
||||
|
||||
@Override
|
||||
public void ptz(Device device, String channelId, int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed) {
|
||||
@ -37,6 +57,17 @@ public class PTZServiceImpl implements IPTZService {
|
||||
|
||||
@Override
|
||||
public void frontEndCommand(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combindCode2) {
|
||||
// 判断设备是否属于当前平台, 如果不属于则发起自动调用
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
// 通道ID
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOneForSource(device.getDeviceId(), channelId);
|
||||
Assert.notNull(deviceChannel, "通道不存在");
|
||||
String msg = redisRpcPlayService.frontEndCommand(device.getServerId(), deviceChannel.getId(), cmdCode, parameter1, parameter2, combindCode2);
|
||||
if (msg != null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
cmder.frontEndCmd(device, channelId, cmdCode, parameter1, parameter2, combindCode2);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
@ -45,6 +76,21 @@ public class PTZServiceImpl implements IPTZService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frontEndCommand(CommonGBChannel channel, Integer cmdCode, Integer parameter1, Integer parameter2, Integer combindCode2) {
|
||||
if (channel.getDataType() != ChannelDataType.GB28181.value) {
|
||||
// 只有国标通道的支持云台控制
|
||||
log.warn("[INFO 消息] 只有国标通道的支持云台控制, 通道ID: {}", channel.getGbId());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "不支持");
|
||||
}
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备ID");
|
||||
}
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOneById(channel.getGbId());
|
||||
frontEndCommand(device, deviceChannel.getDeviceId(), cmdCode, parameter1, parameter2, combindCode2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Preset> queryPresetList(String deviceId, String channelDeviceId) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.enums.ChannelDataType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.dao.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformChannelService;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.jt1078.proc.request.Re;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -26,7 +25,6 @@ import java.util.*;
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@DS("master")
|
||||
public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
|
||||
@Autowired
|
||||
@ -215,6 +213,10 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
|
||||
@Transactional
|
||||
public int addChannelList(Integer platformId, List<CommonGBChannel> channelList) {
|
||||
Platform platform = platformMapper.query(platformId);
|
||||
if (platform == null) {
|
||||
return 0;
|
||||
}
|
||||
int result = platformChannelMapper.addChannels(platformId, channelList);
|
||||
if (result > 0) {
|
||||
// 查询通道相关的行政区划信息是否共享,如果没共享就添加
|
||||
@ -244,7 +246,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platformId, channelList, CatalogEvent.ADD);
|
||||
eventPublisher.catalogEventPublish(platform, channelList, CatalogEvent.ADD);
|
||||
} catch (Exception e) {
|
||||
log.warn("[关联通道] 发送失败,数量:{}", channelList.size(), e);
|
||||
}
|
||||
@ -254,6 +256,11 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
|
||||
@Override
|
||||
public int removeAllChannel(Integer platformId) {
|
||||
Platform platform = platformMapper.query(platformId);
|
||||
if (platform == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<CommonGBChannel> channelListShare = platformChannelMapper.queryShare(platformId, null);
|
||||
Assert.notEmpty(channelListShare, "未共享任何通道");
|
||||
int result = platformChannelMapper.removeChannelsWithPlatform(platformId, channelListShare);
|
||||
@ -278,7 +285,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platformId, channelListShare, CatalogEvent.DEL);
|
||||
eventPublisher.catalogEventPublish(platform, channelListShare, CatalogEvent.DEL);
|
||||
} catch (Exception e) {
|
||||
log.warn("[移除全部关联通道] 发送失败,数量:{}", channelListShare.size(), e);
|
||||
}
|
||||
@ -289,19 +296,23 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
@Override
|
||||
@Transactional
|
||||
public void addChannelByDevice(Integer platformId, List<Integer> deviceIds) {
|
||||
List<Integer> channelList = commonGBChannelMapper.queryByGbDeviceIdsForIds(deviceIds);
|
||||
List<Integer> channelList = commonGBChannelMapper.queryByGbDeviceIdsForIds(ChannelDataType.GB28181.value, deviceIds);
|
||||
addChannels(platformId, channelList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void removeChannelByDevice(Integer platformId, List<Integer> deviceIds) {
|
||||
List<Integer> channelList = commonGBChannelMapper.queryByGbDeviceIdsForIds(deviceIds);
|
||||
List<Integer> channelList = commonGBChannelMapper.queryByGbDeviceIdsForIds(ChannelDataType.GB28181.value, deviceIds);
|
||||
removeChannels(platformId, channelList);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int removeChannelList(Integer platformId, List<CommonGBChannel> channelList) {
|
||||
Platform platform = platformMapper.query(platformId);
|
||||
if (platform == null) {
|
||||
return 0;
|
||||
}
|
||||
int result = platformChannelMapper.removeChannelsWithPlatform(platformId, channelList);
|
||||
if (result > 0) {
|
||||
// 查询通道相关的分组信息
|
||||
@ -324,7 +335,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platformId, channelList, CatalogEvent.DEL);
|
||||
eventPublisher.catalogEventPublish(platform, channelList, CatalogEvent.DEL);
|
||||
} catch (Exception e) {
|
||||
log.warn("[移除关联通道] 发送失败,数量:{}", channelList.size(), e);
|
||||
}
|
||||
@ -425,14 +436,15 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
@Override
|
||||
public void updateCustomChannel(PlatformChannel channel) {
|
||||
platformChannelMapper.updateCustomChannel(channel);
|
||||
Platform platform = platformMapper.query(channel.getPlatformId());
|
||||
CommonGBChannel commonGBChannel = platformChannelMapper.queryShareChannel(channel.getPlatformId(), channel.getGbId());
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(channel.getPlatformId(), commonGBChannel, CatalogEvent.UPDATE);
|
||||
eventPublisher.catalogEventPublish(platform, commonGBChannel, CatalogEvent.UPDATE);
|
||||
} catch (Exception e) {
|
||||
log.warn("[自定义通道信息] 发送失败, 平台ID: {}, 通道: {}({})", channel.getPlatformId(),
|
||||
channel.getGbName(), channel.getGbDeviceDbId(), e);
|
||||
channel.getGbName(), channel.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,7 +480,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platform.getId(), channelListForEvent, CatalogEvent.DEL);
|
||||
eventPublisher.catalogEventPublish(platform, channelListForEvent, CatalogEvent.DEL);
|
||||
} catch (Exception e) {
|
||||
log.warn("[移除关联通道] 发送失败,数量:{}", channelList.size(), e);
|
||||
}
|
||||
@ -506,7 +518,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platform.getId(), channelListForEvent, CatalogEvent.DEL);
|
||||
eventPublisher.catalogEventPublish(platform, channelListForEvent, CatalogEvent.DEL);
|
||||
} catch (Exception e) {
|
||||
log.warn("[移除关联通道] 发送失败,数量:{}", channelList.size(), e);
|
||||
}
|
||||
@ -537,7 +549,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platform.getId(), channelListForEvent, CatalogEvent.ADD);
|
||||
eventPublisher.catalogEventPublish(platform, channelListForEvent, CatalogEvent.ADD);
|
||||
} catch (Exception e) {
|
||||
log.warn("[移除关联通道] 发送失败,数量:{}", channelList.size(), e);
|
||||
}
|
||||
@ -567,7 +579,7 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
// 发送消息
|
||||
try {
|
||||
// 发送catalog
|
||||
eventPublisher.catalogEventPublish(platform.getId(), channelListForEvent, CatalogEvent.ADD);
|
||||
eventPublisher.catalogEventPublish(platform, channelListForEvent, CatalogEvent.ADD);
|
||||
} catch (Exception e) {
|
||||
log.warn("[移除关联通道] 发送失败,数量:{}", channelList.size(), e);
|
||||
}
|
||||
@ -584,4 +596,9 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||
public CommonGBChannel queryChannelByPlatformIdAndChannelId(Integer platformId, Integer channelId) {
|
||||
return platformChannelMapper.queryShareChannel(platformId, channelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommonGBChannel> queryChannelByPlatformIdAndChannelIds(Integer platformId, List<Integer> channelIds) {
|
||||
return platformChannelMapper.queryShare(platformId, channelIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||
import com.genersoft.iot.vmp.common.*;
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
@ -26,6 +26,7 @@ import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.ISendRtpServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.*;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
@ -35,6 +36,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
@ -47,13 +49,13 @@ import java.text.ParseException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@DS("master")
|
||||
public class PlatformServiceImpl implements IPlatformService {
|
||||
|
||||
private final static String REGISTER_KEY_PREFIX = "platform_register_";
|
||||
@ -67,6 +69,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
|
||||
|
||||
@Autowired
|
||||
private SSRCFactory ssrcFactory;
|
||||
|
||||
@ -85,6 +88,12 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private IRedisRpcService redisRpcService;
|
||||
|
||||
@Autowired
|
||||
private SipConfig sipConfig;
|
||||
|
||||
@Autowired
|
||||
private SipInviteSessionManager sessionManager;
|
||||
|
||||
@ -100,6 +109,85 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
@Autowired
|
||||
private ISendRtpServerService sendRtpServerService;
|
||||
|
||||
// 定时监听国标级联所进行的WVP服务是否正常, 如果异常则选择新的wvp执行
|
||||
@Scheduled(fixedDelay = 2, timeUnit = TimeUnit.SECONDS) //每3秒执行一次
|
||||
public void execute(){
|
||||
if (!userSetting.isAutoRegisterPlatform()) {
|
||||
return;
|
||||
}
|
||||
// 查找非平台的国标级联执行服务Id
|
||||
List<String> serverIds = platformMapper.queryServerIdsWithEnableAndNotInServer(userSetting.getServerId());
|
||||
if (serverIds == null || serverIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
serverIds.forEach(serverId -> {
|
||||
// 检查每个是否存活
|
||||
ServerInfo serverInfo = redisCatchStorage.queryServerInfo(serverId);
|
||||
if (serverInfo != null) {
|
||||
return;
|
||||
}
|
||||
log.info("[集群] 检测到 {} 已离线", serverId);
|
||||
String chooseServerId = redisCatchStorage.chooseOneServer(serverId);
|
||||
if (!userSetting.getServerId().equals(chooseServerId)){
|
||||
return;
|
||||
}
|
||||
// 此平台需要选择新平台处理, 确定由当前平台即开始处理
|
||||
List<Platform> platformList = platformMapper.queryByServerId(serverId);
|
||||
platformList.forEach(platform -> {
|
||||
log.info("[集群] 由本平台开启上级平台{}({})的注册", platform.getName(), platform.getServerGBId());
|
||||
// 设置平台使用当前平台的IP
|
||||
platform.setAddress(getIpWithSameNetwork(platform.getAddress()));
|
||||
platform.setServerId(userSetting.getServerId());
|
||||
platformMapper.update(platform);
|
||||
// 更新redis
|
||||
redisCatchStorage.delPlatformCatchInfo(platform.getServerGBId());
|
||||
PlatformCatch platformCatch = new PlatformCatch();
|
||||
platformCatch.setPlatform(platform);
|
||||
platformCatch.setId(platform.getServerGBId());
|
||||
redisCatchStorage.updatePlatformCatchInfo(platformCatch);
|
||||
// 开始注册
|
||||
// 注册成功时由程序直接调用了online方法
|
||||
try {
|
||||
commanderForPlatform.register(platform, eventResult -> {
|
||||
log.info("[国标级联] {}({}),添加向上级注册失败,请确定上级平台可用时重新保存", platform.getName(), platform.getServerGBId());
|
||||
}, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||
log.error("[命令发送失败] 国标级联: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同网段的IP
|
||||
*/
|
||||
private String getIpWithSameNetwork(String ip){
|
||||
if (ip == null || sipConfig.getMonitorIps().size() == 1) {
|
||||
return sipConfig.getMonitorIps().get(0);
|
||||
}
|
||||
String[] ipSplit = ip.split("\\.");
|
||||
String ip1 = null, ip2 = null, ip3 = null;
|
||||
for (String monitorIp : sipConfig.getMonitorIps()) {
|
||||
String[] monitorIpSplit = monitorIp.split("\\.");
|
||||
if (monitorIpSplit[0].equals(ipSplit[0]) && monitorIpSplit[1].equals(ipSplit[1]) && monitorIpSplit[2].equals(ipSplit[2])) {
|
||||
ip3 = monitorIp;
|
||||
}else if (monitorIpSplit[0].equals(ipSplit[0]) && monitorIpSplit[1].equals(ipSplit[1])) {
|
||||
ip2 = monitorIp;
|
||||
}else if (monitorIpSplit[0].equals(ipSplit[0])) {
|
||||
ip1 = monitorIp;
|
||||
}
|
||||
}
|
||||
if (ip3 != null) {
|
||||
return ip3;
|
||||
}else if (ip2 != null) {
|
||||
return ip2;
|
||||
}else if (ip1 != null) {
|
||||
return ip1;
|
||||
}else {
|
||||
return sipConfig.getMonitorIps().get(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 流离开的处理
|
||||
*/
|
||||
@ -175,6 +263,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
// 每次发送目录的数量默认为1
|
||||
platform.setCatalogGroup(1);
|
||||
}
|
||||
platform.setServerId(userSetting.getServerId());
|
||||
int result = platformMapper.add(platform);
|
||||
// 添加缓存
|
||||
PlatformCatch platformCatch = new PlatformCatch();
|
||||
@ -201,6 +290,11 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
log.info("[国标级联] 更新平台 {}({})", platform.getName(), platform.getDeviceGBId());
|
||||
platform.setCharacterSet(platform.getCharacterSet().toUpperCase());
|
||||
Platform platformInDb = platformMapper.query(platform.getId());
|
||||
Assert.notNull(platformInDb, "平台不存在");
|
||||
if (!userSetting.getServerId().equals(platformInDb.getServerId())) {
|
||||
return redisRpcService.updatePlatform(platformInDb.getServerId(), platform);
|
||||
}
|
||||
|
||||
PlatformCatch platformCatchOld = redisCatchStorage.queryPlatformCatchInfo(platformInDb.getServerGBId());
|
||||
platform.setUpdateTime(DateUtil.getNow());
|
||||
|
||||
@ -484,7 +578,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastInvite(Platform platform, CommonGBChannel channel, MediaServer mediaServerItem, HookSubscribe.Event hookEvent,
|
||||
public void broadcastInvite(Platform platform, CommonGBChannel channel, String sourceId, MediaServer mediaServerItem, HookSubscribe.Event hookEvent,
|
||||
SipSubscribe.Event errorEvent, InviteTimeOutCallback timeoutCallback) throws InvalidArgumentException, ParseException, SipException {
|
||||
|
||||
if (mediaServerItem == null) {
|
||||
@ -543,7 +637,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(platform.getServerGBId(), channel.getGbId(), ssrcInfo.getStream(), ssrcInfo, mediaServerItem.getId(),
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), userSetting.getBroadcastForPlatform(), InviteSessionType.BROADCAST,
|
||||
InviteSessionStatus.ready);
|
||||
InviteSessionStatus.ready, userSetting.getRecordSip());
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
String timeOutTaskKey = UUID.randomUUID().toString();
|
||||
dynamicTask.startDelay(timeOutTaskKey, () -> {
|
||||
@ -553,19 +647,19 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
log.info("[国标级联] 发起语音喊话 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", platform.getServerGBId(), channel.getGbDeviceId(), ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
||||
try {
|
||||
commanderForPlatform.streamByeCmd(platform, channel, ssrcInfo.getStream(), null, null);
|
||||
commanderForPlatform.streamByeCmd(platform, channel, ssrcInfo.getApp(), ssrcInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[点播超时], 发送BYE失败 {}", e.getMessage());
|
||||
} finally {
|
||||
timeoutCallback.run(1, "收流超时");
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
||||
}
|
||||
}
|
||||
}, userSetting.getPlayTimeout());
|
||||
commanderForPlatform.broadcastInviteCmd(platform, channel, mediaServerItem, ssrcInfo, (hookData)->{
|
||||
commanderForPlatform.broadcastInviteCmd(platform, channel,sourceId, mediaServerItem, ssrcInfo, (hookData)->{
|
||||
log.info("[国标级联] 发起语音喊话 收到上级推流 deviceId: {}, channelId: {}", platform.getServerGBId(), channel.getGbDeviceId());
|
||||
dynamicTask.stop(timeOutTaskKey);
|
||||
// hook响应
|
||||
@ -590,7 +684,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, mediaInfo.getApp(), mediaInfo.getStream(), mediaInfo, null);
|
||||
streamInfo.setChannelId(channel.getGbId());
|
||||
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getGbId());
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.BROADCAST, channel.getGbId());
|
||||
if (inviteInfo != null) {
|
||||
inviteInfo.setStatus(InviteSessionStatus.ok);
|
||||
inviteInfo.setStreamInfo(streamInfo);
|
||||
@ -638,7 +732,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
if (!result) {
|
||||
try {
|
||||
log.warn("[Invite 200OK] 更新ssrc失败,停止喊话 {}/{}", platform.getServerGBId(), channel.getGbDeviceId());
|
||||
commanderForPlatform.streamByeCmd(platform, channel, ssrcInfo.getStream(), null, null);
|
||||
commanderForPlatform.streamByeCmd(platform, channel, ssrcInfo.getApp(), ssrcInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage());
|
||||
}
|
||||
@ -647,7 +741,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
// 释放ssrc
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
@ -687,12 +781,13 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
if (ssrcInResponse != null) {
|
||||
// 单端口
|
||||
// 重新订阅流上线
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(inviteInfo.getStream());
|
||||
sessionManager.removeByStream(inviteInfo.getStream());
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(ssrcInfo.getApp(), inviteInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), inviteInfo.getStream());
|
||||
inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse);
|
||||
|
||||
ssrcTransaction.setPlatformId(platform.getServerGBId());
|
||||
ssrcTransaction.setChannelId(channel.getGbId());
|
||||
ssrcTransaction.setApp(ssrcInfo.getApp());
|
||||
ssrcTransaction.setStream(inviteInfo.getStream());
|
||||
ssrcTransaction.setSsrc(ssrcInResponse);
|
||||
ssrcTransaction.setMediaServerId(mediaServerItem.getId());
|
||||
@ -744,7 +839,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
// 释放ssrc
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
@ -755,11 +850,11 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopBroadcast(Platform platform, CommonGBChannel channel, String stream, boolean sendBye, MediaServer mediaServerItem) {
|
||||
public void stopBroadcast(Platform platform, CommonGBChannel channel, String app, String stream, boolean sendBye, MediaServer mediaServerItem) {
|
||||
|
||||
try {
|
||||
if (sendBye) {
|
||||
commanderForPlatform.streamByeCmd(platform, channel, stream, null, null);
|
||||
commanderForPlatform.streamByeCmd(platform, channel, app, stream, null, null);
|
||||
}
|
||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
log.warn("[消息发送失败] 停止语音对讲, 平台:{},通道:{}", platform.getId(), channel.getGbDeviceId() );
|
||||
@ -771,7 +866,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), inviteInfo.getSsrcInfo().getSsrc());
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
sessionManager.removeByStream(stream);
|
||||
sessionManager.removeByStream(app, stream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,8 +876,8 @@ public class PlatformServiceImpl implements IPlatformService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Platform> queryEnablePlatformList() {
|
||||
return platformMapper.queryEnablePlatformList();
|
||||
public List<Platform> queryEnablePlatformList(String serverId) {
|
||||
return platformMapper.queryEnableParentPlatformList(serverId,true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.genersoft.iot.vmp.gb28181.service.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||
import com.genersoft.iot.vmp.common.*;
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
@ -32,6 +31,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
|
||||
import com.genersoft.iot.vmp.service.IReceiveRtpServerService;
|
||||
import com.genersoft.iot.vmp.service.ISendRtpServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.*;
|
||||
import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcPlayService;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.utils.CloudRecordUtils;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
@ -64,8 +64,7 @@ import java.util.Vector;
|
||||
|
||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||
@Slf4j
|
||||
@Service
|
||||
@DS("master")
|
||||
@Service("playService")
|
||||
public class PlayServiceImpl implements IPlayService {
|
||||
|
||||
@Autowired
|
||||
@ -125,6 +124,9 @@ public class PlayServiceImpl implements IPlayService {
|
||||
@Autowired
|
||||
private ICloudRecordService cloudRecordService;
|
||||
|
||||
@Autowired
|
||||
private IRedisRpcPlayService redisRpcPlayService;
|
||||
|
||||
/**
|
||||
* 流到来的处理
|
||||
*/
|
||||
@ -188,7 +190,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
DeviceChannel channel = deviceChannelService.getOneById(sendRtpInfo.getChannelId());
|
||||
try {
|
||||
if (device != null && channel != null) {
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), event.getStream(), sendRtpInfo.getCallId());
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), event.getApp(), event.getStream(), sendRtpInfo.getCallId(), null);
|
||||
if (sendRtpInfo.getPlayType().equals(InviteStreamType.BROADCAST)
|
||||
|| sendRtpInfo.getPlayType().equals(InviteStreamType.TALK)) {
|
||||
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(channel.getId());
|
||||
@ -287,6 +289,21 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play(Device device, DeviceChannel channel, ErrorCallback<StreamInfo> callback) {
|
||||
|
||||
// 判断设备是否属于当前平台, 如果不属于则发起自动调用
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcPlayService.play(device.getServerId(), channel.getId(), callback);
|
||||
return;
|
||||
}
|
||||
MediaServer mediaServerItem = getNewMediaServerItem(device);
|
||||
if (mediaServerItem == null) {
|
||||
log.warn("[点播] 未找到可用的zlm deviceId: {},channelId:{}", device.getDeviceId(), channel.getDeviceId());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm");
|
||||
}
|
||||
play(mediaServerItem, device, channel, null, userSetting.getRecordSip(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<StreamInfo> callback) {
|
||||
@ -305,11 +322,11 @@ public class PlayServiceImpl implements IPlayService {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到通道");
|
||||
}
|
||||
|
||||
return play(mediaServerItem, device, channel, ssrc, callback);
|
||||
return play(mediaServerItem, device, channel, ssrc, userSetting.getRecordSip(), callback);
|
||||
}
|
||||
|
||||
private SSRCInfo play(MediaServer mediaServerItem, Device device, DeviceChannel channel, String ssrc,
|
||||
ErrorCallback<StreamInfo> callback) {
|
||||
private SSRCInfo play(MediaServer mediaServerItem, Device device, DeviceChannel channel, String ssrc, Boolean record,
|
||||
ErrorCallback<StreamInfo> callback) {
|
||||
if (mediaServerItem == null ) {
|
||||
if (callback != null) {
|
||||
callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(),
|
||||
@ -322,11 +339,12 @@ public class PlayServiceImpl implements IPlayService {
|
||||
InviteInfo inviteInfoInCatch = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
||||
if (inviteInfoInCatch != null ) {
|
||||
if (inviteInfoInCatch.getStreamInfo() == null) {
|
||||
// 释放生成的ssrc,使用上一次申请的
|
||||
// 释放生成的ssrc,使用上一次申请的322
|
||||
|
||||
ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc);
|
||||
// 点播发起了但是尚未成功, 仅注册回调等待结果即可
|
||||
inviteStreamService.once(InviteSessionType.PLAY, channel.getId(), null, callback);
|
||||
log.info("[点播开始] 已经请求中,等待结果, deviceId: {}, channelId: {}", device.getDeviceId(), channel.getDeviceId());
|
||||
log.info("[点播开始] 已经请求中,等待结果, deviceId: {}, channelId({}): {}", device.getDeviceId(), channel.getDeviceId(), channel.getId());
|
||||
return inviteInfoInCatch.getSsrcInfo();
|
||||
}else {
|
||||
StreamInfo streamInfo = inviteInfoInCatch.getStreamInfo();
|
||||
@ -372,6 +390,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
rtpServerParam.setTcpMode(tcpMode);
|
||||
rtpServerParam.setOnlyAuto(false);
|
||||
rtpServerParam.setDisableAudio(!channel.isHasAudio());
|
||||
|
||||
SSRCInfo ssrcInfo = receiveRtpServerService.openRTPServer(rtpServerParam, (code, msg, result) -> {
|
||||
|
||||
if (code == InviteErrorCode.SUCCESS.getCode() && result != null && result.getHookData() != null) {
|
||||
@ -404,14 +423,14 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, channel.getId(), null, code, msg, null);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(streamId);
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream("rtp", streamId);
|
||||
if (ssrcTransaction != null) {
|
||||
try {
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), streamId, null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(),"rtp", streamId, null, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[点播超时], 发送BYE失败 {}", e.getMessage());
|
||||
} finally {
|
||||
sessionManager.removeByStream(streamId);
|
||||
sessionManager.removeByStream("rtp", streamId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,14 +444,20 @@ public class PlayServiceImpl implements IPlayService {
|
||||
null);
|
||||
return null;
|
||||
}
|
||||
log.info("[点播开始] deviceId: {}, channelId: {},码流类型:{}, 收流端口: {}, 码流:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}",
|
||||
device.getDeviceId(), channel.getDeviceId(), channel.getStreamIdentification(), ssrcInfo.getPort(), ssrcInfo.getStream(),
|
||||
log.info("[点播开始] deviceId: {}, channelId({}): {},码流类型:{}, 收流端口: {}, 码流:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}",
|
||||
device.getDeviceId(), channel.getDeviceId(), channel.getId(), channel.getStreamIdentification(), ssrcInfo.getPort(), ssrcInfo.getStream(),
|
||||
device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
||||
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channel.getId(), ssrcInfo.getStream(), ssrcInfo, mediaServerItem.getId(),
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
||||
InviteSessionStatus.ready);
|
||||
InviteSessionStatus.ready, userSetting.getRecordSip());
|
||||
if (record != null) {
|
||||
inviteInfo.setRecord(record);
|
||||
}else {
|
||||
inviteInfo.setRecord(userSetting.getRecordSip());
|
||||
}
|
||||
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
|
||||
try {
|
||||
@ -443,7 +468,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
log.info("[点播失败]{}:{} deviceId: {}, channelId:{}",event.statusCode, event.msg, device.getDeviceId(), channel.getDeviceId());
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
if (callback != null) {
|
||||
callback.run(event.statusCode, event.msg, null);
|
||||
}
|
||||
@ -455,7 +480,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
log.error("[命令发送失败] 点播消息: {}", e.getMessage());
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
if (callback != null) {
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
||||
@ -506,13 +531,13 @@ public class PlayServiceImpl implements IPlayService {
|
||||
timeoutCallback.run();
|
||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
||||
try {
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), stream, null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), null, null, callId, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[语音对讲]超时, 发送BYE失败 {}", e.getMessage());
|
||||
} finally {
|
||||
timeoutCallback.run();
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc());
|
||||
sessionManager.removeByStream(sendRtpInfo.getStream());
|
||||
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
|
||||
}
|
||||
}, userSetting.getPlayTimeout());
|
||||
|
||||
@ -521,7 +546,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (localPort == null || localPort <= 0) {
|
||||
timeoutCallback.run();
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc());
|
||||
sessionManager.removeByStream(sendRtpInfo.getStream());
|
||||
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
|
||||
return;
|
||||
}
|
||||
sendRtpInfo.setPort(localPort);
|
||||
@ -556,7 +581,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
sendRtpInfo.setCallId(response.getCallIdHeader().getCallId());
|
||||
sendRtpServerService.update(sendRtpInfo);
|
||||
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), sendRtpInfo.getChannelId(), "talk",
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), sendRtpInfo.getChannelId(), "talk", sendRtpInfo.getApp(),
|
||||
sendRtpInfo.getStream(), sendRtpInfo.getSsrc(), sendRtpInfo.getMediaServerId(),
|
||||
response, InviteSessionType.TALK);
|
||||
|
||||
@ -573,7 +598,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
mediaServerService.closeRTPServer(mediaServerItem, sendRtpInfo.getStream());
|
||||
// 释放ssrc
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc());
|
||||
sessionManager.removeByStream(sendRtpInfo.getStream());
|
||||
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
|
||||
errorEvent.response(event);
|
||||
}, userSetting.getPlayTimeout().longValue());
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
@ -584,7 +609,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
// 释放ssrc
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpInfo.getSsrc());
|
||||
|
||||
sessionManager.removeByStream(sendRtpInfo.getStream());
|
||||
sessionManager.removeByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
|
||||
SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
|
||||
eventResult.type = SipSubscribe.EventResultType.cmdSendFailEvent;
|
||||
eventResult.statusCode = -1;
|
||||
@ -627,7 +652,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (!result) {
|
||||
// 主动连接失败,结束流程, 清理数据
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
inviteStreamService.call(InviteSessionType.BROADCAST, channel.getId(), null,
|
||||
@ -638,7 +663,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
log.error("[TCP主动连接对方] deviceId: {}, channelId: {}, 解析200OK的SDP信息失败", device.getDeviceId(), channel.getDeviceId(), e);
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
@ -729,6 +754,11 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (channel == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "通道不存在");
|
||||
}
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcPlayService.playback(device.getServerId(), channel.getId(), startTime, endTime, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
MediaServer newMediaServerItem = getNewMediaServerItem(device);
|
||||
if (newMediaServerItem == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的节点");
|
||||
@ -782,14 +812,14 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAYBACK, channel.getId(), null, code, msg, null);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAYBACK, channel.getId());
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(stream);
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream("rtp", stream);
|
||||
if (ssrcTransaction != null) {
|
||||
try {
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), stream, null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(),"rtp", stream, null, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[录像回放] 发送BYE失败 {}", e.getMessage());
|
||||
} finally {
|
||||
sessionManager.removeByStream(stream);
|
||||
sessionManager.removeByStream("rtp", stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -812,7 +842,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channel.getId(), ssrcInfo.getStream(), ssrcInfo, mediaServerItem.getId(),
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAYBACK,
|
||||
InviteSessionStatus.ready);
|
||||
InviteSessionStatus.ready, userSetting.getRecordSip());
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
|
||||
try {
|
||||
@ -828,7 +858,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}, userSetting.getPlayTimeout().longValue());
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
@ -837,7 +867,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
callback.run(InviteErrorCode.FAIL.getCode(), e.getMessage(), null);
|
||||
}
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
}
|
||||
@ -883,7 +913,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (!result) {
|
||||
try {
|
||||
log.warn("[Invite 200OK] 更新ssrc失败,停止点播 {}/{}", device.getDeviceId(), channel.getDeviceId());
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), ssrcInfo.getStream(), null, null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), ssrcInfo.getApp(), ssrcInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[命令发送失败] 停止播放, 发送BYE: {}", e.getMessage());
|
||||
}
|
||||
@ -891,7 +921,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
// 释放ssrc
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
@ -917,13 +947,15 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (ssrcInResponse != null) {
|
||||
// 单端口
|
||||
// 重新订阅流上线
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(inviteInfo.getStream());
|
||||
sessionManager.removeByStream(inviteInfo.getStream());
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream("rtp", inviteInfo.getStream());
|
||||
sessionManager.removeByStream("rtp", inviteInfo.getStream());
|
||||
inviteStreamService.updateInviteInfoForSSRC(inviteInfo, ssrcInResponse);
|
||||
ssrcTransaction.setDeviceId(device.getDeviceId());
|
||||
ssrcTransaction.setChannelId(ssrcTransaction.getChannelId());
|
||||
ssrcTransaction.setCallId(ssrcTransaction.getCallId());
|
||||
ssrcTransaction.setSsrc(ssrcInResponse);
|
||||
ssrcTransaction.setApp("rtp");
|
||||
ssrcTransaction.setStream(inviteInfo.getStream());
|
||||
ssrcTransaction.setMediaServerId(mediaServerItem.getId());
|
||||
ssrcTransaction.setSipTransactionInfo(new SipTransactionInfo((SIPResponse) responseEvent.getResponse()));
|
||||
ssrcTransaction.setType(inviteSessionType);
|
||||
@ -937,6 +969,11 @@ public class PlayServiceImpl implements IPlayService {
|
||||
@Override
|
||||
public void download(Device device, DeviceChannel channel, String startTime, String endTime, int downloadSpeed, ErrorCallback<StreamInfo> callback) {
|
||||
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcPlayService.download(device.getServerId(), channel.getId(), startTime, endTime, downloadSpeed, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
MediaServer newMediaServerItem = this.getNewMediaServerItem(device);
|
||||
if (newMediaServerItem == null) {
|
||||
callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(),
|
||||
@ -986,14 +1023,14 @@ public class PlayServiceImpl implements IPlayService {
|
||||
inviteStreamService.call(InviteSessionType.DOWNLOAD, channel.getId(), null, code, msg, null);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.DOWNLOAD, channel.getId());
|
||||
if (result != null && result.getSsrcInfo() != null) {
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(result.getSsrcInfo().getStream());
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(result.getSsrcInfo().getApp(), result.getSsrcInfo().getStream());
|
||||
if (ssrcTransaction != null) {
|
||||
try {
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), ssrcTransaction.getStream(), null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), ssrcTransaction.getApp(), ssrcTransaction.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[录像下载] 发送BYE失败 {}", e.getMessage());
|
||||
} finally {
|
||||
sessionManager.removeByStream(ssrcTransaction.getStream());
|
||||
sessionManager.removeByStream(ssrcTransaction.getApp(), ssrcTransaction.getStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1018,7 +1055,9 @@ public class PlayServiceImpl implements IPlayService {
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channel.getId(), ssrcInfo.getStream(), ssrcInfo, mediaServerItem.getId(),
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.DOWNLOAD,
|
||||
InviteSessionStatus.ready);
|
||||
InviteSessionStatus.ready, true);
|
||||
inviteInfo.setStartTime(startTime);
|
||||
inviteInfo.setEndTime(endTime);
|
||||
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
try {
|
||||
@ -1027,7 +1066,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
// 对方返回错误
|
||||
callback.run(InviteErrorCode.FAIL.getCode(), String.format("录像下载失败, 错误码: %s, %s", eventResult.statusCode, eventResult.msg), null);
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}, eventResult ->{
|
||||
// 处理收到200ok后的TCP主动连接以及SSRC不一致的问题
|
||||
@ -1059,13 +1098,15 @@ public class PlayServiceImpl implements IPlayService {
|
||||
log.error("[命令发送失败] 录像下载: {}", e.getMessage());
|
||||
callback.run(InviteErrorCode.FAIL.getCode(),e.getMessage(), null);
|
||||
receiveRtpServerService.closeRTPServer(mediaServerItem, ssrcInfo);
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamInfo getDownLoadInfo(Device device, DeviceChannel channel, String stream) {
|
||||
|
||||
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, channel.getId(), stream);
|
||||
if (inviteInfo == null) {
|
||||
String app = "rtp";
|
||||
@ -1195,8 +1236,8 @@ public class PlayServiceImpl implements IPlayService {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
cmder.streamByeCmd(device, deviceChannel.getDeviceId(),
|
||||
ssrcTransaction.getStream(), null);
|
||||
cmder.streamByeCmd(device, deviceChannel.getDeviceId(), ssrcTransaction.getApp(),
|
||||
ssrcTransaction.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException |
|
||||
SsrcTransactionNotFoundException e) {
|
||||
log.error("[zlm离线]为正在使用此zlm的设备, 发送BYE失败 {}", e.getMessage());
|
||||
@ -1207,10 +1248,19 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioBroadcastResult audioBroadcast(Device device, DeviceChannel deviceChannel, Boolean broadcastMode) {
|
||||
// TODO 必须多端口模式才支持语音喊话鹤语音对讲
|
||||
if (device == null || deviceChannel == null) {
|
||||
return null;
|
||||
public AudioBroadcastResult audioBroadcast(String deviceId, String channelDeviceId, Boolean broadcastMode) {
|
||||
|
||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到设备: " + deviceId);
|
||||
}
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, channelDeviceId);
|
||||
if (deviceChannel == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到通道: " + channelDeviceId);
|
||||
}
|
||||
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
return redisRpcPlayService.audioBroadcast(device.getServerId(), deviceId, channelDeviceId, broadcastMode);
|
||||
}
|
||||
log.info("[语音喊话] device: {}, channel: {}", device.getDeviceId(), deviceChannel.getDeviceId());
|
||||
MediaServer mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
|
||||
@ -1342,11 +1392,20 @@ public class PlayServiceImpl implements IPlayService {
|
||||
|
||||
@Override
|
||||
public void pauseRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException {
|
||||
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, streamId);
|
||||
if (null == inviteInfo || inviteInfo.getStreamInfo() == null) {
|
||||
log.warn("streamId不存在!");
|
||||
throw new ServiceException("streamId不存在");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "streamId不存在");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备不存在");
|
||||
}
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcPlayService.pauseRtp(device.getServerId(), streamId);
|
||||
return;
|
||||
}
|
||||
|
||||
inviteInfo.getStreamInfo().setPause(true);
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
MediaServer mediaServerItem = inviteInfo.getStreamInfo().getMediaServer();
|
||||
@ -1364,7 +1423,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (!result) {
|
||||
throw new ServiceException("暂停RTP接收失败");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
|
||||
|
||||
DeviceChannel channel = deviceChannelService.getOneById(inviteInfo.getChannelId());
|
||||
cmder.playPauseCmd(device, channel, inviteInfo.getStreamInfo());
|
||||
}
|
||||
@ -1373,9 +1432,17 @@ public class PlayServiceImpl implements IPlayService {
|
||||
public void resumeRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException {
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, streamId);
|
||||
if (null == inviteInfo || inviteInfo.getStreamInfo() == null) {
|
||||
log.warn("streamId不存在!");
|
||||
throw new ServiceException("streamId不存在");
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "streamId不存在");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
|
||||
if (device == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备不存在");
|
||||
}
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcPlayService.resumeRtp(device.getServerId(), streamId);
|
||||
return;
|
||||
}
|
||||
|
||||
inviteInfo.getStreamInfo().setPause(false);
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
MediaServer mediaServerItem = inviteInfo.getStreamInfo().getMediaServer();
|
||||
@ -1383,7 +1450,6 @@ public class PlayServiceImpl implements IPlayService {
|
||||
log.warn("mediaServer 不存在!");
|
||||
throw new ServiceException("mediaServer不存在");
|
||||
}
|
||||
// zlm 暂停RTP超时检查
|
||||
// 使用zlm中的流ID
|
||||
String streamKey = inviteInfo.getStream();
|
||||
if (!mediaServerItem.isRtpEnable()) {
|
||||
@ -1393,7 +1459,6 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (!result) {
|
||||
throw new ServiceException("继续RTP接收失败");
|
||||
}
|
||||
Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
|
||||
DeviceChannel channel = deviceChannelService.getOneById(inviteInfo.getChannelId());
|
||||
cmder.playResumeCmd(device, channel, inviteInfo.getStreamInfo());
|
||||
}
|
||||
@ -1530,10 +1595,10 @@ public class PlayServiceImpl implements IPlayService {
|
||||
|
||||
ssrcFactory.releaseSsrc(mediaServerId, sendRtpInfo.getSsrc());
|
||||
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(sendRtpInfo.getStream());
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(sendRtpInfo.getApp(), sendRtpInfo.getStream());
|
||||
if (ssrcTransaction != null) {
|
||||
try {
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), sendRtpInfo.getStream(), null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), sendRtpInfo.getApp(), sendRtpInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
log.info("[语音对讲] 停止消息发送失败,可能已经停止");
|
||||
}
|
||||
@ -1589,30 +1654,34 @@ public class PlayServiceImpl implements IPlayService {
|
||||
|
||||
@Override
|
||||
public void stop(InviteSessionType type, Device device, DeviceChannel channel, String stream) {
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(type, channel.getId(), stream);
|
||||
if (inviteInfo == null) {
|
||||
if (type == InviteSessionType.PLAY) {
|
||||
if (!userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisRpcPlayService.stop(device.getServerId(), type, channel.getId(), stream);
|
||||
}else {
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(type, channel.getId(), stream);
|
||||
if (inviteInfo == null) {
|
||||
if (type == InviteSessionType.PLAY) {
|
||||
deviceChannelService.stopPlay(channel.getId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
|
||||
try {
|
||||
log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId());
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), "rtp", inviteInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (inviteInfo.getType() == InviteSessionType.PLAY) {
|
||||
deviceChannelService.stopPlay(channel.getId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
|
||||
try {
|
||||
log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId());
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), inviteInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
log.error("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
if (inviteInfo.getStreamInfo() != null) {
|
||||
receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), inviteInfo.getSsrcInfo());
|
||||
}
|
||||
}
|
||||
|
||||
if (inviteInfo.getType() == InviteSessionType.PLAY) {
|
||||
deviceChannelService.stopPlay(channel.getId());
|
||||
}
|
||||
if (inviteInfo.getStreamInfo() != null) {
|
||||
receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), inviteInfo.getSsrcInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1623,7 +1692,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
log.warn("[停止点播] 发现通道不存在");
|
||||
return;
|
||||
}
|
||||
Device device = deviceService.getDevice(channel.getDeviceDbId());
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[停止点播] 发现设备不存在");
|
||||
return;
|
||||
@ -1632,7 +1701,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
|
||||
try {
|
||||
log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId());
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), inviteInfo.getStream(), null, null);
|
||||
cmder.streamByeCmd(device, channel.getDeviceId(), "rtp", inviteInfo.getStream(), null, null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
log.warn("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage());
|
||||
}
|
||||
@ -1647,19 +1716,25 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void play(CommonGBChannel channel, ErrorCallback<StreamInfo> callback) {
|
||||
Device device = deviceService.getDevice(channel.getGbDeviceDbId());
|
||||
public void play(CommonGBChannel channel, Boolean record, ErrorCallback<StreamInfo> callback) {
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[点播] 未找到通道{}的设备信息", channel);
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
}
|
||||
MediaServer mediaServer = getNewMediaServerItem(device);
|
||||
if (mediaServer == null) {
|
||||
log.warn("[点播] 未找到可用媒体节点");
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOneForSourceById(channel.getGbId());
|
||||
play(device, deviceChannel, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(InviteSessionType inviteSessionType, CommonGBChannel channel, String stream) {
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[停止播放] 未找到通道{}的设备信息", channel);
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
}
|
||||
DeviceChannel deviceChannel = deviceChannelService.getOneForSourceById(channel.getGbId());
|
||||
play(mediaServer, device, deviceChannel, null, callback);
|
||||
stop(inviteSessionType, device, deviceChannel, stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1668,7 +1743,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
throw new PlayException(Response.BAD_REQUEST, "bad request");
|
||||
}
|
||||
// 国标通道
|
||||
Device device = deviceService.getDevice(channel.getGbDeviceDbId());
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[点播] 未找到通道{}的设备信息", channel);
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
@ -1689,7 +1764,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
throw new PlayException(Response.BAD_REQUEST, "bad request");
|
||||
}
|
||||
// 国标通道
|
||||
Device device = deviceService.getDevice(channel.getGbDeviceDbId());
|
||||
Device device = deviceService.getDevice(channel.getDataDeviceId());
|
||||
if (device == null) {
|
||||
log.warn("[点播] 未找到通道{}的设备信息", channel);
|
||||
throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error");
|
||||
|
||||
@ -262,4 +262,66 @@ public class RegionServiceImpl implements IRegionService {
|
||||
regionList.addAll(allParent);
|
||||
return regionList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(String civilCode) {
|
||||
|
||||
CivilCodePo civilCodePo = CivilCodeUtil.INSTANCE.getCivilCodePo(civilCode);
|
||||
Assert.notNull(civilCodePo, String.format("节点%s未查询到", civilCode));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(civilCodePo.getName());
|
||||
List<CivilCodePo> civilCodePoList = CivilCodeUtil.INSTANCE.getAllParentCode(civilCode);
|
||||
if (civilCodePoList.isEmpty()) {
|
||||
return sb.toString();
|
||||
}
|
||||
for (int i = 0; i < civilCodePoList.size(); i++) {
|
||||
CivilCodePo item = civilCodePoList.get(i);
|
||||
sb.insert(0, item.getName());
|
||||
if (i != civilCodePoList.size() - 1) {
|
||||
sb.insert(0, "/");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void addByCivilCode(String civilCode) {
|
||||
CivilCodePo civilCodePo = CivilCodeUtil.INSTANCE.getCivilCodePo(civilCode);
|
||||
// 查询是否已经存在此节点
|
||||
Assert.notNull(civilCodePo, String.format("节点%s未查询到", civilCode));
|
||||
List<CivilCodePo> civilCodePoList = CivilCodeUtil.INSTANCE.getAllParentCode(civilCode);
|
||||
civilCodePoList.add(civilCodePo);
|
||||
|
||||
Set<String> civilCodeSet = regionMapper.queryInCivilCodePoList(civilCodePoList);
|
||||
if (!civilCodeSet.isEmpty()) {
|
||||
civilCodePoList.removeIf(item -> civilCodeSet.contains(item.getCode()));
|
||||
}
|
||||
if (civilCodePoList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int parentId = -1;
|
||||
for (int i = civilCodePoList.size() - 1; i > -1; i--) {
|
||||
CivilCodePo codePo = civilCodePoList.get(i);
|
||||
|
||||
Region region = new Region();
|
||||
region.setDeviceId(codePo.getCode());
|
||||
region.setParentDeviceId(codePo.getParentCode());
|
||||
region.setName(civilCodePo.getName());
|
||||
region.setCreateTime(DateUtil.getNow());
|
||||
region.setUpdateTime(DateUtil.getNow());
|
||||
if (parentId == -1 && codePo.getParentCode() != null) {
|
||||
Region parentRegion = regionMapper.queryByDeviceId(codePo.getParentCode());
|
||||
if (parentRegion == null){
|
||||
log.error(String.format("行政区划%sy已存在,但查询错误", codePo.getParentCode()));
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), String.format("行政区划%sy已存在,但查询错误", codePo.getParentCode()));
|
||||
}
|
||||
region.setParentId(parentRegion.getId());
|
||||
}else {
|
||||
region.setParentId(parentId);
|
||||
}
|
||||
regionMapper.add(region);
|
||||
parentId = region.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
package com.genersoft.iot.vmp.gb28181.session;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEventListener;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author lin
|
||||
*/
|
||||
@Component
|
||||
public class RecordDataCatch {
|
||||
|
||||
public static Map<String, RecordInfo> data = new ConcurrentHashMap<>();
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder deferredResultHolder;
|
||||
@Autowired
|
||||
private RecordEndEventListener recordEndEventListener;
|
||||
|
||||
|
||||
public int put(String deviceId,String channelId, String sn, int sumNum, List<RecordItem> recordItems) {
|
||||
String key = deviceId + sn;
|
||||
RecordInfo recordInfo = data.get(key);
|
||||
if (recordInfo == null) {
|
||||
recordInfo = new RecordInfo();
|
||||
recordInfo.setDeviceId(deviceId);
|
||||
recordInfo.setChannelId(channelId);
|
||||
recordInfo.setSn(sn.trim());
|
||||
recordInfo.setSumNum(sumNum);
|
||||
recordInfo.setRecordList(Collections.synchronizedList(new ArrayList<>()));
|
||||
recordInfo.setLastTime(Instant.now());
|
||||
recordInfo.getRecordList().addAll(recordItems);
|
||||
data.put(key, recordInfo);
|
||||
}else {
|
||||
// 同一个设备的通道同步请求只考虑一个,其他的直接忽略
|
||||
if (!Objects.equals(sn.trim(), recordInfo.getSn())) {
|
||||
return 0;
|
||||
}
|
||||
recordInfo.getRecordList().addAll(recordItems);
|
||||
recordInfo.setLastTime(Instant.now());
|
||||
}
|
||||
return recordInfo.getRecordList().size();
|
||||
}
|
||||
|
||||
@Scheduled(fixedRate = 5 * 1000) //每5秒执行一次, 发现数据5秒未更新则移除数据并认为数据接收超时
|
||||
private void timerTask(){
|
||||
Set<String> keys = data.keySet();
|
||||
// 获取五秒前的时刻
|
||||
Instant instantBefore5S = Instant.now().minusMillis(TimeUnit.SECONDS.toMillis(5));
|
||||
for (String key : keys) {
|
||||
RecordInfo recordInfo = data.get(key);
|
||||
// 超过五秒收不到消息任务超时, 只更新这一部分数据
|
||||
if ( recordInfo.getLastTime().isBefore(instantBefore5S)) {
|
||||
// 处理录像数据, 返回给前端
|
||||
String msgKey = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + recordInfo.getDeviceId() + recordInfo.getSn();
|
||||
|
||||
// 对数据进行排序
|
||||
Collections.sort(recordInfo.getRecordList());
|
||||
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setKey(msgKey);
|
||||
msg.setData(recordInfo);
|
||||
deferredResultHolder.invokeAllResult(msg);
|
||||
recordEndEventListener.delEndEventHandler(recordInfo.getDeviceId(),recordInfo.getChannelId());
|
||||
data.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isComplete(String deviceId, String sn) {
|
||||
RecordInfo recordInfo = data.get(deviceId + sn);
|
||||
return recordInfo != null && recordInfo.getRecordList().size() == recordInfo.getSumNum();
|
||||
}
|
||||
|
||||
public RecordInfo getRecordInfo(String deviceId, String sn) {
|
||||
return data.get(deviceId + sn);
|
||||
}
|
||||
|
||||
public void remove(String deviceId, String sn) {
|
||||
data.remove(deviceId + sn);
|
||||
}
|
||||
}
|
||||
@ -27,15 +27,15 @@ public class SipInviteSessionManager {
|
||||
*/
|
||||
public void put(SsrcTransaction ssrcTransaction){
|
||||
redisTemplate.opsForHash().put(VideoManagerConstants.SIP_INVITE_SESSION_STREAM + userSetting.getServerId()
|
||||
, ssrcTransaction.getStream(), ssrcTransaction);
|
||||
, ssrcTransaction.getApp() + ssrcTransaction.getStream(), ssrcTransaction);
|
||||
|
||||
redisTemplate.opsForHash().put(VideoManagerConstants.SIP_INVITE_SESSION_CALL_ID + userSetting.getServerId()
|
||||
, ssrcTransaction.getCallId(), ssrcTransaction);
|
||||
}
|
||||
|
||||
public SsrcTransaction getSsrcTransactionByStream(String stream){
|
||||
public SsrcTransaction getSsrcTransactionByStream(String app, String stream){
|
||||
String key = VideoManagerConstants.SIP_INVITE_SESSION_STREAM + userSetting.getServerId();
|
||||
return (SsrcTransaction)redisTemplate.opsForHash().get(key, stream);
|
||||
return (SsrcTransaction)redisTemplate.opsForHash().get(key, app + stream);
|
||||
}
|
||||
|
||||
public SsrcTransaction getSsrcTransactionByCallId(String callId){
|
||||
@ -56,12 +56,12 @@ public class SipInviteSessionManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void removeByStream(String stream) {
|
||||
SsrcTransaction ssrcTransaction = getSsrcTransactionByStream(stream);
|
||||
public void removeByStream(String app, String stream) {
|
||||
SsrcTransaction ssrcTransaction = getSsrcTransactionByStream(app, stream);
|
||||
if (ssrcTransaction == null ) {
|
||||
return;
|
||||
}
|
||||
redisTemplate.opsForHash().delete(VideoManagerConstants.SIP_INVITE_SESSION_STREAM + userSetting.getServerId(), stream);
|
||||
redisTemplate.opsForHash().delete(VideoManagerConstants.SIP_INVITE_SESSION_STREAM + userSetting.getServerId(), app + stream);
|
||||
if (ssrcTransaction.getCallId() != null) {
|
||||
redisTemplate.opsForHash().delete(VideoManagerConstants.SIP_INVITE_SESSION_CALL_ID + userSetting.getServerId(), ssrcTransaction.getCallId());
|
||||
}
|
||||
@ -74,7 +74,7 @@ public class SipInviteSessionManager {
|
||||
}
|
||||
redisTemplate.opsForHash().delete(VideoManagerConstants.SIP_INVITE_SESSION_CALL_ID + userSetting.getServerId(), callId);
|
||||
if (ssrcTransaction.getStream() != null) {
|
||||
redisTemplate.opsForHash().delete(VideoManagerConstants.SIP_INVITE_SESSION_STREAM + userSetting.getServerId(), ssrcTransaction.getStream());
|
||||
redisTemplate.opsForHash().delete(VideoManagerConstants.SIP_INVITE_SESSION_STREAM + userSetting.getServerId(), ssrcTransaction.getApp() + ssrcTransaction.getStream());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.gb28181.task;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||
@ -60,9 +61,12 @@ public class SipRunner implements CommandLineRunner {
|
||||
@Autowired
|
||||
private ISendRtpServerService sendRtpServerService;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
List<Device> deviceList = deviceService.getAllOnlineDevice();
|
||||
List<Device> deviceList = deviceService.getAllOnlineDevice(userSetting.getServerId());
|
||||
|
||||
for (Device device : deviceList) {
|
||||
if (deviceService.expire(device)){
|
||||
@ -86,7 +90,8 @@ public class SipRunner implements CommandLineRunner {
|
||||
deviceMapInDb.put(device.getDeviceId(), device);
|
||||
});
|
||||
devicesInRedis.parallelStream().forEach(device -> {
|
||||
if (deviceMapInDb.get(device.getDeviceId()) == null) {
|
||||
if (deviceMapInDb.get(device.getDeviceId()) == null
|
||||
&& userSetting.getServerId().equals(device.getServerId())) {
|
||||
redisCatchStorage.removeDevice(device.getDeviceId());
|
||||
}
|
||||
});
|
||||
|
||||
@ -5,7 +5,6 @@ import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.event.sip.SipEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.response.ISIPResponseProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.timeout.ITimeoutProcessor;
|
||||
import gov.nist.javax.sip.message.SIPResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -13,6 +12,7 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sip.*;
|
||||
import javax.sip.header.CSeqHeader;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.message.Response;
|
||||
import java.util.Map;
|
||||
@ -27,9 +27,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@Component
|
||||
public class SIPProcessorObserver implements ISIPProcessorObserver {
|
||||
|
||||
private static Map<String, ISIPRequestProcessor> requestProcessorMap = new ConcurrentHashMap<>();
|
||||
private static Map<String, ISIPResponseProcessor> responseProcessorMap = new ConcurrentHashMap<>();
|
||||
private static ITimeoutProcessor timeoutProcessor;
|
||||
private static final Map<String, ISIPRequestProcessor> requestProcessorMap = new ConcurrentHashMap<>();
|
||||
private static final Map<String, ISIPResponseProcessor> responseProcessorMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Autowired
|
||||
private SipSubscribe sipSubscribe;
|
||||
@ -55,14 +54,6 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
|
||||
responseProcessorMap.put(method, processor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 超时事件订阅
|
||||
* @param processor 处理程序
|
||||
*/
|
||||
public void addTimeoutProcessor(ITimeoutProcessor processor) {
|
||||
timeoutProcessor = processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分发RequestEvent事件
|
||||
* @param requestEvent RequestEvent事件
|
||||
@ -95,14 +86,15 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
|
||||
if (((status >= Response.OK) && (status < Response.MULTIPLE_CHOICES)) || status == Response.UNAUTHORIZED) {
|
||||
if (status != Response.UNAUTHORIZED && responseEvent.getResponse() != null && !sipSubscribe.isEmpty() ) {
|
||||
CallIdHeader callIdHeader = response.getCallIdHeader();
|
||||
CSeqHeader cSeqHeader = response.getCSeqHeader();
|
||||
if (callIdHeader != null) {
|
||||
SipEvent sipEvent = sipSubscribe.getSubscribe(callIdHeader.getCallId());
|
||||
SipEvent sipEvent = sipSubscribe.getSubscribe(callIdHeader.getCallId() + cSeqHeader.getSeqNumber());
|
||||
if (sipEvent != null) {
|
||||
if (sipEvent.getOkEvent() != null) {
|
||||
SipSubscribe.EventResult<ResponseEvent> eventResult = new SipSubscribe.EventResult<>(responseEvent);
|
||||
sipEvent.getOkEvent().response(eventResult);
|
||||
}
|
||||
sipSubscribe.removeSubscribe(callIdHeader.getCallId());
|
||||
sipSubscribe.removeSubscribe(callIdHeader.getCallId() + cSeqHeader.getSeqNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,15 +109,16 @@ public class SIPProcessorObserver implements ISIPProcessorObserver {
|
||||
} else {
|
||||
log.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase());
|
||||
if (responseEvent.getResponse() != null && !sipSubscribe.isEmpty() ) {
|
||||
CallIdHeader callIdHeader = (CallIdHeader)responseEvent.getResponse().getHeader(CallIdHeader.NAME);
|
||||
CallIdHeader callIdHeader = response.getCallIdHeader();
|
||||
CSeqHeader cSeqHeader = response.getCSeqHeader();
|
||||
if (callIdHeader != null) {
|
||||
SipEvent sipEvent = sipSubscribe.getSubscribe(callIdHeader.getCallId());
|
||||
SipEvent sipEvent = sipSubscribe.getSubscribe(callIdHeader.getCallId() + cSeqHeader.getSeqNumber());
|
||||
if (sipEvent != null ) {
|
||||
if (sipEvent.getErrorEvent() != null) {
|
||||
SipSubscribe.EventResult<ResponseEvent> eventResult = new SipSubscribe.EventResult<>(responseEvent);
|
||||
sipEvent.getErrorEvent().response(eventResult);
|
||||
}
|
||||
sipSubscribe.removeSubscribe(callIdHeader.getCallId());
|
||||
sipSubscribe.removeSubscribe(callIdHeader.getCallId() + cSeqHeader.getSeqNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.header.CSeqHeader;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.header.UserAgentHeader;
|
||||
import javax.sip.header.ViaHeader;
|
||||
@ -71,18 +72,20 @@ public class SIPSender {
|
||||
|
||||
if (okEvent != null || errorEvent != null) {
|
||||
CallIdHeader callIdHeader = (CallIdHeader) message.getHeader(CallIdHeader.NAME);
|
||||
SipEvent sipEvent = SipEvent.getInstance(callIdHeader.getCallId(), eventResult -> {
|
||||
sipSubscribe.removeSubscribe(callIdHeader.getCallId());
|
||||
CSeqHeader cSeqHeader = (CSeqHeader) message.getHeader(CSeqHeader.NAME);
|
||||
String key = callIdHeader.getCallId() + cSeqHeader.getSeqNumber();
|
||||
SipEvent sipEvent = SipEvent.getInstance(key, eventResult -> {
|
||||
sipSubscribe.removeSubscribe(key);
|
||||
if(okEvent != null) {
|
||||
okEvent.response(eventResult);
|
||||
}
|
||||
}, (eventResult -> {
|
||||
sipSubscribe.removeSubscribe(callIdHeader.getCallId());
|
||||
sipSubscribe.removeSubscribe(key);
|
||||
if (errorEvent != null) {
|
||||
errorEvent.response(eventResult);
|
||||
}
|
||||
}), timeout == null ? sipConfig.getTimeout() : timeout);
|
||||
sipSubscribe.addSubscribe(callIdHeader.getCallId(), sipEvent);
|
||||
sipSubscribe.addSubscribe(key, sipEvent);
|
||||
}
|
||||
|
||||
if ("TCP".equals(transport)) {
|
||||
|
||||
@ -18,20 +18,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||
@Component
|
||||
public class DeferredResultHolder {
|
||||
|
||||
public static final String CALLBACK_CMD_DEVICESTATUS = "CALLBACK_DEVICESTATUS";
|
||||
|
||||
public static final String CALLBACK_CMD_DEVICEINFO = "CALLBACK_DEVICEINFO";
|
||||
|
||||
public static final String CALLBACK_CMD_DEVICECONTROL = "CALLBACK_DEVICECONTROL";
|
||||
|
||||
public static final String CALLBACK_CMD_DEVICECONFIG = "CALLBACK_DEVICECONFIG";
|
||||
|
||||
public static final String CALLBACK_CMD_CONFIGDOWNLOAD = "CALLBACK_CONFIGDOWNLOAD";
|
||||
|
||||
public static final String CALLBACK_CMD_CATALOG = "CALLBACK_CATALOG";
|
||||
|
||||
public static final String CALLBACK_CMD_RECORDINFO = "CALLBACK_RECORDINFO";
|
||||
|
||||
public static final String CALLBACK_CMD_PLAY = "CALLBACK_PLAY";
|
||||
|
||||
@ -39,20 +25,11 @@ public class DeferredResultHolder {
|
||||
|
||||
public static final String CALLBACK_CMD_DOWNLOAD = "CALLBACK_DOWNLOAD";
|
||||
|
||||
public static final String CALLBACK_CMD_PROXY = "CALLBACK_PROXY";
|
||||
|
||||
public static final String CALLBACK_CMD_STOP = "CALLBACK_STOP";
|
||||
|
||||
public static final String UPLOAD_FILE_CHANNEL = "UPLOAD_FILE_CHANNEL";
|
||||
|
||||
public static final String CALLBACK_CMD_MOBILE_POSITION = "CALLBACK_CMD_MOBILE_POSITION";
|
||||
|
||||
public static final String CALLBACK_CMD_PRESETQUERY = "CALLBACK_PRESETQUERY";
|
||||
|
||||
public static final String CALLBACK_CMD_ALARM = "CALLBACK_ALARM";
|
||||
|
||||
public static final String CALLBACK_CMD_BROADCAST = "CALLBACK_BROADCAST";
|
||||
|
||||
public static final String CALLBACK_CMD_SNAP= "CALLBACK_SNAP";
|
||||
|
||||
private Map<String, Map<String, DeferredResultEx>> map = new ConcurrentHashMap<>();
|
||||
|
||||
@ -9,6 +9,7 @@ import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||
import gov.nist.javax.sip.message.SIPRequest;
|
||||
|
||||
@ -23,45 +24,6 @@ import java.text.ParseException;
|
||||
*/
|
||||
public interface ISIPCommander {
|
||||
|
||||
/**
|
||||
* 云台方向放控制,使用配置文件中的默认镜头移动速度
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
*/
|
||||
void ptzdirectCmd(Device device,String channelId,int leftRight, int upDown) throws InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
/**
|
||||
* 云台方向放控制
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param moveSpeed 镜头移动速度
|
||||
*/
|
||||
void ptzdirectCmd(Device device,String channelId,int leftRight, int upDown, int moveSpeed) throws InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
/**
|
||||
* 云台缩放控制,使用配置文件中的默认镜头缩放速度
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
*/
|
||||
void ptzZoomCmd(Device device,String channelId,int inOut) throws InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
/**
|
||||
* 云台缩放控制
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
*/
|
||||
void ptzZoomCmd(Device device,String channelId,int inOut, int moveSpeed) throws InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
/**
|
||||
* 云台控制,支持方向与缩放控制
|
||||
*
|
||||
@ -129,13 +91,10 @@ public interface ISIPCommander {
|
||||
/**
|
||||
* 视频流停止
|
||||
*/
|
||||
void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;
|
||||
void streamByeCmd(Device device, String channelId, String app, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;
|
||||
|
||||
void talkStreamCmd(MediaServer mediaServerItem, SendRtpInfo sendRtpItem, Device device, DeviceChannel channelId, String callId, HookSubscribe.Event event, HookSubscribe.Event eventForPush, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent, Long timeout) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
|
||||
void streamByeCmd(Device device, String channelId, String stream, String callId) throws InvalidArgumentException, ParseException, SipException, SsrcTransactionNotFoundException;
|
||||
|
||||
void streamByeCmd(Device device, String channelId, SipTransactionInfo sipTransactionInfo, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;
|
||||
|
||||
/**
|
||||
@ -184,7 +143,7 @@ public interface ISIPCommander {
|
||||
* @param channelId 预览通道
|
||||
* @param recordCmdStr 录像命令:Record / StopRecord
|
||||
*/
|
||||
void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void recordCmd(Device device, String channelId, String recordCmdStr, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 远程启动控制命令
|
||||
@ -198,7 +157,7 @@ public interface ISIPCommander {
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void guardCmd(Device device, String guardCmdStr, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 报警复位命令
|
||||
@ -207,7 +166,7 @@ public interface ISIPCommander {
|
||||
* @param alarmMethod 报警方式(可选)
|
||||
* @param alarmType 报警类型(可选)
|
||||
*/
|
||||
void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void alarmResetCmd(Device device, String alarmMethod, String alarmType, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
||||
@ -221,7 +180,7 @@ public interface ISIPCommander {
|
||||
* 看守位控制命令
|
||||
*
|
||||
*/
|
||||
void homePositionCmd(Device device, String channelId, Boolean enabled, Integer resetTime, Integer presetIndex, SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void homePositionCmd(Device device, String channelId, Boolean enabled, Integer resetTime, Integer presetIndex, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 设备配置命令
|
||||
@ -232,30 +191,24 @@ public interface ISIPCommander {
|
||||
|
||||
/**
|
||||
* 设备配置命令:basicParam
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param channelId 通道编码(可选)
|
||||
* @param name 设备/通道名称(可选)
|
||||
* @param expiration 注册过期时间(可选)
|
||||
* @param heartBeatInterval 心跳间隔时间(可选)
|
||||
* @param heartBeatCount 心跳超时次数(可选)
|
||||
*/
|
||||
void deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
*/
|
||||
void deviceBasicConfigCmd(Device device, BasicParam basicParam, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 查询设备状态
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
void deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void deviceStatusQuery(Device device, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 查询设备信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @return
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
void deviceInfoQuery(Device device) throws InvalidArgumentException, SipException, ParseException;
|
||||
void deviceInfoQuery(Device device, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 查询目录列表
|
||||
@ -287,7 +240,7 @@ public interface ISIPCommander {
|
||||
* @return true = 命令发送成功
|
||||
*/
|
||||
void alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod,
|
||||
String alarmType, String startTime, String endTime, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
String alarmType, String startTime, String endTime, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 查询设备配置
|
||||
@ -296,14 +249,14 @@ public interface ISIPCommander {
|
||||
* @param channelId 通道编码(可选)
|
||||
* @param configType 配置类型:
|
||||
*/
|
||||
void deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void deviceConfigQuery(Device device, String channelId, String configType, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 查询设备预置位置
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
void presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void presetQuery(Device device, String channelId, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 查询移动设备位置数据
|
||||
@ -326,7 +279,6 @@ public interface ISIPCommander {
|
||||
* @param expires 订阅过期时间(0 = 取消订阅)
|
||||
* @param startPriority 报警起始级别(可选)
|
||||
* @param endPriority 报警终止级别(可选)
|
||||
* @param alarmType 报警类型
|
||||
* @param startTime 报警发生起始时间(可选)
|
||||
* @param endTime 报警发生终止时间(可选)
|
||||
* @return true = 命令发送成功
|
||||
@ -347,7 +299,7 @@ public interface ISIPCommander {
|
||||
* @param channelId 通道id
|
||||
* @param cmdString 前端控制指令串
|
||||
*/
|
||||
void dragZoomCmd(Device device, String channelId, String cmdString) throws InvalidArgumentException, SipException, ParseException;
|
||||
void dragZoomCmd(Device device, String channelId, String cmdString, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
|
||||
void playbackControlCmd(Device device, DeviceChannel channel, String stream, String content, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException;
|
||||
|
||||
@ -140,13 +140,13 @@ public interface ISIPCommanderForPlatform {
|
||||
* @param sendRtpItem
|
||||
* @return
|
||||
*/
|
||||
void sendMediaStatusNotify(Platform platform, SendRtpInfo sendRtpItem) throws SipException, InvalidArgumentException, ParseException;
|
||||
void sendMediaStatusNotify(Platform platform, SendRtpInfo sendRtpItem, CommonGBChannel channel) throws SipException, InvalidArgumentException, ParseException;
|
||||
|
||||
void streamByeCmd(Platform platform, SendRtpInfo sendRtpItem, CommonGBChannel channel) throws SipException, InvalidArgumentException, ParseException;
|
||||
|
||||
void streamByeCmd(Platform platform, CommonGBChannel channel, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;
|
||||
void streamByeCmd(Platform platform, CommonGBChannel channel, String app, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException;
|
||||
|
||||
void broadcastInviteCmd(Platform platform, CommonGBChannel channel, MediaServer mediaServerItem,
|
||||
void broadcastInviteCmd(Platform platform, CommonGBChannel channel, String sourceId, MediaServer mediaServerItem,
|
||||
SSRCInfo ssrcInfo, HookSubscribe.Event event, SipSubscribe.Event okEvent,
|
||||
SipSubscribe.Event errorEvent) throws ParseException, SipException, InvalidArgumentException;
|
||||
|
||||
|
||||
@ -312,12 +312,12 @@ public class SIPRequestHeaderPlarformProvider {
|
||||
return request;
|
||||
}
|
||||
|
||||
public Request createInviteRequest(Platform platform, String channelId, String content, String viaTag, String fromTag, String ssrc, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
|
||||
public Request createInviteRequest(Platform platform,String sourceId, String channelId, String content, String viaTag, String fromTag, String ssrc, CallIdHeader callIdHeader) throws PeerUnavailableException, ParseException, InvalidArgumentException {
|
||||
Request request = null;
|
||||
//请求行
|
||||
String platformHostAddress = platform.getServerIp() + ":" + platform.getServerPort();
|
||||
String localHostAddress = sipLayer.getLocalIp(platform.getDeviceIp())+":"+ platform.getDevicePort();
|
||||
SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, platformHostAddress);
|
||||
SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(sourceId, platformHostAddress);
|
||||
//via
|
||||
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||
ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipLayer.getLocalIp(platform.getDeviceIp()), platform.getDevicePort(), platform.getTransport(), viaTag);
|
||||
@ -329,7 +329,7 @@ public class SIPRequestHeaderPlarformProvider {
|
||||
Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI);
|
||||
FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
|
||||
//to
|
||||
SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, platformHostAddress);
|
||||
SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sourceId, platformHostAddress);
|
||||
Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI);
|
||||
ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress,null);
|
||||
|
||||
@ -345,7 +345,7 @@ public class SIPRequestHeaderPlarformProvider {
|
||||
Address concatAddress = SipFactory.getInstance().createAddressFactory().createAddress(SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(),localHostAddress));
|
||||
request.addHeader(SipFactory.getInstance().createHeaderFactory().createContactHeader(concatAddress));
|
||||
// Subject
|
||||
SubjectHeader subjectHeader = SipFactory.getInstance().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", sipConfig.getId(), ssrc, channelId, 0));
|
||||
SubjectHeader subjectHeader = SipFactory.getInstance().createHeaderFactory().createSubjectHeader(String.format("%s:%s,%s:%s", sourceId, ssrc, channelId, 0));
|
||||
request.addHeader(subjectHeader);
|
||||
ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("APPLICATION", "SDP");
|
||||
request.setContent(content, contentTypeHeader);
|
||||
|
||||
@ -7,7 +7,9 @@ import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.MessageSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.event.sip.MessageEvent;
|
||||
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.SIPSender;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
@ -19,8 +21,10 @@ import com.genersoft.iot.vmp.media.event.hook.Hook;
|
||||
import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.event.hook.HookType;
|
||||
import com.genersoft.iot.vmp.media.service.IMediaServerService;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import gov.nist.javax.sip.message.SIPRequest;
|
||||
import gov.nist.javax.sip.message.SIPResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -71,59 +75,8 @@ public class SIPCommander implements ISIPCommander {
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 云台方向放控制,使用配置文件中的默认镜头移动速度
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
*/
|
||||
@Override
|
||||
public void ptzdirectCmd(Device device, String channelId, int leftRight, int upDown) throws InvalidArgumentException, ParseException, SipException {
|
||||
ptzCmd(device, channelId, leftRight, upDown, 0, sipConfig.getPtzSpeed(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台方向放控制
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param moveSpeed 镜头移动速度
|
||||
*/
|
||||
@Override
|
||||
public void ptzdirectCmd(Device device, String channelId, int leftRight, int upDown, int moveSpeed) throws InvalidArgumentException, ParseException, SipException {
|
||||
ptzCmd(device, channelId, leftRight, upDown, 0, moveSpeed, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台缩放控制,使用配置文件中的默认镜头缩放速度
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
*/
|
||||
@Override
|
||||
public void ptzZoomCmd(Device device, String channelId, int inOut) throws InvalidArgumentException, ParseException, SipException {
|
||||
ptzCmd(device, channelId, 0, 0, inOut, 0, sipConfig.getPtzSpeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台缩放控制
|
||||
*
|
||||
* @param device 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
* @param zoomSpeed 镜头缩放速度
|
||||
*/
|
||||
@Override
|
||||
public void ptzZoomCmd(Device device, String channelId, int inOut, int zoomSpeed) throws InvalidArgumentException, ParseException, SipException {
|
||||
ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed);
|
||||
}
|
||||
@Autowired
|
||||
private MessageSubscribe messageSubscribe;
|
||||
|
||||
/**
|
||||
* 云台指令码计算
|
||||
@ -211,9 +164,6 @@ public class SIPCommander implements ISIPCommander {
|
||||
ptzXml.append("</Info>\r\n");
|
||||
ptzXml.append("</Control>\r\n");
|
||||
|
||||
|
||||
|
||||
|
||||
SIPRequest request = (SIPRequest) headerProvider.createMessageRequest(device, ptzXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request);
|
||||
|
||||
@ -332,14 +282,15 @@ public class SIPCommander implements ISIPCommander {
|
||||
|
||||
Request request = headerProvider.createInviteRequest(device, channel.getDeviceId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> {
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||
errorEvent.response(e);
|
||||
}), e -> {
|
||||
ResponseEvent responseEvent = (ResponseEvent) e.event;
|
||||
SIPResponse response = (SIPResponse) responseEvent.getResponse();
|
||||
String callId = response.getCallIdHeader().getCallId();
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), callId, stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response,
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(),
|
||||
callId,ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response,
|
||||
InviteSessionType.PLAY);
|
||||
sessionManager.put(ssrcTransaction);
|
||||
okEvent.response(e);
|
||||
@ -435,7 +386,9 @@ public class SIPCommander implements ISIPCommander {
|
||||
ResponseEvent responseEvent = (ResponseEvent) event.event;
|
||||
SIPResponse response = (SIPResponse) responseEvent.getResponse();
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(),
|
||||
channel.getId(), sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAYBACK);
|
||||
channel.getId(), sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),
|
||||
device.getTransport()).getCallId(), ssrcInfo.getApp(), ssrcInfo.getStream(), ssrcInfo.getSsrc(),
|
||||
mediaServerItem.getId(), response, InviteSessionType.PLAYBACK);
|
||||
sessionManager.put(ssrcTransaction);
|
||||
okEvent.response(event);
|
||||
}, timeout);
|
||||
@ -526,7 +479,9 @@ public class SIPCommander implements ISIPCommander {
|
||||
SIPResponse response = (SIPResponse) responseEvent.getResponse();
|
||||
String contentString =new String(response.getRawContent());
|
||||
String ssrc = SipUtils.getSsrcFromSdp(contentString);
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD);
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(),
|
||||
response.getCallIdHeader().getCallId(), ssrcInfo.getApp(), ssrcInfo.getStream(), ssrc,
|
||||
mediaServerItem.getId(), response, InviteSessionType.DOWNLOAD);
|
||||
sessionManager.put(ssrcTransaction);
|
||||
okEvent.response(event);
|
||||
}, timeout);
|
||||
@ -586,32 +541,24 @@ public class SIPCommander implements ISIPCommander {
|
||||
Request request = headerProvider.createInviteRequest(device, channel.getDeviceId(), content.toString(),
|
||||
SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, sendRtpItem.getSsrc(), callIdHeader);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> {
|
||||
sessionManager.removeByStream(sendRtpItem.getStream());
|
||||
sessionManager.removeByStream(sendRtpItem.getApp(), sendRtpItem.getStream());
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
|
||||
errorEvent.response(e);
|
||||
}), e -> {
|
||||
// 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
|
||||
ResponseEvent responseEvent = (ResponseEvent) e.event;
|
||||
SIPResponse response = (SIPResponse) responseEvent.getResponse();
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), "talk", stream, sendRtpItem.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.TALK);
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForDevice(device.getDeviceId(), channel.getId(), "talk",sendRtpItem.getApp(), stream, sendRtpItem.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.TALK);
|
||||
sessionManager.put(ssrcTransaction);
|
||||
okEvent.response(e);
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频流停止, 不使用回调
|
||||
*/
|
||||
@Override
|
||||
public void streamByeCmd(Device device, String channelId, String stream, String callId) throws InvalidArgumentException, ParseException, SipException, SsrcTransactionNotFoundException {
|
||||
streamByeCmd(device, channelId, stream, callId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频流停止
|
||||
*/
|
||||
@Override
|
||||
public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
|
||||
public void streamByeCmd(Device device, String channelId, String app, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
|
||||
if (device == null) {
|
||||
log.warn("[发送BYE] device为null");
|
||||
return;
|
||||
@ -620,7 +567,7 @@ public class SIPCommander implements ISIPCommander {
|
||||
if (callId != null) {
|
||||
ssrcTransaction = sessionManager.getSsrcTransactionByCallId(callId);
|
||||
}else if (stream != null) {
|
||||
ssrcTransaction = sessionManager.getSsrcTransactionByStream(stream);
|
||||
ssrcTransaction = sessionManager.getSsrcTransactionByStream(app, stream);
|
||||
}
|
||||
|
||||
if (ssrcTransaction == null) {
|
||||
@ -677,13 +624,16 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param recordCmdStr 录像命令:Record / StopRecord
|
||||
*/
|
||||
@Override
|
||||
public void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void recordCmd(Device device, String channelId, String recordCmdStr, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
final String cmdType = "DeviceControl";
|
||||
final int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Control>\r\n");
|
||||
cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
if (ObjectUtils.isEmpty(channelId)) {
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
} else {
|
||||
@ -692,10 +642,14 @@ public class SIPCommander implements ISIPCommander {
|
||||
cmdXml.append("<RecordCmd>" + recordCmdStr + "</RecordCmd>\r\n");
|
||||
cmdXml.append("</Control>\r\n");
|
||||
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", channelId, 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
},null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -729,22 +683,29 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param guardCmdStr "SetGuard"/"ResetGuard"
|
||||
*/
|
||||
@Override
|
||||
public void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void guardCmd(Device device, String guardCmdStr, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "DeviceControl";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Control>\r\n");
|
||||
cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
cmdXml.append("<GuardCmd>" + guardCmdStr + "</GuardCmd>\r\n");
|
||||
cmdXml.append("</Control>\r\n");
|
||||
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", device.getDeviceId(), 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -753,14 +714,17 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void alarmResetCmd(Device device, String alarmMethod, String alarmType, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "DeviceControl";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Control>\r\n");
|
||||
cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
cmdXml.append("<AlarmCmd>ResetAlarm</AlarmCmd>\r\n");
|
||||
if (!ObjectUtils.isEmpty(alarmMethod) || !ObjectUtils.isEmpty(alarmType)) {
|
||||
@ -777,10 +741,14 @@ public class SIPCommander implements ISIPCommander {
|
||||
}
|
||||
cmdXml.append("</Control>\r\n");
|
||||
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", device.getDeviceId(), 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -822,19 +790,21 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
||||
*/
|
||||
@Override
|
||||
public void homePositionCmd(Device device, String channelId, Boolean enabled, Integer resetTime, Integer presetIndex, SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void homePositionCmd(Device device, String channelId, Boolean enabled, Integer resetTime, Integer presetIndex, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "DeviceControl";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Control>\r\n");
|
||||
cmdXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
if (ObjectUtils.isEmpty(channelId)) {
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
} else {
|
||||
cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
||||
channelId = device.getDeviceId();
|
||||
}
|
||||
cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
||||
cmdXml.append("<HomePosition>\r\n");
|
||||
if (enabled) {
|
||||
cmdXml.append("<Enabled>1</Enabled>\r\n");
|
||||
@ -846,10 +816,14 @@ public class SIPCommander implements ISIPCommander {
|
||||
cmdXml.append("</HomePosition>\r\n");
|
||||
cmdXml.append("</Control>\r\n");
|
||||
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", channelId, 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -864,55 +838,50 @@ public class SIPCommander implements ISIPCommander {
|
||||
|
||||
/**
|
||||
* 设备配置命令:basicParam
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param channelId 通道编码(可选)
|
||||
* @param name 设备/通道名称(可选)
|
||||
* @param expiration 注册过期时间(可选)
|
||||
* @param heartBeatInterval 心跳间隔时间(可选)
|
||||
* @param heartBeatCount 心跳超时次数(可选)
|
||||
*/
|
||||
@Override
|
||||
public void deviceBasicConfigCmd(Device device, String channelId, String name, String expiration,
|
||||
String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void deviceBasicConfigCmd(Device device, BasicParam basicParam, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
String cmdType = "DeviceConfig";
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Control>\r\n");
|
||||
cmdXml.append("<CmdType>DeviceConfig</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
String channelId = basicParam.getChannelId();
|
||||
if (ObjectUtils.isEmpty(channelId)) {
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
} else {
|
||||
cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
||||
channelId = device.getDeviceId();
|
||||
}
|
||||
cmdXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
||||
cmdXml.append("<BasicParam>\r\n");
|
||||
if (!ObjectUtils.isEmpty(name)) {
|
||||
cmdXml.append("<Name>" + name + "</Name>\r\n");
|
||||
if (!ObjectUtils.isEmpty(basicParam.getName())) {
|
||||
cmdXml.append("<Name>" + basicParam.getName() + "</Name>\r\n");
|
||||
}
|
||||
if (NumericUtil.isInteger(expiration)) {
|
||||
if (Integer.valueOf(expiration) > 0) {
|
||||
cmdXml.append("<Expiration>" + expiration + "</Expiration>\r\n");
|
||||
if (NumericUtil.isInteger(basicParam.getExpiration())) {
|
||||
if (Integer.parseInt(basicParam.getExpiration()) > 0) {
|
||||
cmdXml.append("<Expiration>" + basicParam.getExpiration() + "</Expiration>\r\n");
|
||||
}
|
||||
}
|
||||
if (NumericUtil.isInteger(heartBeatInterval)) {
|
||||
if (Integer.valueOf(heartBeatInterval) > 0) {
|
||||
cmdXml.append("<HeartBeatInterval>" + heartBeatInterval + "</HeartBeatInterval>\r\n");
|
||||
}
|
||||
if (basicParam.getHeartBeatInterval() != null && basicParam.getHeartBeatInterval() > 0) {
|
||||
cmdXml.append("<HeartBeatInterval>" + basicParam.getHeartBeatInterval() + "</HeartBeatInterval>\r\n");
|
||||
}
|
||||
if (NumericUtil.isInteger(heartBeatCount)) {
|
||||
if (Integer.valueOf(heartBeatCount) > 0) {
|
||||
cmdXml.append("<HeartBeatCount>" + heartBeatCount + "</HeartBeatCount>\r\n");
|
||||
}
|
||||
if (basicParam.getHeartBeatCount() != null && basicParam.getHeartBeatCount() > 0) {
|
||||
cmdXml.append("<HeartBeatCount>" + basicParam.getHeartBeatCount() + "</HeartBeatCount>\r\n");
|
||||
}
|
||||
cmdXml.append("</BasicParam>\r\n");
|
||||
cmdXml.append("</Control>\r\n");
|
||||
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", channelId, 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, 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, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -921,46 +890,63 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public void deviceStatusQuery(Device device, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void deviceStatusQuery(Device device, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "DeviceStatus";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
String charset = device.getCharset();
|
||||
StringBuffer catalogXml = new StringBuffer(200);
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
catalogXml.append("<Query>\r\n");
|
||||
catalogXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
catalogXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
catalogXml.append("</Query>\r\n");
|
||||
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", device.getDeviceId(), 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), null, 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, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param device 视频设备
|
||||
* @param callback
|
||||
*/
|
||||
@Override
|
||||
public void deviceInfoQuery(Device device) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void deviceInfoQuery(Device device, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "DeviceInfo";
|
||||
String sn = (int) ((Math.random() * 9 + 1) * 100000) + "";
|
||||
|
||||
StringBuffer catalogXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
catalogXml.append("<Query>\r\n");
|
||||
catalogXml.append("<CmdType>DeviceInfo</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
catalogXml.append("<CmdType>" + cmdType +"</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
catalogXml.append("</Query>\r\n");
|
||||
|
||||
|
||||
MessageEvent<Object> messageEvent = MessageEvent.getInstance(cmdType, sn, device.getDeviceId(), 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
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);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
if (callback != null) {
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -1046,14 +1032,17 @@ public class SIPCommander implements ISIPCommander {
|
||||
*/
|
||||
@Override
|
||||
public void alarmInfoQuery(Device device, String startPriority, String endPriority, String alarmMethod, String alarmType,
|
||||
String startTime, String endTime, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
String startTime, String endTime, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "Alarm";
|
||||
String sn = (int) ((Math.random() * 9 + 1) * 100000) + "";
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Query>\r\n");
|
||||
cmdXml.append("<CmdType>Alarm</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
if (!ObjectUtils.isEmpty(startPriority)) {
|
||||
cmdXml.append("<StartAlarmPriority>" + startPriority + "</StartAlarmPriority>\r\n");
|
||||
@ -1075,10 +1064,14 @@ public class SIPCommander implements ISIPCommander {
|
||||
}
|
||||
cmdXml.append("</Query>\r\n");
|
||||
|
||||
|
||||
MessageEvent<Object> messageEvent = MessageEvent.getInstance(cmdType, sn, device.getDeviceId(), 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, 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, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1089,14 +1082,16 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param configType 配置类型:
|
||||
*/
|
||||
@Override
|
||||
public void deviceConfigQuery(Device device, String channelId, String configType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void deviceConfigQuery(Device device, String channelId, String configType, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "ConfigDownload";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Query>\r\n");
|
||||
cmdXml.append("<CmdType>ConfigDownload</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
if (ObjectUtils.isEmpty(channelId)) {
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
} else {
|
||||
@ -1105,10 +1100,16 @@ public class SIPCommander implements ISIPCommander {
|
||||
cmdXml.append("<ConfigType>" + configType + "</ConfigType>\r\n");
|
||||
cmdXml.append("</Query>\r\n");
|
||||
|
||||
|
||||
MessageEvent<Object> messageEvent = MessageEvent.getInstance(cmdType, sn + "", channelId, 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, 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, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
if (callback != null) {
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1117,14 +1118,17 @@ public class SIPCommander implements ISIPCommander {
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public void presetQuery(Device device, String channelId, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void presetQuery(Device device, String channelId, ErrorCallback<Object> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "PresetQuery";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
cmdXml.append("<Query>\r\n");
|
||||
cmdXml.append("<CmdType>PresetQuery</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
cmdXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
cmdXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
if (ObjectUtils.isEmpty(channelId)) {
|
||||
cmdXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
} else {
|
||||
@ -1132,9 +1136,14 @@ public class SIPCommander implements ISIPCommander {
|
||||
}
|
||||
cmdXml.append("</Query>\r\n");
|
||||
|
||||
MessageEvent<Object> messageEvent = MessageEvent.getInstance(cmdType, sn + "", channelId, 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, 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, eventResult -> {
|
||||
messageSubscribe.removeSubscribe(messageEvent.getKey());
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "失败," + eventResult.msg, null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1273,14 +1282,17 @@ public class SIPCommander implements ISIPCommander {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragZoomCmd(Device device, String channelId, String cmdString) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void dragZoomCmd(Device device, String channelId, String cmdString, ErrorCallback<String> callback) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
String cmdType = "DeviceControl";
|
||||
int sn = (int) ((Math.random() * 9 + 1) * 100000);
|
||||
|
||||
StringBuffer dragXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
dragXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
dragXml.append("<Control>\r\n");
|
||||
dragXml.append("<CmdType>DeviceControl</CmdType>\r\n");
|
||||
dragXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
dragXml.append("<CmdType>" + cmdType + "</CmdType>\r\n");
|
||||
dragXml.append("<SN>" + sn + "</SN>\r\n");
|
||||
if (ObjectUtils.isEmpty(channelId)) {
|
||||
dragXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
} else {
|
||||
@ -1289,8 +1301,10 @@ public class SIPCommander implements ISIPCommander {
|
||||
dragXml.append(cmdString);
|
||||
dragXml.append("</Control>\r\n");
|
||||
|
||||
MessageEvent<String> messageEvent = MessageEvent.getInstance(cmdType, sn + "", channelId, 1000L, callback);
|
||||
messageSubscribe.addSubscribe(messageEvent);
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, dragXml.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()));
|
||||
log.debug("拉框信令: " + request.toString());
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()),request);
|
||||
}
|
||||
|
||||
@ -1362,7 +1376,7 @@ public class SIPCommander implements ISIPCommander {
|
||||
@Override
|
||||
public void playbackControlCmd(Device device, DeviceChannel channel, String stream, String content, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
|
||||
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream(stream);
|
||||
SsrcTransaction ssrcTransaction = sessionManager.getSsrcTransactionByStream("rtp", stream);
|
||||
if (ssrcTransaction == null) {
|
||||
log.info("[回放控制]未找到视频流信息,设备:{}, 流ID: {}", device.getDeviceId(), stream);
|
||||
return;
|
||||
|
||||
@ -59,9 +59,6 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
|
||||
@Autowired
|
||||
private SipSubscribe sipSubscribe;
|
||||
|
||||
@Autowired
|
||||
private SipLayer sipLayer;
|
||||
|
||||
@ -599,24 +596,23 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMediaStatusNotify(Platform parentPlatform, SendRtpInfo sendRtpItem) throws SipException, InvalidArgumentException, ParseException {
|
||||
if (sendRtpItem == null || parentPlatform == null) {
|
||||
public void sendMediaStatusNotify(Platform parentPlatform, SendRtpInfo sendRtpInfo, CommonGBChannel channel) throws SipException, InvalidArgumentException, ParseException {
|
||||
if (channel == null || parentPlatform == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer mediaStatusXml = new StringBuffer(200);
|
||||
mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Notify>\r\n")
|
||||
.append("<CmdType>MediaStatus</CmdType>\r\n")
|
||||
.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n")
|
||||
.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n")
|
||||
.append("<DeviceID>" + channel.getGbDeviceId() + "</DeviceID>\r\n")
|
||||
.append("<NotifyType>121</NotifyType>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
|
||||
SIPRequest messageRequest = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(parentPlatform, mediaStatusXml.toString(),
|
||||
sendRtpItem);
|
||||
sendRtpInfo);
|
||||
|
||||
sipSender.transmitRequest(parentPlatform.getDeviceIp(),messageRequest);
|
||||
|
||||
@ -647,13 +643,13 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void streamByeCmd(Platform platform, CommonGBChannel channel, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
|
||||
public void streamByeCmd(Platform platform, CommonGBChannel channel, String app, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
|
||||
|
||||
SsrcTransaction ssrcTransaction = null;
|
||||
if (callId != null) {
|
||||
ssrcTransaction = sessionManager.getSsrcTransactionByCallId(callId);
|
||||
}else if (stream != null) {
|
||||
ssrcTransaction = sessionManager.getSsrcTransactionByStream(stream);
|
||||
ssrcTransaction = sessionManager.getSsrcTransactionByStream(app, stream);
|
||||
}
|
||||
if (ssrcTransaction == null) {
|
||||
throw new SsrcTransactionNotFoundException(platform.getServerGBId(), channel.getGbDeviceId(), callId, stream);
|
||||
@ -661,7 +657,7 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
|
||||
mediaServerService.releaseSsrc(ssrcTransaction.getMediaServerId(), ssrcTransaction.getSsrc());
|
||||
mediaServerService.closeRTPServer(ssrcTransaction.getMediaServerId(), ssrcTransaction.getStream());
|
||||
sessionManager.removeByStream(ssrcTransaction.getStream());
|
||||
sessionManager.removeByStream(ssrcTransaction.getApp(), ssrcTransaction.getStream());
|
||||
|
||||
Request byteRequest = headerProviderPlatformProvider.createByteRequest(platform, channel.getGbDeviceId(), ssrcTransaction.getSipTransactionInfo());
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), byteRequest, null, okEvent);
|
||||
@ -691,7 +687,7 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastInviteCmd(Platform platform, CommonGBChannel channel, MediaServer mediaServerItem,
|
||||
public void broadcastInviteCmd(Platform platform, CommonGBChannel channel,String sourceId, MediaServer mediaServerItem,
|
||||
SSRCInfo ssrcInfo, HookSubscribe.Event event, SipSubscribe.Event okEvent,
|
||||
SipSubscribe.Event errorEvent) throws ParseException, SipException, InvalidArgumentException {
|
||||
String stream = ssrcInfo.getStream();
|
||||
@ -712,8 +708,9 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
|
||||
StringBuffer content = new StringBuffer(200);
|
||||
content.append("v=0\r\n");
|
||||
content.append("o=" + channel.getGbDeviceId() + " 0 0 IN IP4 " + sdpIp + "\r\n");
|
||||
content.append("o=" + platform.getDeviceGBId() + " 0 0 IN IP4 " + sdpIp + "\r\n");
|
||||
content.append("s=Play\r\n");
|
||||
content.append("u=" + channel.getGbDeviceId() + ":0\r\n");
|
||||
content.append("c=IN IP4 " + sdpIp + "\r\n");
|
||||
content.append("t=0 0\r\n");
|
||||
|
||||
@ -738,21 +735,22 @@ public class SIPCommanderForPlatform implements ISIPCommanderForPlatform {
|
||||
|
||||
content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
|
||||
// f字段:f= v/编码格式/分辨率/帧率/码率类型/码率大小a/编码格式/码率大小/采样率
|
||||
content.append("f=v/////a/1/8/1\r\n");
|
||||
content.append("f=v/2/5/25/1/4096a/1/8/1\r\n");
|
||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(platform.getDeviceIp()), platform.getTransport());
|
||||
|
||||
Request request = headerProviderPlatformProvider.createInviteRequest(platform, channel.getGbDeviceId(),
|
||||
Request request = headerProviderPlatformProvider.createInviteRequest(platform, sourceId, channel.getGbDeviceId(),
|
||||
content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), ssrcInfo.getSsrc(),
|
||||
callIdHeader);
|
||||
sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> {
|
||||
sessionManager.removeByStream(ssrcInfo.getStream());
|
||||
sessionManager.removeByStream(ssrcInfo.getApp(), ssrcInfo.getStream());
|
||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
|
||||
subscribe.removeSubscribe(hook);
|
||||
errorEvent.response(e);
|
||||
}), e -> {
|
||||
ResponseEvent responseEvent = (ResponseEvent) e.event;
|
||||
SIPResponse response = (SIPResponse) responseEvent.getResponse();
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForPlatform(platform.getServerGBId(), channel.getGbId(), callIdHeader.getCallId(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.BROADCAST);
|
||||
SsrcTransaction ssrcTransaction = SsrcTransaction.buildForPlatform(platform.getServerGBId(), channel.getGbId(),
|
||||
callIdHeader.getCallId(), ssrcInfo.getApp(), stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.BROADCAST);
|
||||
sessionManager.put(ssrcTransaction);
|
||||
okEvent.response(e);
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user