Merge branch 'main' into main2
# Conflicts: # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java结构优化
commit
197f80581b
doc/_content/introduction
sql
src/main
java/com/genersoft/iot/vmp
common/enums
gb28181
event/record
transmit
event/request
utils
vmanager
gb28181
device
playback
resources
web_src
build
config
src/components
dialog
|
@ -98,6 +98,7 @@ https://gitee.com/pan648540858/wvp-GB28181-pro.git
|
|||
- [X] 支持推流鉴权
|
||||
- [X] 支持接口鉴权
|
||||
- [X] 云端录像,推流/代理/国标视频均可以录制在云端服务器,支持预览和下载
|
||||
- [X] 支持打包可执行jar和war
|
||||
|
||||
|
||||
# 遇到问题如何解决
|
||||
|
|
|
@ -77,13 +77,18 @@ npm run build
|
|||
**编译完成一般是这个样子,中间没有报红的错误信息**
|
||||

|
||||
|
||||
### 5.3 打包项目, 生成可执行jar
|
||||
### 5.3 生成可执行jar
|
||||
```bash
|
||||
cd wvp-GB28181-pro
|
||||
mvn package
|
||||
```
|
||||
### 5.4 生成war
|
||||
```bash
|
||||
cd wvp-GB28181-pro
|
||||
mvn package -P war
|
||||
```
|
||||
编译如果报错, 一般都是网络问题, 导致的依赖包下载失败
|
||||
编译完成后在target目录下出现wvp-pro-***.jar。
|
||||
编译完成后在target目录下出现wvp-pro-***.jar/wvp-pro-***.war。
|
||||
接下来[配置服务](./_content/introduction/config.md)
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ java -jar wvp-pro-*.jar
|
|||
## 2 配置WVP-PRO
|
||||
### 2.1 Mysql数据库配置
|
||||
首先你需要创建一个名为wvp(也可使用其他名字)的数据库,并使用sql/mysql.sql导入数据库,初始化数据库结构。
|
||||
(这里注意,取决于版本,新版的sql文件夹下有update.sql,补丁包,一定要注意运行导入)
|
||||
在application-dev.yml中配置(使用1.2方式的是在jar包的同级目录的application.yml)配置数据库连接,包括数据库连接信息,密码。
|
||||
### 2.2 Redis数据库配置
|
||||
配置wvp中的redis连接信息,建议wvp自己单独使用一个db。
|
||||
|
@ -116,4 +117,4 @@ user-settings:
|
|||
|
||||
|
||||
如果配置信息无误,你可以启动zlm,再启动wvp来测试了,启动成功的话,你可以在wvp的日志下看到zlm已连接的提示。
|
||||
接下来[部署到服务器](./_content/introduction/deployment.md), 如何你只是本地运行直接再本地运行即可。
|
||||
接下来[部署到服务器](./_content/introduction/deployment.md), 如何你只是本地运行直接再本地运行即可。
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
```shell
|
||||
nohup java -jar wvp-pro-*.jar &
|
||||
```
|
||||
|
||||
war包:
|
||||
下载Tomcat后将war包放入webapps中,启动Tomcat以解压war包,停止Tomcat后,删除ROOT目录以及war包,将解压后的war包目录重命名为ROOT,
|
||||
然后启动Tomcat。
|
||||
**启动ZLM**
|
||||
```shell
|
||||
nohup ./MediaServer -d -m 3 &
|
||||
|
|
39
pom.xml
39
pom.xml
|
@ -14,6 +14,7 @@
|
|||
<version>2.6.7</version>
|
||||
<name>web video platform</name>
|
||||
<description>国标28181视频平台</description>
|
||||
<packaging>${project.packaging}</packaging>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
|
@ -56,6 +57,42 @@
|
|||
<asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>jar</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.packaging>jar</project.packaging>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>war</id>
|
||||
<properties>
|
||||
<project.packaging>war</project.packaging>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -242,8 +279,8 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<!-- <scope>test</scope>-->
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
-- 2.6.6->2.6.7
|
||||
alter table device
|
||||
add keepaliveIntervalTime int default null;
|
|
@ -1,20 +1,24 @@
|
|||
package com.genersoft.iot.vmp;
|
||||
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.druid.EnableDruidSupport;
|
||||
import com.genersoft.iot.vmp.storager.impl.RedisCatchStorageImpl;
|
||||
import com.genersoft.iot.vmp.utils.GitUtil;
|
||||
import com.genersoft.iot.vmp.utils.SpringBeanFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.SessionCookieConfig;
|
||||
import javax.servlet.SessionTrackingMode;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* 启动类
|
||||
*/
|
||||
|
@ -22,7 +26,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@EnableDruidSupport
|
||||
public class VManageBootstrap extends LogManager {
|
||||
public class VManageBootstrap extends SpringBootServletInitializer {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class);
|
||||
|
||||
|
@ -41,6 +45,21 @@ public class VManageBootstrap extends LogManager {
|
|||
context.close();
|
||||
VManageBootstrap.context = SpringApplication.run(VManageBootstrap.class, args);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
return application.sources(VManageBootstrap.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
super.onStartup(servletContext);
|
||||
|
||||
servletContext.setSessionTrackingModes(
|
||||
Collections.singleton(SessionTrackingMode.COOKIE)
|
||||
);
|
||||
SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
|
||||
sessionCookieConfig.setHttpOnly(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package com.genersoft.iot.vmp.common.enums;
|
||||
|
||||
import org.dom4j.Element;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
|
||||
/**
|
||||
* @author gaofuwang
|
||||
* @date 2023/01/18/ 10:09:00
|
||||
* @since 1.0
|
||||
*/
|
||||
public enum DeviceControlType {
|
||||
|
||||
/**
|
||||
* 云台控制
|
||||
* 上下左右,预置位,扫描,辅助功能,巡航
|
||||
*/
|
||||
PTZ("PTZCmd","云台控制"),
|
||||
/**
|
||||
* 远程启动
|
||||
*/
|
||||
TELE_BOOT("TeleBoot","远程启动"),
|
||||
/**
|
||||
* 录像控制
|
||||
*/
|
||||
RECORD("RecordCmd","录像控制"),
|
||||
/**
|
||||
* 布防撤防
|
||||
*/
|
||||
GUARD("GuardCmd","布防撤防"),
|
||||
/**
|
||||
* 告警控制
|
||||
*/
|
||||
ALARM("AlarmCmd","告警控制"),
|
||||
/**
|
||||
* 强制关键帧
|
||||
*/
|
||||
I_FRAME("IFameCmd","强制关键帧"),
|
||||
/**
|
||||
* 拉框放大
|
||||
*/
|
||||
DRAG_ZOOM_IN("DragZoomIn","拉框放大"),
|
||||
/**
|
||||
* 拉框缩小
|
||||
*/
|
||||
DRAG_ZOOM_OUT("DragZoomOut","拉框缩小"),
|
||||
/**
|
||||
* 看守位
|
||||
*/
|
||||
HOME_POSITION("HomePosition","看守位");
|
||||
|
||||
private final String val;
|
||||
|
||||
private final String desc;
|
||||
|
||||
DeviceControlType(String val, String desc) {
|
||||
this.val = val;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getVal() {
|
||||
return val;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public static DeviceControlType typeOf(Element rootElement) {
|
||||
for (DeviceControlType item : DeviceControlType.values()) {
|
||||
if (!ObjectUtils.isEmpty(rootElement.element(item.val)) || !ObjectUtils.isEmpty(rootElement.elements(item.val))) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
|
@ -23,6 +24,7 @@ import java.io.IOException;
|
|||
* @author lin
|
||||
*/
|
||||
@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/api/*", asyncSupported=true)
|
||||
@Component
|
||||
public class ApiAccessFilter extends OncePerRequestFilter {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ApiAccessFilter.class);
|
||||
|
@ -48,7 +50,7 @@ public class ApiAccessFilter extends OncePerRequestFilter {
|
|||
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
|
||||
if (uriName != null && userSetting.getLogInDatebase()) {
|
||||
if (uriName != null && userSetting != null && userSetting.getLogInDatebase() != null && userSetting.getLogInDatebase()) {
|
||||
|
||||
LogDto logDto = new LogDto();
|
||||
logDto.setName(uriName);
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.conf;
|
|||
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||
import org.apache.catalina.connector.ClientAbortException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
|
@ -15,11 +14,9 @@ import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
|
||||
|
@ -77,9 +74,7 @@ public class ProxyServletConfig {
|
|||
} catch (IOException ioException) {
|
||||
if (ioException instanceof ConnectException) {
|
||||
logger.error("zlm 连接失败");
|
||||
} else if (ioException instanceof ClientAbortException) {
|
||||
logger.error("zlm: 用户已中断连接,代理终止");
|
||||
} else {
|
||||
} else {
|
||||
logger.error("zlm 代理失败: ", e);
|
||||
}
|
||||
} catch (RuntimeException exception){
|
||||
|
@ -195,9 +190,7 @@ public class ProxyServletConfig {
|
|||
} catch (IOException ioException) {
|
||||
if (ioException instanceof ConnectException) {
|
||||
logger.error("录像服务 连接失败");
|
||||
} else if (ioException instanceof ClientAbortException) {
|
||||
logger.error("录像服务:用户已中断连接,代理终止");
|
||||
} else {
|
||||
}else {
|
||||
logger.error("录像服务 代理失败: ", e);
|
||||
}
|
||||
} catch (RuntimeException exception){
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.genersoft.iot.vmp.conf;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.web.context.WebServerInitializedEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ServiceInfo implements ApplicationListener<WebServerInitializedEvent> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ServiceInfo.class);
|
||||
|
||||
private static int serverPort;
|
||||
|
||||
public static int getServerPort() {
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(WebServerInitializedEvent event) {
|
||||
// 项目启动获取启动的端口号
|
||||
ServiceInfo.serverPort = event.getWebServer().getPort();
|
||||
logger.info("项目启动获取启动的端口号: " + ServiceInfo.serverPort);
|
||||
}
|
||||
|
||||
public void setServerPort(int serverPort) {
|
||||
ServiceInfo.serverPort = serverPort;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.genersoft.iot.vmp.conf.security;
|
||||
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.SessionCookieConfig;
|
||||
import javax.servlet.SessionTrackingMode;
|
||||
import java.util.Collections;
|
||||
|
||||
public class UrlTokenHandler extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
super.onStartup(servletContext);
|
||||
|
||||
servletContext.setSessionTrackingModes(
|
||||
Collections.singleton(SessionTrackingMode.COOKIE)
|
||||
);
|
||||
SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
|
||||
sessionCookieConfig.setHttpOnly(true);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
/**
|
||||
* 通过redis分发报警消息
|
||||
*/
|
||||
|
@ -8,12 +9,14 @@ public class AlarmChannelMessage {
|
|||
* 国标编号
|
||||
*/
|
||||
private String gbId;
|
||||
|
||||
/**
|
||||
* 报警编号
|
||||
*/
|
||||
private int alarmSn;
|
||||
|
||||
/**
|
||||
* 告警类型
|
||||
*/
|
||||
private int alarmType;
|
||||
|
||||
/**
|
||||
* 报警描述
|
||||
|
@ -36,6 +39,14 @@ public class AlarmChannelMessage {
|
|||
this.alarmSn = alarmSn;
|
||||
}
|
||||
|
||||
public int getAlarmType() {
|
||||
return alarmType;
|
||||
}
|
||||
|
||||
public void setAlarmType(int alarmType) {
|
||||
this.alarmType = alarmType;
|
||||
}
|
||||
|
||||
public String getAlarmDescription() {
|
||||
return alarmDescription;
|
||||
}
|
||||
|
|
|
@ -37,4 +37,18 @@ public enum DeviceAlarmMethod {
|
|||
public int getVal() {
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询是否匹配类型
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
public static DeviceAlarmMethod typeOf(int code) {
|
||||
for (DeviceAlarmMethod item : DeviceAlarmMethod.values()) {
|
||||
if (code==item.getVal()) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
|
||||
|
||||
/**
|
||||
* 设备信息查询响应
|
||||
*
|
||||
* @author Y.G
|
||||
* @version 1.0
|
||||
* @date 2022/6/28 14:55
|
||||
*/
|
||||
public class DragZoomRequest {
|
||||
/**
|
||||
* 序列号
|
||||
*/
|
||||
@MessageElement("SN")
|
||||
private String sn;
|
||||
|
||||
@MessageElement("DeviceID")
|
||||
private String deviceId;
|
||||
|
||||
@MessageElement(value = "DragZoomIn")
|
||||
private DragZoom dragZoomIn;
|
||||
|
||||
@MessageElement(value = "DragZoomOut")
|
||||
private DragZoom 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,94 @@
|
|||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.utils.MessageElement;
|
||||
|
||||
/**
|
||||
* 设备信息查询响应
|
||||
*
|
||||
* @author Y.G
|
||||
* @version 1.0
|
||||
* @date 2022/6/28 14:55
|
||||
*/
|
||||
public class HomePositionRequest {
|
||||
/**
|
||||
* 序列号
|
||||
*/
|
||||
@MessageElement("SN")
|
||||
private String sn;
|
||||
|
||||
@MessageElement("DeviceID")
|
||||
private String deviceId;
|
||||
|
||||
@MessageElement(value = "HomePosition")
|
||||
private HomePosition homePosition;
|
||||
|
||||
|
||||
/**
|
||||
* 基本参数
|
||||
*/
|
||||
public static class HomePosition {
|
||||
/**
|
||||
* 播放窗口长度像素值
|
||||
*/
|
||||
@MessageElement("Enabled")
|
||||
protected String enabled;
|
||||
/**
|
||||
* 播放窗口宽度像素值
|
||||
*/
|
||||
@MessageElement("ResetTime")
|
||||
protected String resetTime;
|
||||
/**
|
||||
* 拉框中心的横轴坐标像素值
|
||||
*/
|
||||
@MessageElement("PresetIndex")
|
||||
protected String presetIndex;
|
||||
|
||||
public String getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(String enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getResetTime() {
|
||||
return resetTime;
|
||||
}
|
||||
|
||||
public void setResetTime(String resetTime) {
|
||||
this.resetTime = resetTime;
|
||||
}
|
||||
|
||||
public String getPresetIndex() {
|
||||
return presetIndex;
|
||||
}
|
||||
|
||||
public void setPresetIndex(String presetIndex) {
|
||||
this.presetIndex = presetIndex;
|
||||
}
|
||||
}
|
||||
|
||||
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 HomePosition getHomePosition() {
|
||||
return homePosition;
|
||||
}
|
||||
|
||||
public void setHomePosition(HomePosition homePosition) {
|
||||
this.homePosition = homePosition;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.genersoft.iot.vmp.gb28181.bean;
|
||||
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -20,6 +21,8 @@ public class RecordInfo {
|
|||
|
||||
private int sumNum;
|
||||
|
||||
private int count;
|
||||
|
||||
private Instant lastTime;
|
||||
|
||||
private List<RecordItem> recordList;
|
||||
|
@ -79,4 +82,12 @@ public class RecordInfo {
|
|||
public void setLastTime(Instant lastTime) {
|
||||
this.lastTime = lastTime;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.genersoft.iot.vmp.gb28181.event.record;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -20,25 +22,46 @@ public class RecordEndEventListener implements ApplicationListener<RecordEndEven
|
|||
|
||||
private final static Logger logger = LoggerFactory.getLogger(RecordEndEventListener.class);
|
||||
|
||||
private Map<String, RecordEndEventHandler> handlerMap = new ConcurrentHashMap<>();
|
||||
public interface RecordEndEventHandler{
|
||||
void handler(RecordInfo recordInfo);
|
||||
}
|
||||
|
||||
private Map<String, RecordEndEventHandler> handlerMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(RecordEndEvent event) {
|
||||
logger.info("录像查询完成事件触发,deviceId:{}, channelId: {}, 录像数量{}条", event.getRecordInfo().getDeviceId(),
|
||||
event.getRecordInfo().getChannelId(), event.getRecordInfo().getSumNum() );
|
||||
String deviceId = event.getRecordInfo().getDeviceId();
|
||||
String channelId = event.getRecordInfo().getChannelId();
|
||||
int count = event.getRecordInfo().getCount();
|
||||
int sumNum = event.getRecordInfo().getSumNum();
|
||||
logger.info("录像查询完成事件触发,deviceId:{}, channelId: {}, 录像数量{}/{}条", event.getRecordInfo().getDeviceId(),
|
||||
event.getRecordInfo().getChannelId(), count,sumNum);
|
||||
if (handlerMap.size() > 0) {
|
||||
for (RecordEndEventHandler recordEndEventHandler : handlerMap.values()) {
|
||||
recordEndEventHandler.handler(event.getRecordInfo());
|
||||
RecordEndEventHandler handler = handlerMap.get(deviceId + channelId);
|
||||
if (handler !=null){
|
||||
handler.handler(event.getRecordInfo());
|
||||
if (count ==sumNum){
|
||||
handlerMap.remove(deviceId + channelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
handlerMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
* @param device
|
||||
* @param channelId
|
||||
* @param recordEndEventHandler
|
||||
*/
|
||||
public void addEndEventHandler(String device, String channelId, RecordEndEventHandler recordEndEventHandler) {
|
||||
handlerMap.put(device + channelId, recordEndEventHandler);
|
||||
}
|
||||
/**
|
||||
* 添加
|
||||
* @param device
|
||||
* @param channelId
|
||||
*/
|
||||
public void delEndEventHandler(String device, String channelId) {
|
||||
handlerMap.remove(device + channelId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -109,12 +109,18 @@ public class CatalogDataCatch {
|
|||
|
||||
for (String deviceId : keys) {
|
||||
CatalogData catalogData = data.get(deviceId);
|
||||
if ( catalogData.getLastTime().isBefore(instantBefore5S)) { // 超过五秒收不到消息任务超时, 只更新这一部分数据
|
||||
if ( catalogData.getLastTime().isBefore(instantBefore5S)) {
|
||||
// 超过五秒收不到消息任务超时, 只更新这一部分数据, 收到数据与声明的总数一致,则重置通道数据,数据不全则只对收到的数据做更新操作
|
||||
if (catalogData.getStatus().equals(CatalogData.CatalogDataStatus.runIng)) {
|
||||
storager.resetChannels(catalogData.getDevice().getDeviceId(), catalogData.getChannelList());
|
||||
if (catalogData.getTotal() == catalogData.getChannelList().size()) {
|
||||
storager.resetChannels(catalogData.getDevice().getDeviceId(), catalogData.getChannelList());
|
||||
}else {
|
||||
storager.updateChannels(catalogData.getDevice().getDeviceId(), catalogData.getChannelList());
|
||||
}
|
||||
String errorMsg = "更新成功,共" + catalogData.getTotal() + "条,已更新" + catalogData.getChannelList().size() + "条";
|
||||
catalogData.setErrorMsg(errorMsg);
|
||||
if (catalogData.getTotal() != catalogData.getChannelList().size()) {
|
||||
String errorMsg = "更新成功,共" + catalogData.getTotal() + "条,已更新" + catalogData.getChannelList().size() + "条";
|
||||
catalogData.setErrorMsg(errorMsg);
|
||||
|
||||
}
|
||||
}else if (catalogData.getStatus().equals(CatalogData.CatalogDataStatus.ready)) {
|
||||
String errorMsg = "同步失败,等待回复超时";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
@ -23,14 +24,17 @@ public class RecordDataCatch {
|
|||
|
||||
@Autowired
|
||||
private DeferredResultHolder deferredResultHolder;
|
||||
@Autowired
|
||||
private RecordEndEventListener recordEndEventListener;
|
||||
|
||||
|
||||
public int put(String deviceId, String sn, int sumNum, List<RecordItem> recordItems) {
|
||||
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<>()));
|
||||
|
@ -67,6 +71,7 @@ public class RecordDataCatch {
|
|||
msg.setKey(msgKey);
|
||||
msg.setData(recordInfo);
|
||||
deferredResultHolder.invokeAllResult(msg);
|
||||
recordEndEventListener.delEndEventHandler(recordInfo.getDeviceId(),recordInfo.getChannelId());
|
||||
data.remove(key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
|||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SipTransactionInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||
import com.genersoft.iot.vmp.utils.JsonUtil;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import gov.nist.javax.sip.message.SIPResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -134,7 +135,7 @@ public class VideoStreamSessionManager {
|
|||
List<SsrcTransaction> result= new ArrayList<>();
|
||||
for (int i = 0; i < ssrcTransactionKeys.size(); i++) {
|
||||
String key = (String)ssrcTransactionKeys.get(i);
|
||||
SsrcTransaction ssrcTransaction = (SsrcTransaction)RedisUtil.get(key);
|
||||
SsrcTransaction ssrcTransaction = JsonUtil.redisJsonToObject(key, SsrcTransaction.class);
|
||||
result.add(ssrcTransaction);
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -47,61 +47,65 @@ public class SIPSender {
|
|||
}
|
||||
|
||||
public void transmitRequest(String ip, Message message, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, ParseException {
|
||||
ViaHeader viaHeader = (ViaHeader)message.getHeader(ViaHeader.NAME);
|
||||
String transport = "UDP";
|
||||
if (viaHeader == null) {
|
||||
logger.warn("[消息头缺失]: ViaHeader, 使用默认的UDP方式处理数据");
|
||||
}else {
|
||||
transport = viaHeader.getTransport();
|
||||
}
|
||||
if (message.getHeader(UserAgentHeader.NAME) == null) {
|
||||
try {
|
||||
message.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
|
||||
} catch (ParseException e) {
|
||||
logger.error("添加UserAgentHeader失败", e);
|
||||
try {
|
||||
ViaHeader viaHeader = (ViaHeader)message.getHeader(ViaHeader.NAME);
|
||||
String transport = "UDP";
|
||||
if (viaHeader == null) {
|
||||
logger.warn("[消息头缺失]: ViaHeader, 使用默认的UDP方式处理数据");
|
||||
}else {
|
||||
transport = viaHeader.getTransport();
|
||||
}
|
||||
}
|
||||
|
||||
CallIdHeader callIdHeader = (CallIdHeader) message.getHeader(CallIdHeader.NAME);
|
||||
// 添加错误订阅
|
||||
if (errorEvent != null) {
|
||||
sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (eventResult -> {
|
||||
errorEvent.response(eventResult);
|
||||
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
||||
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
||||
}));
|
||||
}
|
||||
// 添加订阅
|
||||
if (okEvent != null) {
|
||||
sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), eventResult -> {
|
||||
okEvent.response(eventResult);
|
||||
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
||||
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
||||
});
|
||||
}
|
||||
if ("TCP".equals(transport)) {
|
||||
SipProviderImpl tcpSipProvider = sipLayer.getTcpSipProvider(ip);
|
||||
if (tcpSipProvider == null) {
|
||||
logger.error("[发送信息失败] 未找到tcp://{}的监听信息", ip);
|
||||
return;
|
||||
}
|
||||
if (message instanceof Request) {
|
||||
tcpSipProvider.sendRequest((Request)message);
|
||||
}else if (message instanceof Response) {
|
||||
tcpSipProvider.sendResponse((Response)message);
|
||||
if (message.getHeader(UserAgentHeader.NAME) == null) {
|
||||
try {
|
||||
message.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
|
||||
} catch (ParseException e) {
|
||||
logger.error("添加UserAgentHeader失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ("UDP".equals(transport)) {
|
||||
SipProviderImpl sipProvider = sipLayer.getUdpSipProvider(ip);
|
||||
if (sipProvider == null) {
|
||||
logger.error("[发送信息失败] 未找到udp://{}的监听信息", ip);
|
||||
return;
|
||||
CallIdHeader callIdHeader = (CallIdHeader) message.getHeader(CallIdHeader.NAME);
|
||||
// 添加错误订阅
|
||||
if (errorEvent != null) {
|
||||
sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (eventResult -> {
|
||||
errorEvent.response(eventResult);
|
||||
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
||||
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
||||
}));
|
||||
}
|
||||
if (message instanceof Request) {
|
||||
sipProvider.sendRequest((Request)message);
|
||||
}else if (message instanceof Response) {
|
||||
sipProvider.sendResponse((Response)message);
|
||||
// 添加订阅
|
||||
if (okEvent != null) {
|
||||
sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), eventResult -> {
|
||||
okEvent.response(eventResult);
|
||||
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
||||
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
||||
});
|
||||
}
|
||||
if ("TCP".equals(transport)) {
|
||||
SipProviderImpl tcpSipProvider = sipLayer.getTcpSipProvider(ip);
|
||||
if (tcpSipProvider == null) {
|
||||
logger.error("[发送信息失败] 未找到tcp://{}的监听信息", ip);
|
||||
return;
|
||||
}
|
||||
if (message instanceof Request) {
|
||||
tcpSipProvider.sendRequest((Request)message);
|
||||
}else if (message instanceof Response) {
|
||||
tcpSipProvider.sendResponse((Response)message);
|
||||
}
|
||||
|
||||
} else if ("UDP".equals(transport)) {
|
||||
SipProviderImpl sipProvider = sipLayer.getUdpSipProvider(ip);
|
||||
if (sipProvider == null) {
|
||||
logger.error("[发送信息失败] 未找到udp://{}的监听信息", ip);
|
||||
return;
|
||||
}
|
||||
if (message instanceof Request) {
|
||||
sipProvider.sendRequest((Request)message);
|
||||
}else if (message instanceof Response) {
|
||||
sipProvider.sendResponse((Response)message);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
logger.info("[SEND]:SUCCESS:{}", message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ public interface ISIPCommander {
|
|||
* @param channelId 预览通道
|
||||
* @param recordCmdStr 录像命令:Record / StopRecord
|
||||
*/
|
||||
void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 远程启动控制命令
|
||||
|
@ -196,7 +196,7 @@ public interface ISIPCommander {
|
|||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 报警复位命令
|
||||
|
@ -205,7 +205,7 @@ public interface ISIPCommander {
|
|||
* @param alarmMethod 报警方式(可选)
|
||||
* @param alarmType 报警类型(可选)
|
||||
*/
|
||||
void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
||||
|
@ -214,17 +214,19 @@ public interface ISIPCommander {
|
|||
* @param channelId 预览通道
|
||||
*/
|
||||
void iFrameCmd(Device device, String channelId) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
|
||||
/**
|
||||
* 看守位控制命令
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param enabled 看守位使能:1 = 开启,0 = 关闭
|
||||
* @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
||||
* @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param channelId 通道id,非通道则是设备本身
|
||||
* @param frontCmd 上级平台的指令,如果存在则直接下发
|
||||
* @param enabled 看守位使能:1 = 开启,0 = 关闭
|
||||
* @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
||||
* @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
||||
*/
|
||||
void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 设备配置命令
|
||||
*
|
||||
|
|
|
@ -69,12 +69,11 @@ public interface ISIPCommanderForPlatform {
|
|||
* 向上级回复DeviceInfo查询信息
|
||||
*
|
||||
* @param parentPlatform 平台信息
|
||||
* @param sn
|
||||
* @param fromTag
|
||||
* @param sn SN
|
||||
* @param fromTag FROM头的tag信息
|
||||
* @return
|
||||
*/
|
||||
void deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag)
|
||||
throws SipException, InvalidArgumentException, ParseException;
|
||||
void deviceInfoResponse(ParentPlatform parentPlatform,Device device, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException;
|
||||
|
||||
/**
|
||||
* 向上级回复DeviceStatus查询信息
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.ResponseEvent;
|
||||
|
@ -711,7 +712,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
* @param recordCmdStr 录像命令:Record / StopRecord
|
||||
*/
|
||||
@Override
|
||||
public void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n");
|
||||
|
@ -729,7 +730,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
|
||||
|
||||
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, errorEvent,okEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -763,7 +764,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
* @param guardCmdStr "SetGuard"/"ResetGuard"
|
||||
*/
|
||||
@Override
|
||||
public void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
|
@ -778,7 +779,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
|
||||
|
||||
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, errorEvent,okEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -787,7 +788,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
|
@ -814,7 +815,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
|
||||
|
||||
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, errorEvent,okEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -850,12 +851,14 @@ public class SIPCommander implements ISIPCommander {
|
|||
* 看守位控制命令
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @param channelId 通道id,非通道则是设备本身
|
||||
* @param frontCmd 上级平台的指令,如果存在则直接下发
|
||||
* @param enabled 看守位使能:1 = 开启,0 = 关闭
|
||||
* @param resetTime 自动归位时间间隔,开启看守位时使用,单位:秒(s)
|
||||
* @param presetIndex 调用预置位编号,开启看守位时使用,取值范围0~255
|
||||
*/
|
||||
@Override
|
||||
public void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
public void homePositionCmd(Device device, String channelId, String enabled, String resetTime, String presetIndex, SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
String charset = device.getCharset();
|
||||
|
@ -890,7 +893,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
|
||||
|
||||
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, errorEvent,okEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -81,6 +81,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
@Autowired
|
||||
private VideoStreamSessionManager streamSession;
|
||||
|
||||
@Autowired
|
||||
private DynamicTask dynamicTask;
|
||||
|
||||
@Override
|
||||
public void register(ParentPlatform parentPlatform, SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws InvalidArgumentException, ParseException, SipException {
|
||||
register(parentPlatform, null, null, errorEvent, okEvent, false, true);
|
||||
|
@ -129,13 +132,14 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
public String keepalive(ParentPlatform parentPlatform,SipSubscribe.Event errorEvent , SipSubscribe.Event okEvent) throws SipException, InvalidArgumentException, ParseException {
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer keepaliveXml = new StringBuffer(200);
|
||||
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
keepaliveXml.append("<Notify>\r\n");
|
||||
keepaliveXml.append("<CmdType>Keepalive</CmdType>\r\n");
|
||||
keepaliveXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||
keepaliveXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||
keepaliveXml.append("<Status>OK</Status>\r\n");
|
||||
keepaliveXml.append("</Notify>\r\n");
|
||||
keepaliveXml.append("<?xml version=\"1.0\" encoding=\"")
|
||||
.append(characterSet).append("\"?>\r\n")
|
||||
.append("<Notify>\r\n")
|
||||
.append("<CmdType>Keepalive</CmdType>\r\n")
|
||||
.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n")
|
||||
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
||||
.append("<Status>OK</Status>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
|
||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||
|
||||
|
@ -153,7 +157,6 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
* 向上级回复通道信息
|
||||
* @param channel 通道信息
|
||||
* @param parentPlatform 平台信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size) throws SipException, InvalidArgumentException, ParseException {
|
||||
|
@ -180,18 +183,18 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
if ( parentPlatform ==null) {
|
||||
return ;
|
||||
}
|
||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, 0);
|
||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, 0, true);
|
||||
}
|
||||
private String getCatalogXml(List<DeviceChannel> channels, String sn, ParentPlatform parentPlatform, int size) {
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer catalogXml = new StringBuffer(600);
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet +"\"?>\r\n");
|
||||
catalogXml.append("<Response>\r\n");
|
||||
catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" +sn + "</SN>\r\n");
|
||||
catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||
catalogXml.append("<SumNum>" + size + "</SumNum>\r\n");
|
||||
catalogXml.append("<DeviceList Num=\"" + channels.size() +"\">\r\n");
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet +"\"?>\r\n")
|
||||
.append("<Response>\r\n")
|
||||
.append("<CmdType>Catalog</CmdType>\r\n")
|
||||
.append("<SN>" +sn + "</SN>\r\n")
|
||||
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
||||
.append("<SumNum>" + size + "</SumNum>\r\n")
|
||||
.append("<DeviceList Num=\"" + channels.size() +"\">\r\n");
|
||||
if (channels.size() > 0) {
|
||||
for (DeviceChannel channel : channels) {
|
||||
if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
|
||||
|
@ -242,7 +245,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
return catalogXml.toString();
|
||||
}
|
||||
|
||||
private void sendCatalogResponse(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag, int index) throws SipException, InvalidArgumentException, ParseException {
|
||||
private void sendCatalogResponse(List<DeviceChannel> channels, ParentPlatform parentPlatform, String sn, String fromTag, int index, boolean sendAfterResponse) throws SipException, InvalidArgumentException, ParseException {
|
||||
if (index >= channels.size()) {
|
||||
return;
|
||||
}
|
||||
|
@ -256,15 +259,49 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
// callid
|
||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||
|
||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||
sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, eventResult -> {
|
||||
int indexNext = index + parentPlatform.getCatalogGroup();
|
||||
try {
|
||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 国标级联 目录查询回复: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
SIPRequest request = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(parentPlatform, catalogXml, fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||
|
||||
String timeoutTaskKey = "catalog_task_" + parentPlatform.getServerGBId() + sn;
|
||||
|
||||
String callId = request.getCallIdHeader().getCallId();
|
||||
|
||||
if (sendAfterResponse) {
|
||||
// 默认按照收到200回复后发送下一条, 如果超时收不到回复,就以30毫秒的间隔直接发送。
|
||||
dynamicTask.startDelay(timeoutTaskKey, ()->{
|
||||
sipSubscribe.removeOkSubscribe(callId);
|
||||
int indexNext = index + parentPlatform.getCatalogGroup();
|
||||
try {
|
||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext, false);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 国标级联 目录查询回复: {}", e.getMessage());
|
||||
}
|
||||
}, 3000);
|
||||
sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, eventResult -> {
|
||||
logger.error("[目录推送失败] 国标级联 platform : {}, code: {}, msg: {}, 停止发送", parentPlatform.getServerGBId(), eventResult.statusCode, eventResult.msg);
|
||||
dynamicTask.stop(timeoutTaskKey);
|
||||
}, eventResult -> {
|
||||
dynamicTask.stop(timeoutTaskKey);
|
||||
int indexNext = index + parentPlatform.getCatalogGroup();
|
||||
try {
|
||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext, true);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 国标级联 目录查询回复: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
}else {
|
||||
sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, eventResult -> {
|
||||
logger.error("[目录推送失败] 国标级联 platform : {}, code: {}, msg: {}, 停止发送", parentPlatform.getServerGBId(), eventResult.statusCode, eventResult.msg);
|
||||
dynamicTask.stop(timeoutTaskKey);
|
||||
}, null);
|
||||
dynamicTask.startDelay(timeoutTaskKey, ()->{
|
||||
int indexNext = index + parentPlatform.getCatalogGroup();
|
||||
try {
|
||||
sendCatalogResponse(channels, parentPlatform, sn, fromTag, indexNext, false);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 国标级联 目录查询回复: {}", e.getMessage());
|
||||
}
|
||||
}, 30);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,7 +312,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void deviceInfoResponse(ParentPlatform parentPlatform, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException {
|
||||
public void deviceInfoResponse(ParentPlatform parentPlatform,Device device, String sn, String fromTag) throws SipException, InvalidArgumentException, ParseException {
|
||||
if (parentPlatform == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -285,11 +322,11 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
deviceInfoXml.append("<Response>\r\n");
|
||||
deviceInfoXml.append("<CmdType>DeviceInfo</CmdType>\r\n");
|
||||
deviceInfoXml.append("<SN>" +sn + "</SN>\r\n");
|
||||
deviceInfoXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||
deviceInfoXml.append("<DeviceName>" + parentPlatform.getName() + "</DeviceName>\r\n");
|
||||
deviceInfoXml.append("<Manufacturer>wvp</Manufacturer>\r\n");
|
||||
deviceInfoXml.append("<Model>wvp-28181-2.0</Model>\r\n");
|
||||
deviceInfoXml.append("<Firmware>2.0.202107</Firmware>\r\n");
|
||||
deviceInfoXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>\r\n");
|
||||
deviceInfoXml.append("<DeviceName>" + device.getName() + "</DeviceName>\r\n");
|
||||
deviceInfoXml.append("<Manufacturer>" + device.getManufacturer() + "</Manufacturer>\r\n");
|
||||
deviceInfoXml.append("<Model>" + device.getModel() + "</Model>\r\n");
|
||||
deviceInfoXml.append("<Firmware>" + device.getFirmware() + "</Firmware>\r\n");
|
||||
deviceInfoXml.append("<Result>OK</Result>\r\n");
|
||||
deviceInfoXml.append("</Response>\r\n");
|
||||
|
||||
|
@ -314,15 +351,15 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
String statusStr = (status==1)?"ONLINE":"OFFLINE";
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
deviceStatusXml.append("<Response>\r\n");
|
||||
deviceStatusXml.append("<CmdType>DeviceStatus</CmdType>\r\n");
|
||||
deviceStatusXml.append("<SN>" +sn + "</SN>\r\n");
|
||||
deviceStatusXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
|
||||
deviceStatusXml.append("<Result>OK</Result>\r\n");
|
||||
deviceStatusXml.append("<Online>"+statusStr+"</Online>\r\n");
|
||||
deviceStatusXml.append("<Status>OK</Status>\r\n");
|
||||
deviceStatusXml.append("</Response>\r\n");
|
||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Response>\r\n")
|
||||
.append("<CmdType>DeviceStatus</CmdType>\r\n")
|
||||
.append("<SN>" +sn + "</SN>\r\n")
|
||||
.append("<DeviceID>" + channelId + "</DeviceID>\r\n")
|
||||
.append("<Result>OK</Result>\r\n")
|
||||
.append("<Online>"+statusStr+"</Online>\r\n")
|
||||
.append("<Status>OK</Status>\r\n")
|
||||
.append("</Response>\r\n");
|
||||
|
||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||
|
||||
|
@ -341,18 +378,18 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
deviceStatusXml.append("<Notify>\r\n");
|
||||
deviceStatusXml.append("<CmdType>MobilePosition</CmdType>\r\n");
|
||||
deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||
deviceStatusXml.append("<DeviceID>" + gpsMsgInfo.getId() + "</DeviceID>\r\n");
|
||||
deviceStatusXml.append("<Time>" + gpsMsgInfo.getTime() + "</Time>\r\n");
|
||||
deviceStatusXml.append("<Longitude>" + gpsMsgInfo.getLng() + "</Longitude>\r\n");
|
||||
deviceStatusXml.append("<Latitude>" + gpsMsgInfo.getLat() + "</Latitude>\r\n");
|
||||
deviceStatusXml.append("<Speed>" + gpsMsgInfo.getSpeed() + "</Speed>\r\n");
|
||||
deviceStatusXml.append("<Direction>" + gpsMsgInfo.getDirection() + "</Direction>\r\n");
|
||||
deviceStatusXml.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n");
|
||||
deviceStatusXml.append("</Notify>\r\n");
|
||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Notify>\r\n")
|
||||
.append("<CmdType>MobilePosition</CmdType>\r\n")
|
||||
.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n")
|
||||
.append("<DeviceID>" + gpsMsgInfo.getId() + "</DeviceID>\r\n")
|
||||
.append("<Time>" + gpsMsgInfo.getTime() + "</Time>\r\n")
|
||||
.append("<Longitude>" + gpsMsgInfo.getLng() + "</Longitude>\r\n")
|
||||
.append("<Latitude>" + gpsMsgInfo.getLat() + "</Latitude>\r\n")
|
||||
.append("<Speed>" + gpsMsgInfo.getSpeed() + "</Speed>\r\n")
|
||||
.append("<Direction>" + gpsMsgInfo.getDirection() + "</Direction>\r\n")
|
||||
.append("<Altitude>" + gpsMsgInfo.getAltitude() + "</Altitude>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
|
||||
sendNotify(parentPlatform, deviceStatusXml.toString(), subscribeInfo, eventResult -> {
|
||||
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
||||
|
@ -369,21 +406,21 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm));
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
deviceStatusXml.append("<Notify>\r\n");
|
||||
deviceStatusXml.append("<CmdType>Alarm</CmdType>\r\n");
|
||||
deviceStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||
deviceStatusXml.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n");
|
||||
deviceStatusXml.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n");
|
||||
deviceStatusXml.append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n");
|
||||
deviceStatusXml.append("<AlarmTime>" + deviceAlarm.getAlarmTime() + "</AlarmTime>\r\n");
|
||||
deviceStatusXml.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n");
|
||||
deviceStatusXml.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n");
|
||||
deviceStatusXml.append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n");
|
||||
deviceStatusXml.append("<info>\r\n");
|
||||
deviceStatusXml.append("<AlarmType>" + deviceAlarm.getAlarmType() + "</AlarmType>\r\n");
|
||||
deviceStatusXml.append("</info>\r\n");
|
||||
deviceStatusXml.append("</Notify>\r\n");
|
||||
deviceStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Notify>\r\n")
|
||||
.append("<CmdType>Alarm</CmdType>\r\n")
|
||||
.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n")
|
||||
.append("<DeviceID>" + deviceAlarm.getChannelId() + "</DeviceID>\r\n")
|
||||
.append("<AlarmPriority>" + deviceAlarm.getAlarmPriority() + "</AlarmPriority>\r\n")
|
||||
.append("<AlarmMethod>" + deviceAlarm.getAlarmMethod() + "</AlarmMethod>\r\n")
|
||||
.append("<AlarmTime>" + deviceAlarm.getAlarmTime() + "</AlarmTime>\r\n")
|
||||
.append("<AlarmDescription>" + deviceAlarm.getAlarmDescription() + "</AlarmDescription>\r\n")
|
||||
.append("<Longitude>" + deviceAlarm.getLongitude() + "</Longitude>\r\n")
|
||||
.append("<Latitude>" + deviceAlarm.getLatitude() + "</Latitude>\r\n")
|
||||
.append("<info>\r\n")
|
||||
.append("<AlarmType>" + deviceAlarm.getAlarmType() + "</AlarmType>\r\n")
|
||||
.append("</info>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
|
||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||
|
||||
|
@ -442,13 +479,13 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
StringBuffer catalogXml = new StringBuffer(600);
|
||||
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
catalogXml.append("<Notify>\r\n");
|
||||
catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||
catalogXml.append("<SumNum>1</SumNum>\r\n");
|
||||
catalogXml.append("<DeviceList Num=\"" + channels.size() + "\">\r\n");
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Notify>\r\n")
|
||||
.append("<CmdType>Catalog</CmdType>\r\n")
|
||||
.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n")
|
||||
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
||||
.append("<SumNum>1</SumNum>\r\n")
|
||||
.append("<DeviceList Num=\"" + channels.size() + "\">\r\n");
|
||||
if (channels.size() > 0) {
|
||||
for (DeviceChannel channel : channels) {
|
||||
if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
|
||||
|
@ -469,16 +506,16 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");
|
||||
if (channel.getParental() == 0) {
|
||||
// 通道项
|
||||
catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
|
||||
catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
|
||||
catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
|
||||
catalogXml.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
|
||||
catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n")
|
||||
.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n")
|
||||
.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n")
|
||||
.append("<Status>" + (channel.getStatus() == 0 ? "OFF" : "ON") + "</Status>\r\n");
|
||||
|
||||
if (channel.getChannelType() != 2) { // 业务分组/虚拟组织/行政区划 不设置以下属性
|
||||
catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
|
||||
catalogXml.append("<Owner> " + channel.getOwner()+ "</Owner>\r\n");
|
||||
catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
|
||||
catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
|
||||
catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n")
|
||||
.append("<Owner> " + channel.getOwner()+ "</Owner>\r\n")
|
||||
.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n")
|
||||
.append("<Address>" + channel.getAddress() + "</Address>\r\n");
|
||||
}
|
||||
if (!"presence".equals(subscribeInfo.getEventType())) {
|
||||
catalogXml.append("<Event>" + type + "</Event>\r\n");
|
||||
|
@ -488,8 +525,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
catalogXml.append("</Item>\r\n");
|
||||
}
|
||||
}
|
||||
catalogXml.append("</DeviceList>\r\n");
|
||||
catalogXml.append("</Notify>\r\n");
|
||||
catalogXml.append("</DeviceList>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
return catalogXml.toString();
|
||||
}
|
||||
|
||||
|
@ -535,26 +572,26 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer catalogXml = new StringBuffer(600);
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
catalogXml.append("<Notify>\r\n");
|
||||
catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
|
||||
catalogXml.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n");
|
||||
catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
|
||||
catalogXml.append("<SumNum>1</SumNum>\r\n");
|
||||
catalogXml.append("<DeviceList Num=\" " + channels.size() + " \">\r\n");
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Notify>\r\n")
|
||||
.append("<CmdType>Catalog</CmdType>\r\n")
|
||||
.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n")
|
||||
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
||||
.append("<SumNum>1</SumNum>\r\n")
|
||||
.append("<DeviceList Num=\" " + channels.size() + " \">\r\n");
|
||||
if (channels.size() > 0) {
|
||||
for (DeviceChannel channel : channels) {
|
||||
if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
|
||||
channel.setParentId(parentPlatform.getDeviceGBId());
|
||||
}
|
||||
catalogXml.append("<Item>\r\n");
|
||||
catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
|
||||
catalogXml.append("<Event>" + type + "</Event>\r\n");
|
||||
catalogXml.append("</Item>\r\n");
|
||||
catalogXml.append("<Item>\r\n")
|
||||
.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n")
|
||||
.append("<Event>" + type + "</Event>\r\n")
|
||||
.append("</Item>\r\n");
|
||||
}
|
||||
}
|
||||
catalogXml.append("</DeviceList>\r\n");
|
||||
catalogXml.append("</Notify>\r\n");
|
||||
catalogXml.append("</DeviceList>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
return catalogXml.toString();
|
||||
}
|
||||
@Override
|
||||
|
@ -564,12 +601,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
}
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer recordXml = new StringBuffer(600);
|
||||
recordXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
recordXml.append("<Response>\r\n");
|
||||
recordXml.append("<CmdType>RecordInfo</CmdType>\r\n");
|
||||
recordXml.append("<SN>" +recordInfo.getSn() + "</SN>\r\n");
|
||||
recordXml.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n");
|
||||
recordXml.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
|
||||
recordXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||
.append("<Response>\r\n")
|
||||
.append("<CmdType>RecordInfo</CmdType>\r\n")
|
||||
.append("<SN>" +recordInfo.getSn() + "</SN>\r\n")
|
||||
.append("<DeviceID>" + recordInfo.getDeviceId() + "</DeviceID>\r\n")
|
||||
.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
|
||||
if (recordInfo.getRecordList() == null ) {
|
||||
recordXml.append("<RecordList Num=\"0\">\r\n");
|
||||
}else {
|
||||
|
@ -578,12 +615,12 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
for (RecordItem recordItem : recordInfo.getRecordList()) {
|
||||
recordXml.append("<Item>\r\n");
|
||||
if (deviceChannel != null) {
|
||||
recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n");
|
||||
recordXml.append("<Name>" + recordItem.getName() + "</Name>\r\n");
|
||||
recordXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n");
|
||||
recordXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n");
|
||||
recordXml.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n");
|
||||
recordXml.append("<Type>" + recordItem.getType() + "</Type>\r\n");
|
||||
recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n")
|
||||
.append("<Name>" + recordItem.getName() + "</Name>\r\n")
|
||||
.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\r\n")
|
||||
.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n")
|
||||
.append("<Secrecy>" + recordItem.getSecrecy() + "</Secrecy>\r\n")
|
||||
.append("<Type>" + recordItem.getType() + "</Type>\r\n");
|
||||
if (!ObjectUtils.isEmpty(recordItem.getFileSize())) {
|
||||
recordXml.append("<FileSize>" + recordItem.getFileSize() + "</FileSize>\r\n");
|
||||
}
|
||||
|
@ -596,8 +633,8 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
recordXml.append("</RecordList>\r\n");
|
||||
recordXml.append("</Response>\r\n");
|
||||
recordXml.append("</RecordList>\r\n")
|
||||
.append("</Response>\r\n");
|
||||
|
||||
// callid
|
||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||
|
@ -616,13 +653,13 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||
|
||||
String characterSet = parentPlatform.getCharacterSet();
|
||||
StringBuffer mediaStatusXml = new StringBuffer(200);
|
||||
mediaStatusXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n");
|
||||
mediaStatusXml.append("<Notify>\r\n");
|
||||
mediaStatusXml.append("<CmdType>MediaStatus</CmdType>\r\n");
|
||||
mediaStatusXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>\r\n");
|
||||
mediaStatusXml.append("<DeviceID>" + sendRtpItem.getChannelId() + "</DeviceID>\r\n");
|
||||
mediaStatusXml.append("<NotifyType>121</NotifyType>\r\n");
|
||||
mediaStatusXml.append("</Notify>\r\n");
|
||||
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("<NotifyType>121</NotifyType>\r\n")
|
||||
.append("</Notify>\r\n");
|
||||
|
||||
SIPRequest messageRequest = (SIPRequest)headerProviderPlatformProvider.createMessageRequest(parentPlatform, mediaStatusXml.toString(),
|
||||
sendRtpItem);
|
||||
|
|
|
@ -16,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
|
||||
import javax.sip.*;
|
||||
import javax.sip.address.Address;
|
||||
import javax.sip.address.AddressFactory;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.header.ContentTypeHeader;
|
||||
import javax.sip.header.ExpiresHeader;
|
||||
|
@ -42,15 +41,6 @@ public abstract class SIPRequestProcessorParent {
|
|||
@Autowired
|
||||
private SIPSender sipSender;
|
||||
|
||||
public AddressFactory getAddressFactory() {
|
||||
try {
|
||||
return SipFactory.getInstance().createAddressFactory();
|
||||
} catch (PeerUnavailableException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public HeaderFactory getHeaderFactory() {
|
||||
try {
|
||||
return SipFactory.getInstance().createHeaderFactory();
|
||||
|
|
|
@ -275,7 +275,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||
}
|
||||
return;
|
||||
} else {
|
||||
logger.info("通道不存在,返回404");
|
||||
logger.info("通道不存在,返回404: {}", channelId);
|
||||
try {
|
||||
// 通道不存在,发404,资源不存在
|
||||
responseAck(request, Response.NOT_FOUND);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.ServiceInfo;
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
|
||||
|
@ -82,6 +83,19 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
|||
RequestEventExt evtExt = (RequestEventExt) evt;
|
||||
String requestAddress = evtExt.getRemoteIpAddress() + ":" + evtExt.getRemotePort();
|
||||
logger.info("[注册请求] 开始处理: {}", requestAddress);
|
||||
// MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
|
||||
// QueryExp protocol = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"));
|
||||
//// ObjectName name = new ObjectName("*:type=Connector,*");
|
||||
// ObjectName name = new ObjectName("*:*");
|
||||
// Set<ObjectName> objectNames = beanServer.queryNames(name, protocol);
|
||||
// for (ObjectName objectName : objectNames) {
|
||||
// String catalina = objectName.getDomain();
|
||||
// if ("Catalina".equals(catalina)) {
|
||||
// System.out.println(objectName.getKeyProperty("port"));
|
||||
// }
|
||||
// }
|
||||
|
||||
System.out.println(ServiceInfo.getServerPort());
|
||||
SIPRequest request = (SIPRequest)evt.getRequest();
|
||||
Response response = null;
|
||||
boolean passwordCorrect = false;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.control.cmd;
|
||||
|
||||
import com.genersoft.iot.vmp.VManageBootstrap;
|
||||
import com.genersoft.iot.vmp.common.enums.DeviceControlType;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DragZoomRequest;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.HomePositionRequest;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||
|
@ -19,17 +22,14 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.sip.*;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.header.HeaderAddress;
|
||||
import javax.sip.header.ToHeader;
|
||||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*;
|
||||
|
||||
@Component
|
||||
public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||
|
@ -81,7 +81,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
|
|||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||
logger.error("[命令发送失败] 国标级联 注销: {}", e.getMessage());
|
||||
}
|
||||
taskExecutor.execute(()->{
|
||||
taskExecutor.execute(() -> {
|
||||
// 远程启动
|
||||
// try {
|
||||
// Thread.sleep(3000);
|
||||
|
@ -101,13 +101,12 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
|
|||
// logger.error("[任务执行失败] 服务重启: {}", e.getMessage());
|
||||
// }
|
||||
});
|
||||
} else {
|
||||
// 远程启动指定设备
|
||||
}
|
||||
}
|
||||
// 云台/前端控制命令
|
||||
if (!ObjectUtils.isEmpty(getText(rootElement,"PTZCmd")) && !parentPlatform.getServerGBId().equals(targetGBId)) {
|
||||
String cmdString = getText(rootElement,"PTZCmd");
|
||||
DeviceControlType deviceControlType = DeviceControlType.typeOf(rootElement);
|
||||
logger.info("[接受deviceControl命令] 命令: {}", deviceControlType);
|
||||
if (!ObjectUtils.isEmpty(deviceControlType) && !parentPlatform.getServerGBId().equals(targetGBId)) {
|
||||
//判断是否存在该通道
|
||||
Device deviceForPlatform = storager.queryVideoDeviceByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
|
||||
if (deviceForPlatform == null) {
|
||||
try {
|
||||
|
@ -117,25 +116,240 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent
|
|||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
cmder.fronEndCmd(deviceForPlatform, channelId, cmdString, eventResult -> {
|
||||
// 失败的回复
|
||||
try {
|
||||
responseAck(request, eventResult.statusCode, eventResult.msg);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 云台/前端回复: {}", e.getMessage());
|
||||
}
|
||||
}, eventResult -> {
|
||||
// 成功的回复
|
||||
try {
|
||||
responseAck(request, eventResult.statusCode);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 云台/前端回复: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 云台/前端: {}", e.getMessage());
|
||||
switch (deviceControlType) {
|
||||
case PTZ:
|
||||
handlePtzCmd(deviceForPlatform, channelId, rootElement, request, DeviceControlType.PTZ);
|
||||
break;
|
||||
case ALARM:
|
||||
handleAlarmCmd(deviceForPlatform, rootElement, request);
|
||||
break;
|
||||
case GUARD:
|
||||
handleGuardCmd(deviceForPlatform, rootElement, request, DeviceControlType.GUARD);
|
||||
break;
|
||||
case RECORD:
|
||||
handleRecordCmd(deviceForPlatform, channelId, rootElement, request, DeviceControlType.RECORD);
|
||||
break;
|
||||
case I_FRAME:
|
||||
handleIFameCmd(deviceForPlatform, request, channelId);
|
||||
break;
|
||||
case TELE_BOOT:
|
||||
handleTeleBootCmd(deviceForPlatform, request);
|
||||
break;
|
||||
case DRAG_ZOOM_IN:
|
||||
handleDragZoom(deviceForPlatform, channelId, rootElement, request, DeviceControlType.DRAG_ZOOM_IN);
|
||||
break;
|
||||
case DRAG_ZOOM_OUT:
|
||||
handleDragZoom(deviceForPlatform, channelId, rootElement, request, DeviceControlType.DRAG_ZOOM_OUT);
|
||||
break;
|
||||
case HOME_POSITION:
|
||||
handleHomePositionCmd(deviceForPlatform, channelId, rootElement, request, DeviceControlType.HOME_POSITION);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理云台指令
|
||||
*
|
||||
* @param device 设备
|
||||
* @param channelId 通道id
|
||||
* @param rootElement
|
||||
* @param request
|
||||
*/
|
||||
private void handlePtzCmd(Device device, String channelId, Element rootElement, SIPRequest request, DeviceControlType type) {
|
||||
String cmdString = getText(rootElement, type.getVal());
|
||||
try {
|
||||
cmder.fronEndCmd(device, channelId, cmdString,
|
||||
errorResult -> onError(request, errorResult),
|
||||
okResult -> onOk(request, okResult));
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 云台/前端: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理强制关键帧
|
||||
*
|
||||
* @param device 设备
|
||||
* @param channelId 通道id
|
||||
*/
|
||||
private void handleIFameCmd(Device device, SIPRequest request, String channelId) {
|
||||
try {
|
||||
cmder.iFrameCmd(device, channelId);
|
||||
responseAck(request, Response.OK);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 强制关键帧: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理重启命令
|
||||
*
|
||||
* @param device 设备信息
|
||||
*/
|
||||
private void handleTeleBootCmd(Device device, SIPRequest request) {
|
||||
try {
|
||||
cmder.teleBootCmd(device);
|
||||
responseAck(request, Response.OK);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 重启: {}", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理拉框控制***
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @param channelId 通道id
|
||||
* @param rootElement 根节点
|
||||
* @param type 消息类型
|
||||
*/
|
||||
private void handleDragZoom(Device device, String channelId, Element rootElement, SIPRequest request, DeviceControlType type) {
|
||||
try {
|
||||
DragZoomRequest dragZoomRequest = loadElement(rootElement, DragZoomRequest.class);
|
||||
DragZoomRequest.DragZoom dragZoom = dragZoomRequest.getDragZoomIn();
|
||||
if (dragZoom == null) {
|
||||
dragZoom = dragZoomRequest.getDragZoomOut();
|
||||
}
|
||||
StringBuffer cmdXml = new StringBuffer(200);
|
||||
cmdXml.append("<" + type.getVal() + ">\r\n");
|
||||
cmdXml.append("<Length>" + dragZoom.getLength() + "</Length>\r\n");
|
||||
cmdXml.append("<Width>" + dragZoom.getWidth() + "</Width>\r\n");
|
||||
cmdXml.append("<MidPointX>" + dragZoom.getMidPointX() + "</MidPointX>\r\n");
|
||||
cmdXml.append("<MidPointY>" + dragZoom.getMidPointY() + "</MidPointY>\r\n");
|
||||
cmdXml.append("<LengthX>" + dragZoom.getLengthX() + "</LengthX>\r\n");
|
||||
cmdXml.append("<LengthY>" + dragZoom.getLengthY() + "</LengthY>\r\n");
|
||||
cmdXml.append("</" + type.getVal() + ">\r\n");
|
||||
cmder.dragZoomCmd(device, channelId, cmdXml.toString());
|
||||
responseAck(request, Response.OK);
|
||||
} catch (Exception e) {
|
||||
logger.error("[命令发送失败] 拉框控制: {}", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理看守位命令***
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @param channelId 通道id
|
||||
* @param rootElement 根节点
|
||||
* @param request 请求信息
|
||||
* @param type 消息类型
|
||||
*/
|
||||
private void handleHomePositionCmd(Device device, String channelId, Element rootElement, SIPRequest request, DeviceControlType type) {
|
||||
try {
|
||||
HomePositionRequest homePosition = loadElement(rootElement, HomePositionRequest.class);
|
||||
//获取整个消息主体,我们只需要修改请求头即可
|
||||
HomePositionRequest.HomePosition info = homePosition.getHomePosition();
|
||||
cmder.homePositionCmd(device, channelId, info.getEnabled(), info.getResetTime(), info.getPresetIndex(),
|
||||
errorResult -> onError(request, errorResult),
|
||||
okResult -> onOk(request, okResult));
|
||||
} catch (Exception e) {
|
||||
logger.error("[命令发送失败] 看守位设置: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理告警消息***
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @param rootElement 根节点
|
||||
* @param request 请求信息
|
||||
*/
|
||||
private void handleAlarmCmd(Device device, Element rootElement, SIPRequest request) {
|
||||
//告警方法
|
||||
String alarmMethod = "";
|
||||
//告警类型
|
||||
String alarmType = "";
|
||||
List<Element> info = rootElement.elements("Info");
|
||||
if (info != null) {
|
||||
for (Element element : info) {
|
||||
alarmMethod = getText(element, "AlarmMethod");
|
||||
alarmType = getText(element, "AlarmType");
|
||||
}
|
||||
}
|
||||
try {
|
||||
cmder.alarmCmd(device, alarmMethod, alarmType,
|
||||
errorResult -> onError(request, errorResult),
|
||||
okResult -> onOk(request, okResult));
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 告警消息: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理录像控制
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @param channelId 通道id
|
||||
* @param rootElement 根节点
|
||||
* @param request 请求信息
|
||||
* @param type 消息类型
|
||||
*/
|
||||
private void handleRecordCmd(Device device, String channelId, Element rootElement, SIPRequest request, DeviceControlType type) {
|
||||
//获取整个消息主体,我们只需要修改请求头即可
|
||||
String cmdString = getText(rootElement, type.getVal());
|
||||
try {
|
||||
cmder.recordCmd(device, channelId, cmdString,
|
||||
errorResult -> onError(request, errorResult),
|
||||
okResult -> onOk(request, okResult));
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 录像控制: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理报警布防/撤防命令
|
||||
*
|
||||
* @param device 设备信息
|
||||
* @param rootElement 根节点
|
||||
* @param request 请求信息
|
||||
* @param type 消息类型
|
||||
*/
|
||||
private void handleGuardCmd(Device device, Element rootElement, SIPRequest request, DeviceControlType type) {
|
||||
//获取整个消息主体,我们只需要修改请求头即可
|
||||
String cmdString = getText(rootElement, type.getVal());
|
||||
try {
|
||||
cmder.guardCmd(device, cmdString,
|
||||
errorResult -> onError(request, errorResult),
|
||||
okResult -> onOk(request, okResult));
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 布防/撤防命令: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 错误响应处理
|
||||
*
|
||||
* @param request 请求
|
||||
* @param eventResult 响应结构
|
||||
*/
|
||||
private void onError(SIPRequest request, SipSubscribe.EventResult eventResult) {
|
||||
// 失败的回复
|
||||
try {
|
||||
responseAck(request, eventResult.statusCode, eventResult.msg);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 回复: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功响应处理
|
||||
*
|
||||
* @param request 请求
|
||||
* @param eventResult 响应结构
|
||||
*/
|
||||
private void onOk(SIPRequest request, SipSubscribe.EventResult eventResult) {
|
||||
// 成功的回复
|
||||
try {
|
||||
responseAck(request, eventResult.statusCode);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 回复: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,11 +181,14 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
|
|||
}
|
||||
}
|
||||
logger.info("[收到报警通知]内容:{}", JSON.toJSONString(deviceAlarm));
|
||||
if ("7".equals(deviceAlarm.getAlarmMethod()) ) {
|
||||
// 作者自用判断,其他小伙伴需要此消息可以自行修改,但是不要提在pr里
|
||||
if (DeviceAlarmMethod.Other.getVal() == Integer.parseInt(deviceAlarm.getAlarmMethod())) {
|
||||
// 发送给平台的报警信息。 发送redis通知
|
||||
logger.info("[发送给平台的报警信息]内容:{}", JSONObject.toJSONString(deviceAlarm));
|
||||
AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage();
|
||||
alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));
|
||||
alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
|
||||
alarmChannelMessage.setAlarmType(Integer.parseInt(deviceAlarm.getAlarmType()));
|
||||
alarmChannelMessage.setGbId(channelId);
|
||||
redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
|
||||
continue;
|
||||
|
@ -264,6 +267,7 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme
|
|||
alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod()));
|
||||
alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription());
|
||||
alarmChannelMessage.setGbId(channelId);
|
||||
alarmChannelMessage.setAlarmType(Integer.parseInt(deviceAlarm.getAlarmType()));
|
||||
redisCatchStorage.sendAlarmMsg(alarmChannelMessage);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.cmd;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||
|
@ -63,7 +64,6 @@ public class CatalogQueryMessageHandler extends SIPRequestProcessorParent implem
|
|||
@Override
|
||||
public void handForPlatform(RequestEvent evt, ParentPlatform parentPlatform, Element rootElement) {
|
||||
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_CATALOG + parentPlatform.getServerGBId();
|
||||
FromHeader fromHeader = (FromHeader) evt.getRequest().getHeader(FromHeader.NAME);
|
||||
try {
|
||||
// 回复200 OK
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
|||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.query.QueryMessageHandler;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import gov.nist.javax.sip.message.SIPRequest;
|
||||
import org.dom4j.Element;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -21,6 +22,8 @@ import javax.sip.header.FromHeader;
|
|||
import javax.sip.message.Response;
|
||||
import java.text.ParseException;
|
||||
|
||||
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
|
||||
|
||||
@Component
|
||||
public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
|
||||
|
||||
|
@ -32,6 +35,8 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp
|
|||
|
||||
@Autowired
|
||||
private SIPCommanderFroPlatform cmderFroPlatform;
|
||||
@Autowired
|
||||
private IVideoManagerStorage storager;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
@ -52,10 +57,20 @@ public class DeviceInfoQueryMessageHandler extends SIPRequestProcessorParent imp
|
|||
responseAck((SIPRequest) evt.getRequest(), Response.OK);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] DeviceInfo查询回复: {}", e.getMessage());
|
||||
return;
|
||||
}
|
||||
String sn = rootElement.element("SN").getText();
|
||||
/*根据WVP原有的数据结构,设备和通道是分开放置,设备信息都是存放在设备表里,通道表里的设备信息不可作为真实信息处理
|
||||
大部分NVR/IPC设备对他的通道信息实现都是返回默认的值没有什么参考价值。NVR/IPC通道我们统一使用设备表的设备信息来作为返回。
|
||||
我们这里使用查询数据库的方式来实现这个设备信息查询的功能,在其他地方对设备信息更新达到正确的目的。*/
|
||||
String channelId = getText(rootElement, "DeviceID");
|
||||
Device device = storager.queryDeviceInfoByPlatformIdAndChannelId(parentPlatform.getServerGBId(), channelId);
|
||||
if (device ==null){
|
||||
logger.error("[平台没有该通道的使用权限]:platformId"+parentPlatform.getServerGBId()+" deviceID:"+channelId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
cmderFroPlatform.deviceInfoResponse(parentPlatform, sn, fromHeader.getTag());
|
||||
cmderFroPlatform.deviceInfoResponse(parentPlatform,device, sn, fromHeader.getTag());
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
logger.error("[命令发送失败] 国标级联 DeviceInfo查询回复: {}", e.getMessage());
|
||||
}
|
||||
|
|
|
@ -102,8 +102,9 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
|
|||
Element recordListElement = rootElementForCharset.element("RecordList");
|
||||
if (recordListElement == null || sumNum == 0) {
|
||||
logger.info("无录像数据");
|
||||
int count = recordDataCatch.put(take.getDevice().getDeviceId(),channelId, sn, sumNum, new ArrayList<>());
|
||||
recordInfo.setCount(count);
|
||||
eventPublisher.recordEndEventPush(recordInfo);
|
||||
recordDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, new ArrayList<>());
|
||||
releaseRequest(take.getDevice().getDeviceId(), sn);
|
||||
} else {
|
||||
Iterator<Element> recordListIterator = recordListElement.elementIterator();
|
||||
|
@ -137,12 +138,11 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
|
|||
recordList.add(record);
|
||||
}
|
||||
recordInfo.setRecordList(recordList);
|
||||
int count = recordDataCatch.put(take.getDevice().getDeviceId(),channelId, sn, sumNum, recordList);recordInfo.setCount(count);
|
||||
logger.info("[国标录像], {}->{}: {}/{}", take.getDevice().getDeviceId(), sn, count, sumNum);
|
||||
// 发送消息,如果是上级查询此录像,则会通过这里通知给上级
|
||||
eventPublisher.recordEndEventPush(recordInfo);
|
||||
int count = recordDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, recordList);
|
||||
logger.info("[国标录像], {}->{}: {}/{}", take.getDevice().getDeviceId(), sn, count, sumNum);
|
||||
}
|
||||
|
||||
if (recordDataCatch.isComplete(take.getDevice().getDeviceId(), sn)){
|
||||
releaseRequest(take.getDevice().getDeviceId(), sn);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.genersoft.iot.vmp.gb28181.utils;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author gaofuwang
|
||||
* @version 1.0
|
||||
* @date 2022/6/28 14:58
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface MessageElement {
|
||||
String value();
|
||||
|
||||
String subVal() default "";
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package com.genersoft.iot.vmp.gb28181.utils;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
|
@ -15,12 +16,16 @@ import org.dom4j.io.SAXReader;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.message.Request;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -411,4 +416,76 @@ public class XmlUtil {
|
|||
}
|
||||
return deviceChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增方法支持内部嵌套
|
||||
*
|
||||
* @param element xmlElement
|
||||
* @param clazz 结果类
|
||||
* @param <T> 泛型
|
||||
* @return 结果对象
|
||||
* @throws NoSuchMethodException
|
||||
* @throws InvocationTargetException
|
||||
* @throws InstantiationException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public static <T> T loadElement(Element element, Class<T> clazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
T t = clazz.getDeclaredConstructor().newInstance();
|
||||
for (Field field : fields) {
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
MessageElement annotation = field.getAnnotation(MessageElement.class);
|
||||
if (annotation == null) {
|
||||
continue;
|
||||
}
|
||||
String value = annotation.value();
|
||||
String subVal = annotation.subVal();
|
||||
Element element1 = element.element(value);
|
||||
if (element1 == null) {
|
||||
continue;
|
||||
}
|
||||
if ("".equals(subVal)) {
|
||||
// 无下级数据
|
||||
Object fieldVal = element1.isTextOnly() ? element1.getText() : loadElement(element1, field.getType());
|
||||
Object o = simpleTypeDeal(field.getType(), fieldVal);
|
||||
ReflectionUtils.setField(field, t, o);
|
||||
} else {
|
||||
// 存在下级数据
|
||||
ArrayList<Object> list = new ArrayList<>();
|
||||
Type genericType = field.getGenericType();
|
||||
if (!(genericType instanceof ParameterizedType)) {
|
||||
continue;
|
||||
}
|
||||
Class<?> aClass = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
|
||||
for (Element element2 : element1.elements(subVal)) {
|
||||
list.add(loadElement(element2, aClass));
|
||||
}
|
||||
ReflectionUtils.setField(field, t, list);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单类型处理
|
||||
*
|
||||
* @param tClass
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
private static Object simpleTypeDeal(Class<?> tClass, Object val) {
|
||||
if (tClass.equals(String.class)) {
|
||||
return val.toString();
|
||||
}
|
||||
if (tClass.equals(Integer.class)) {
|
||||
return Integer.valueOf(val.toString());
|
||||
}
|
||||
if (tClass.equals(Double.class)) {
|
||||
return Double.valueOf(val.toString());
|
||||
}
|
||||
if (tClass.equals(Long.class)) {
|
||||
return Long.valueOf(val.toString());
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -36,7 +36,7 @@ public class ZLMRESTfulUtils {
|
|||
// 设置连接超时时间
|
||||
httpClientBuilder.connectTimeout(5,TimeUnit.SECONDS);
|
||||
// 设置读取超时时间
|
||||
httpClientBuilder.readTimeout(15,TimeUnit.SECONDS);
|
||||
httpClientBuilder.readTimeout(10,TimeUnit.SECONDS);
|
||||
// 设置连接池
|
||||
httpClientBuilder.connectionPool(new ConnectionPool(16, 5, TimeUnit.MINUTES));
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
@ -189,6 +189,7 @@ public class ZLMRESTfulUtils {
|
|||
FileOutputStream outStream = new FileOutputStream(snapFile);
|
||||
|
||||
outStream.write(Objects.requireNonNull(response.body()).bytes());
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
} else {
|
||||
logger.error(String.format("[ %s ]请求失败: %s %s", url, response.code(), response.message()));
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
||||
|
||||
public class HookResult {
|
||||
|
||||
private int code;
|
||||
private String msg;
|
||||
|
||||
|
||||
public HookResult() {
|
||||
}
|
||||
|
||||
public HookResult(int code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public static HookResult SUCCESS(){
|
||||
return new HookResult(0, "success");
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
||||
|
||||
public class HookResultForOnPublish extends HookResult{
|
||||
|
||||
private boolean enable_audio;
|
||||
private boolean enable_mp4;
|
||||
private int mp4_max_second;
|
||||
|
||||
public HookResultForOnPublish() {
|
||||
}
|
||||
|
||||
public static HookResultForOnPublish SUCCESS(){
|
||||
return new HookResultForOnPublish(0, "success");
|
||||
}
|
||||
|
||||
public HookResultForOnPublish(int code, String msg) {
|
||||
setCode(code);
|
||||
setMsg(msg);
|
||||
}
|
||||
|
||||
public boolean isEnable_audio() {
|
||||
return enable_audio;
|
||||
}
|
||||
|
||||
public void setEnable_audio(boolean enable_audio) {
|
||||
this.enable_audio = enable_audio;
|
||||
}
|
||||
|
||||
public boolean isEnable_mp4() {
|
||||
return enable_mp4;
|
||||
}
|
||||
|
||||
public void setEnable_mp4(boolean enable_mp4) {
|
||||
this.enable_mp4 = enable_mp4;
|
||||
}
|
||||
|
||||
public int getMp4_max_second() {
|
||||
return mp4_max_second;
|
||||
}
|
||||
|
||||
public void setMp4_max_second(int mp4_max_second) {
|
||||
this.mp4_max_second = mp4_max_second;
|
||||
}
|
||||
}
|
|
@ -152,6 +152,10 @@ public class GbStreamServiceImpl implements IGbStreamService {
|
|||
|
||||
@Override
|
||||
public void sendCatalogMsg(GbStream gbStream, String type) {
|
||||
if (gbStream == null || type == null) {
|
||||
logger.warn("[发送目录订阅]类型:流信息或类型为NULL");
|
||||
return;
|
||||
}
|
||||
List<GbStream> gbStreams = new ArrayList<>();
|
||||
if (gbStream.getGbId() != null) {
|
||||
gbStreams.add(gbStream);
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
|||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.JsonUtil;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
@ -241,7 +242,10 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||
String onlineKey = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetting.getServerId();
|
||||
for (Object mediaServerKey : mediaServerKeys) {
|
||||
String key = (String) mediaServerKey;
|
||||
MediaServerItem mediaServerItem = (MediaServerItem) RedisUtil.get(key);
|
||||
MediaServerItem mediaServerItem = JsonUtil.redisJsonToObject(key, MediaServerItem.class);
|
||||
if (Objects.isNull(mediaServerItem)) {
|
||||
continue;
|
||||
}
|
||||
// 检查状态
|
||||
Double aDouble = RedisUtil.zScore(onlineKey, mediaServerItem.getId());
|
||||
if (aDouble != null) {
|
||||
|
@ -293,7 +297,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||
return null;
|
||||
}
|
||||
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerId;
|
||||
return (MediaServerItem)RedisUtil.get(key);
|
||||
return JsonUtil.redisJsonToObject(key, MediaServerItem.class);
|
||||
}
|
||||
|
||||
|
||||
|
@ -410,8 +414,10 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||
SsrcConfig ssrcConfig = new SsrcConfig(zlmServerConfig.getGeneralMediaServerId(), null, sipConfig.getDomain());
|
||||
serverItem.setSsrcConfig(ssrcConfig);
|
||||
}else {
|
||||
MediaServerItem mediaServerItemInRedis = (MediaServerItem)RedisUtil.get(key);
|
||||
serverItem.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig());
|
||||
MediaServerItem mediaServerItemInRedis = JsonUtil.redisJsonToObject(key, MediaServerItem.class);
|
||||
if (Objects.nonNull(mediaServerItemInRedis)) {
|
||||
serverItem.setSsrcConfig(mediaServerItemInRedis.getSsrcConfig());
|
||||
}
|
||||
}
|
||||
RedisUtil.set(key, serverItem);
|
||||
resetOnlineServerItem(serverItem);
|
||||
|
|
|
@ -184,7 +184,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
|
|||
@Override
|
||||
public boolean stop(String app, String streamId) {
|
||||
StreamPushItem streamPushItem = streamPushMapper.selectOne(app, streamId);
|
||||
gbStreamService.sendCatalogMsg(streamPushItem, CatalogEvent.DEL);
|
||||
if (streamPushItem != null) {
|
||||
gbStreamService.sendCatalogMsg(streamPushItem, CatalogEvent.DEL);
|
||||
}
|
||||
|
||||
platformGbStreamMapper.delByAppAndStream(app, streamId);
|
||||
gbStreamMapper.del(app, streamId);
|
||||
|
|
|
@ -62,16 +62,16 @@ public class RedisAlarmMsgListener implements MessageListener {
|
|||
}
|
||||
String gbId = alarmChannelMessage.getGbId();
|
||||
|
||||
DeviceAlarm deviceAlarm = new DeviceAlarm();
|
||||
deviceAlarm.setCreateTime(DateUtil.getNow());
|
||||
deviceAlarm.setChannelId(gbId);
|
||||
deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
|
||||
deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
|
||||
deviceAlarm.setAlarmPriority("1");
|
||||
deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
|
||||
deviceAlarm.setAlarmType("1");
|
||||
deviceAlarm.setLongitude(0D);
|
||||
deviceAlarm.setLatitude(0D);
|
||||
DeviceAlarm deviceAlarm = new DeviceAlarm();
|
||||
deviceAlarm.setCreateTime(DateUtil.getNow());
|
||||
deviceAlarm.setChannelId(gbId);
|
||||
deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription());
|
||||
deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn());
|
||||
deviceAlarm.setAlarmType("" + alarmChannelMessage.getAlarmType());
|
||||
deviceAlarm.setAlarmPriority("1");
|
||||
deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601());
|
||||
deviceAlarm.setLongitude(0);
|
||||
deviceAlarm.setLatitude(0);
|
||||
|
||||
if (ObjectUtils.isEmpty(gbId)) {
|
||||
// 发送给所有的上级
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.storager;
|
|||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
||||
import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.ChannelSourceInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||
|
@ -186,7 +185,13 @@ public interface IVideoManagerStorage {
|
|||
|
||||
Device queryVideoDeviceByPlatformIdAndChannelId(String platformId, String channelId);
|
||||
|
||||
|
||||
/**
|
||||
* 针对deviceinfo指令的查询接口
|
||||
* @param platformId 平台id
|
||||
* @param channelId 通道id
|
||||
* @return 设备信息
|
||||
*/
|
||||
Device queryDeviceInfoByPlatformIdAndChannelId(String platformId, String channelId);
|
||||
/**
|
||||
* 添加Mobile Position设备移动位置
|
||||
* @param mobilePosition
|
||||
|
@ -324,6 +329,8 @@ public interface IVideoManagerStorage {
|
|||
*/
|
||||
boolean resetChannels(String deviceId, List<DeviceChannel> deviceChannelList);
|
||||
|
||||
boolean updateChannels(String deviceId, List<DeviceChannel> deviceChannelList);
|
||||
|
||||
/**
|
||||
* 获取目录信息
|
||||
* @param platformId
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.genersoft.iot.vmp.storager.dao;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -20,7 +21,7 @@ public interface DeviceAlarmMapper {
|
|||
int add(DeviceAlarm alarm);
|
||||
|
||||
|
||||
@Select(value = {" <script>" +
|
||||
@Select( value = {" <script>" +
|
||||
" SELECT * FROM device_alarm " +
|
||||
" WHERE 1=1 " +
|
||||
" <if test=\"deviceId != null\" > AND deviceId = #{deviceId}</if>" +
|
||||
|
|
|
@ -107,4 +107,14 @@ public interface PlatformChannelMapper {
|
|||
"DELETE FROM platform_gb_channel WHERE platformId=#{platformId} and catalogId=#{catalogId}" +
|
||||
"</script>")
|
||||
int delChannelForGBByCatalogId(String platformId, String catalogId);
|
||||
|
||||
@Select("select dc.channelId deviceId,dc.name,d.manufacturer,d.model,d.firmware\n" +
|
||||
"from platform_gb_channel pgc\n" +
|
||||
" left join device_channel dc on dc.id = pgc.deviceChannelId\n" +
|
||||
" left join device d on dc.deviceId = d.deviceId\n" +
|
||||
"where dc.channelId = #{channelId} and pgc.platformId=#{platformId}")
|
||||
List<Device> queryDeviceInfoByPlatformIdAndChannelId(String platformId, String channelId);
|
||||
|
||||
@Select("SELECT pgc.platformId FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}'")
|
||||
List<String> queryParentPlatformByChannelId(String channelId);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
|||
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
|
||||
import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
|
||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||
import com.genersoft.iot.vmp.utils.JsonUtil;
|
||||
import com.genersoft.iot.vmp.utils.SystemInfoUtils;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -157,7 +158,10 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
}
|
||||
for (Object player : players) {
|
||||
String key = (String) player;
|
||||
StreamInfo streamInfo = (StreamInfo) RedisUtil.get(key);
|
||||
StreamInfo streamInfo = JsonUtil.redisJsonToObject(key, StreamInfo.class);
|
||||
if (Objects.isNull(streamInfo)) {
|
||||
continue;
|
||||
}
|
||||
streamInfos.put(streamInfo.getDeviceID() + "_" + streamInfo.getChannelId(), streamInfo);
|
||||
}
|
||||
return streamInfos;
|
||||
|
@ -624,8 +628,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
@Override
|
||||
public ThirdPartyGB queryMemberNoGBId(String queryKey) {
|
||||
String key = VideoManagerConstants.WVP_STREAM_GB_ID_PREFIX + queryKey;
|
||||
JSONObject jsonObject = (JSONObject)RedisUtil.get(key);
|
||||
return jsonObject.to(ThirdPartyGB.class);
|
||||
return JsonUtil.redisJsonToObject(key, ThirdPartyGB.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -664,7 +667,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
@Override
|
||||
public Device getDevice(String deviceId) {
|
||||
String key = VideoManagerConstants.DEVICE_PREFIX + userSetting.getServerId() + "_" + deviceId;
|
||||
return (Device)RedisUtil.get(key);
|
||||
return JsonUtil.redisJsonToObject(key, Device.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -676,7 +679,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
@Override
|
||||
public GPSMsgInfo getGpsMsgInfo(String gbId) {
|
||||
String key = VideoManagerConstants.WVP_STREAM_GPS_MSG_PREFIX + userSetting.getServerId() + "_" + gbId;
|
||||
return (GPSMsgInfo)RedisUtil.get(key);
|
||||
return JsonUtil.redisJsonToObject(key, GPSMsgInfo.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -686,9 +689,9 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
List<Object> keys = RedisUtil.scan(scanKey);
|
||||
for (Object o : keys) {
|
||||
String key = (String) o;
|
||||
GPSMsgInfo gpsMsgInfo = (GPSMsgInfo) RedisUtil.get(key);
|
||||
if (!gpsMsgInfo.isStored()) { // 只取没有存过得
|
||||
result.add((GPSMsgInfo) RedisUtil.get(key));
|
||||
GPSMsgInfo gpsMsgInfo = JsonUtil.redisJsonToObject(key, GPSMsgInfo.class);
|
||||
if (Objects.nonNull(gpsMsgInfo) && !gpsMsgInfo.isStored()) { // 只取没有存过得
|
||||
result.add(JsonUtil.redisJsonToObject(key, GPSMsgInfo.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -710,7 +713,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
@Override
|
||||
public StreamAuthorityInfo getStreamAuthorityInfo(String app, String stream) {
|
||||
String key = VideoManagerConstants.MEDIA_STREAM_AUTHORITY + userSetting.getServerId() + "_" + app+ "_" + stream ;
|
||||
return (StreamAuthorityInfo) RedisUtil.get(key);
|
||||
return JsonUtil.redisJsonToObject(key, StreamAuthorityInfo.class);
|
||||
|
||||
}
|
||||
|
||||
|
@ -721,7 +724,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
List<Object> keys = RedisUtil.scan(scanKey);
|
||||
for (Object o : keys) {
|
||||
String key = (String) o;
|
||||
result.add((StreamAuthorityInfo) RedisUtil.get(key));
|
||||
result.add(JsonUtil.redisJsonToObject(key, StreamAuthorityInfo.class));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -735,7 +738,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
List<Object> keys = RedisUtil.scan(scanKey);
|
||||
if (keys.size() > 0) {
|
||||
String key = (String) keys.get(0);
|
||||
result = (OnStreamChangedHookParam)RedisUtil.get(key);
|
||||
result = JsonUtil.redisJsonToObject(key, OnStreamChangedHookParam.class);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -827,7 +830,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||
|
||||
@Override
|
||||
public void sendAlarmMsg(AlarmChannelMessage msg) {
|
||||
String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM;
|
||||
String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE;
|
||||
logger.info("[redis发送通知] 报警{}: {}", key, JSON.toJSON(msg));
|
||||
RedisUtil.convertAndSend(key, (JSONObject)JSON.toJSON(msg));
|
||||
}
|
||||
|
|
|
@ -126,6 +126,15 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
|||
if (allChannelMap.containsKey(deviceChannel.getChannelId())) {
|
||||
deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
|
||||
deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
|
||||
if (allChannelMap.get(deviceChannel.getChannelId()).getStatus() !=deviceChannel.getStatus()){
|
||||
List<String> strings = platformChannelMapper.queryParentPlatformByChannelId(deviceChannel.getChannelId());
|
||||
if (!CollectionUtils.isEmpty(strings)){
|
||||
strings.forEach(platformId->{
|
||||
eventPublisher.catalogEventPublish(platformId, deviceChannel, deviceChannel.getStatus()==1?CatalogEvent.ON:CatalogEvent.OFF);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
channels.add(deviceChannel);
|
||||
if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
|
||||
|
@ -187,6 +196,119 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean updateChannels(String deviceId, List<DeviceChannel> deviceChannelList) {
|
||||
if (CollectionUtils.isEmpty(deviceChannelList)) {
|
||||
return false;
|
||||
}
|
||||
List<DeviceChannel> allChannels = deviceChannelMapper.queryAllChannels(deviceId);
|
||||
Map<String,DeviceChannel> allChannelMap = new ConcurrentHashMap<>();
|
||||
if (allChannels.size() > 0) {
|
||||
for (DeviceChannel deviceChannel : allChannels) {
|
||||
allChannelMap.put(deviceChannel.getChannelId(), deviceChannel);
|
||||
}
|
||||
}
|
||||
List<DeviceChannel> addChannels = new ArrayList<>();
|
||||
List<DeviceChannel> updateChannels = new ArrayList<>();
|
||||
|
||||
|
||||
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
|
||||
// 数据去重
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
Map<String, Integer> subContMap = new HashMap<>();
|
||||
if (deviceChannelList.size() > 0) {
|
||||
// 数据去重
|
||||
Set<String> gbIdSet = new HashSet<>();
|
||||
for (DeviceChannel deviceChannel : deviceChannelList) {
|
||||
if (!gbIdSet.contains(deviceChannel.getChannelId())) {
|
||||
gbIdSet.add(deviceChannel.getChannelId());
|
||||
if (allChannelMap.containsKey(deviceChannel.getChannelId())) {
|
||||
deviceChannel.setStreamId(allChannelMap.get(deviceChannel.getChannelId()).getStreamId());
|
||||
deviceChannel.setHasAudio(allChannelMap.get(deviceChannel.getChannelId()).isHasAudio());
|
||||
updateChannels.add(deviceChannel);
|
||||
}else {
|
||||
addChannels.add(deviceChannel);
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(deviceChannel.getParentId())) {
|
||||
if (subContMap.get(deviceChannel.getParentId()) == null) {
|
||||
subContMap.put(deviceChannel.getParentId(), 1);
|
||||
}else {
|
||||
Integer count = subContMap.get(deviceChannel.getParentId());
|
||||
subContMap.put(deviceChannel.getParentId(), count++);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
stringBuilder.append(deviceChannel.getChannelId()).append(",");
|
||||
}
|
||||
}
|
||||
if (addChannels.size() > 0) {
|
||||
for (DeviceChannel channel : addChannels) {
|
||||
if (subContMap.get(channel.getChannelId()) != null){
|
||||
channel.setSubCount(subContMap.get(channel.getChannelId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updateChannels.size() > 0) {
|
||||
for (DeviceChannel channel : updateChannels) {
|
||||
if (subContMap.get(channel.getChannelId()) != null){
|
||||
channel.setSubCount(subContMap.get(channel.getChannelId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (stringBuilder.length() > 0) {
|
||||
logger.info("[目录查询]收到的数据存在重复: {}" , stringBuilder);
|
||||
}
|
||||
if(CollectionUtils.isEmpty(updateChannels) && CollectionUtils.isEmpty(addChannels) ){
|
||||
logger.info("通道更新,数据为空={}" , deviceChannelList);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
int limitCount = 300;
|
||||
boolean result = false;
|
||||
if (addChannels.size() > 0) {
|
||||
if (addChannels.size() > limitCount) {
|
||||
for (int i = 0; i < addChannels.size(); i += limitCount) {
|
||||
int toIndex = i + limitCount;
|
||||
if (i + limitCount > addChannels.size()) {
|
||||
toIndex = addChannels.size();
|
||||
}
|
||||
result = result || deviceChannelMapper.batchAdd(addChannels.subList(i, toIndex)) < 0;
|
||||
}
|
||||
}else {
|
||||
result = result || deviceChannelMapper.batchAdd(addChannels) < 0;
|
||||
}
|
||||
}
|
||||
if (updateChannels.size() > 0) {
|
||||
if (updateChannels.size() > limitCount) {
|
||||
for (int i = 0; i < updateChannels.size(); i += limitCount) {
|
||||
int toIndex = i + limitCount;
|
||||
if (i + limitCount > updateChannels.size()) {
|
||||
toIndex = updateChannels.size();
|
||||
}
|
||||
result = result || deviceChannelMapper.batchUpdate(updateChannels.subList(i, toIndex)) < 0;
|
||||
}
|
||||
}else {
|
||||
result = result || deviceChannelMapper.batchUpdate(updateChannels) < 0;
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
//事务回滚
|
||||
dataSourceTransactionManager.rollback(transactionStatus);
|
||||
}else {
|
||||
//手动提交
|
||||
dataSourceTransactionManager.commit(transactionStatus);
|
||||
}
|
||||
return true;
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
dataSourceTransactionManager.rollback(transactionStatus);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deviceChannelOnline(String deviceId, String channelId) {
|
||||
deviceChannelMapper.online(deviceId, channelId);
|
||||
|
@ -464,6 +586,20 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Device queryDeviceInfoByPlatformIdAndChannelId(String platformId, String channelId) {
|
||||
List<Device> devices = platformChannelMapper.queryDeviceInfoByPlatformIdAndChannelId(platformId, channelId);
|
||||
if (devices.size() > 1) {
|
||||
// 出现长度大于0的时候肯定是国标通道的ID重复了
|
||||
logger.warn("国标ID存在重复:{}", channelId);
|
||||
}
|
||||
if (devices.size() == 0) {
|
||||
return null;
|
||||
}else {
|
||||
return devices.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最新移动位置
|
||||
* @param deviceId
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.genersoft.iot.vmp.utils;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* JsonUtil
|
||||
*
|
||||
* @author KunLong-Luo
|
||||
* @version 1.0.0
|
||||
* @since 2023/2/2 15:24
|
||||
*/
|
||||
public final class JsonUtil {
|
||||
|
||||
private JsonUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* safe json type conversion
|
||||
*
|
||||
* @param key redis key
|
||||
* @param clazz cast type
|
||||
* @param <T>
|
||||
* @return result type
|
||||
*/
|
||||
public static <T> T redisJsonToObject(String key, Class<T> clazz) {
|
||||
Object jsonObject = RedisUtil.get(key);
|
||||
if (Objects.isNull(jsonObject)) {
|
||||
return null;
|
||||
}
|
||||
return clazz.cast(jsonObject);
|
||||
}
|
||||
}
|
|
@ -110,7 +110,7 @@ public class DeviceControl {
|
|||
msg.setKey(key);
|
||||
msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeAllResult(msg);
|
||||
});
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 开始/停止录像: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
|
@ -143,7 +143,7 @@ public class DeviceControl {
|
|||
msg.setKey(key);
|
||||
msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage());
|
||||
|
@ -192,7 +192,7 @@ public class DeviceControl {
|
|||
msg.setKey(key);
|
||||
msg.setData(String.format("报警复位操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 报警复位: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
|
@ -274,7 +274,7 @@ public class DeviceControl {
|
|||
msg.setKey(key);
|
||||
msg.setData(String.format("看守位控制操作失败,错误码: %s, %s", event.statusCode, event.msg));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
},null);
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 看守位控制: {}", e.getMessage());
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.genersoft.iot.vmp.vmanager.gb28181.playback;
|
||||
|
||||
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.ServiceException;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
|
@ -64,13 +65,16 @@ public class PlaybackController {
|
|||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
@Autowired
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Operation(summary = "开始视频回放")
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "startTime", description = "开始时间", required = true)
|
||||
@Parameter(name = "endTime", description = "结束时间", required = true)
|
||||
@GetMapping("/start/{deviceId}/{channelId}")
|
||||
public DeferredResult<WVPResult<StreamContent>> play(@PathVariable String deviceId, @PathVariable String channelId,
|
||||
public DeferredResult<WVPResult<StreamContent>> start(@PathVariable String deviceId, @PathVariable String channelId,
|
||||
String startTime, String endTime) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
@ -79,7 +83,7 @@ public class PlaybackController {
|
|||
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
|
||||
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(30000L);
|
||||
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
|
||||
resultHolder.put(key, uuid, result);
|
||||
|
||||
WVPResult<StreamContent> wvpResult = new WVPResult<>();
|
||||
|
|
|
@ -11,17 +11,13 @@ import com.genersoft.iot.vmp.utils.DateUtil;
|
|||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.security.sasl.AuthenticationException;
|
||||
|
@ -90,7 +86,7 @@ public class UserController {
|
|||
|
||||
|
||||
@PostMapping("/add")
|
||||
@Operation(summary = "停止视频回放")
|
||||
@Operation(summary = "添加用户")
|
||||
@Parameter(name = "username", description = "用户名", required = true)
|
||||
@Parameter(name = "password", description = "密码(未md5加密的密码)", required = true)
|
||||
@Parameter(name = "roleId", description = "角色ID", required = true)
|
||||
|
|
|
@ -167,7 +167,7 @@ user-settings:
|
|||
senior-sdp: false
|
||||
# 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认)
|
||||
save-position-history: false
|
||||
# 点播等待超时时间,单位:毫秒
|
||||
# 点播/录像回放 等待超时时间,单位:毫秒
|
||||
play-timeout: 18000
|
||||
# 上级点播等待超时时间,单位:毫秒
|
||||
platform-play-timeout: 60000
|
||||
|
|
|
@ -1,86 +1,86 @@
|
|||
spring:
|
||||
# [可选]上传文件大小限制
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 100MB
|
||||
# REDIS数据库配置
|
||||
redis:
|
||||
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
|
||||
host: 127.0.0.1
|
||||
# [必须修改] 端口号
|
||||
port: 6379
|
||||
# [可选] 数据库 DB
|
||||
database: 6
|
||||
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
|
||||
password: face2020
|
||||
# [可选] 超时时间
|
||||
timeout: 10000
|
||||
# mysql数据源
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
|
||||
username: root
|
||||
password: 123456
|
||||
druid:
|
||||
initialSize: 10 # 连接池初始化连接数
|
||||
maxActive: 200 # 连接池最大连接数
|
||||
minIdle: 5 # 连接池最小空闲连接数
|
||||
maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
|
||||
keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
|
||||
validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
|
||||
testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小
|
||||
timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒
|
||||
filters: stat,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j
|
||||
useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
|
||||
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000
|
||||
#stat-view-servlet.url-pattern: /admin/druid/*
|
||||
# [可选]上传文件大小限制
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 100MB
|
||||
# REDIS数据库配置
|
||||
redis:
|
||||
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
|
||||
host: 127.0.0.1
|
||||
# [必须修改] 端口号
|
||||
port: 6379
|
||||
# [可选] 数据库 DB
|
||||
database: 6
|
||||
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
|
||||
password: face2020
|
||||
# [可选] 超时时间
|
||||
timeout: 10000
|
||||
# mysql数据源
|
||||
datasource:
|
||||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
|
||||
username: root
|
||||
password: 123456
|
||||
druid:
|
||||
initialSize: 10 # 连接池初始化连接数
|
||||
maxActive: 200 # 连接池最大连接数
|
||||
minIdle: 5 # 连接池最小空闲连接数
|
||||
maxWait: 60000 # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
|
||||
keepAlive: true # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
|
||||
validationQuery: select 1 # 检测连接是否有效sql,要求是查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
|
||||
testWhileIdle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
testOnBorrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
testOnReturn: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
poolPreparedStatements: false # 是否開啟PSCache,並且指定每個連線上PSCache的大小
|
||||
timeBetweenEvictionRunsMillis: 60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
|
||||
minEvictableIdleTimeMillis: 300000 # 配置一個連線在池中最小生存的時間,單位是毫秒
|
||||
filters: stat,slf4j # 配置监控统计拦截的filters,监控统计用的filter:sta, 日志用的filter:log4j
|
||||
useGlobalDataSourceStat: true # 合并多个DruidDataSource的监控数据
|
||||
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000
|
||||
#stat-view-servlet.url-pattern: /admin/druid/*
|
||||
|
||||
#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
||||
server:
|
||||
port: 18080
|
||||
port: 18080
|
||||
|
||||
# 作为28181服务器的配置
|
||||
sip:
|
||||
# [必须修改] 本机的IP
|
||||
ip: 192.168.41.16
|
||||
# [可选] 28181服务监听的端口
|
||||
port: 5060
|
||||
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
|
||||
# 后两位为行业编码,定义参照附录D.3
|
||||
# 3701020049标识山东济南历下区 信息行业接入
|
||||
# [可选]
|
||||
domain: 4401020049
|
||||
# [可选]
|
||||
id: 44010200492000000001
|
||||
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
|
||||
password: admin123
|
||||
# [必须修改] 本机的IP
|
||||
ip: 192.168.41.16
|
||||
# [可选] 28181服务监听的端口
|
||||
port: 5060
|
||||
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
|
||||
# 后两位为行业编码,定义参照附录D.3
|
||||
# 3701020049标识山东济南历下区 信息行业接入
|
||||
# [可选]
|
||||
domain: 4401020049
|
||||
# [可选]
|
||||
id: 44010200492000000001
|
||||
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
|
||||
password: admin123
|
||||
|
||||
#zlm 默认服务器配置
|
||||
media:
|
||||
id: FQ3TF8yT83wh5Wvz
|
||||
# [必须修改] zlm服务器的内网IP
|
||||
ip: 192.168.41.16
|
||||
# [必须修改] zlm服务器的http.port
|
||||
http-port: 8091
|
||||
# [可选] zlm服务器的hook.admin_params=secret
|
||||
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
|
||||
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
||||
rtp:
|
||||
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
||||
enable: true
|
||||
# [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
|
||||
port-range: 30000,30500 # 端口范围
|
||||
# [可选] 国标级联在此范围内选择端口发送媒体流,
|
||||
send-port-range: 30000,30500 # 端口范围
|
||||
# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
|
||||
record-assist-port: 18081
|
||||
id: FQ3TF8yT83wh5Wvz
|
||||
# [必须修改] zlm服务器的内网IP
|
||||
ip: 192.168.41.16
|
||||
# [必须修改] zlm服务器的http.port
|
||||
http-port: 8091
|
||||
# [可选] zlm服务器的hook.admin_params=secret
|
||||
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
|
||||
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
||||
rtp:
|
||||
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
||||
enable: true
|
||||
# [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功
|
||||
port-range: 30000,30500 # 端口范围
|
||||
# [可选] 国标级联在此范围内选择端口发送媒体流,
|
||||
send-port-range: 30000,30500 # 端口范围
|
||||
# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
|
||||
record-assist-port: 18081
|
||||
# [可选] 日志配置, 一般不需要改
|
||||
logging:
|
||||
config: classpath:logback-spring-local.xml
|
||||
config: classpath:logback-spring-local.xml
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
spring:
|
||||
application:
|
||||
name: wvp
|
||||
profiles:
|
||||
active: local
|
||||
# flayway相关配置
|
||||
flyway:
|
||||
enabled: true #是否启用flyway(默认true)
|
||||
locations: classpath:db/migration #这个路径指的是fly版本控制的sql语句存放的路径,可以多个,可以给每个环境使用不同位置,比如classpath:db/migration,classpath:test/db/migration
|
||||
baseline-on-migrate: true #开启自动创建flyway元数据表标识 默认: false
|
||||
# 与 baseline-on-migrate: true 搭配使用,将当前数据库初始版本设置为0
|
||||
baseline-version: 0
|
||||
clean-disabled: true #禁止flyway执行清理
|
||||
# 假如已经执行了版本1和版本3,如果增加了一个版本2,下面这个选项将会允许执行版本2的脚本
|
||||
out-of-order: true
|
||||
table: flyway_schema_history_${spring.application.name} #用于记录所有的版本变化记录
|
|
@ -39,6 +39,7 @@ CREATE TABLE `device` (
|
|||
`updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`port` int DEFAULT NULL,
|
||||
`expires` int DEFAULT NULL,
|
||||
`keepaliveIntervalTime` int DEFAULT NULL,
|
||||
`subscribeCycleForCatalog` int DEFAULT NULL,
|
||||
`hostAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`charset` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
|
@ -47,7 +47,8 @@ exports.cssLoaders = function (options) {
|
|||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
fallback: 'vue-style-loader',
|
||||
publicPath: '../../'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
|
|
|
@ -8,8 +8,8 @@ module.exports = {
|
|||
dev: {
|
||||
|
||||
// Paths
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
assetsSubDirectory: './static',
|
||||
assetsPublicPath: './',
|
||||
proxyTable: {
|
||||
'/debug': {
|
||||
target: 'https://default.wvp-pro.cn:18080',
|
||||
|
@ -61,7 +61,7 @@ module.exports = {
|
|||
// Paths
|
||||
assetsRoot: path.resolve(__dirname, '../../src/main/resources/static/'),
|
||||
assetsSubDirectory: './static',
|
||||
assetsPublicPath: '/',
|
||||
assetsPublicPath: './',
|
||||
|
||||
/**
|
||||
* Source Maps
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${that.mediaServerId}/api/record/list`,
|
||||
url:`./record_proxy/${that.mediaServerId}/api/record/list`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count
|
||||
|
@ -185,7 +185,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'delete',
|
||||
url:`/record_proxy/api/record/delete`,
|
||||
url:`./record_proxy/api/record/delete`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
<template>
|
||||
<div id="recordDetail">
|
||||
<el-container>
|
||||
|
||||
<el-aside width="300px">
|
||||
|
||||
<el-aside width="260px">
|
||||
<div class="record-list-box-box">
|
||||
<el-date-picker size="mini" v-model="chooseDate" :picker-options="pickerOptions" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="dateChange()"></el-date-picker>
|
||||
<div style="margin-top: 20px">
|
||||
<el-date-picker size="mini" style="width: 160px" v-model="chooseDate" :picker-options="pickerOptions" type="date" value-format="yyyy-MM-dd" placeholder="日期" @change="dateChange()"></el-date-picker>
|
||||
<el-button size="mini" type="primary" icon="fa fa-cloud-download" style="margin: auto; margin-left: 12px " title="裁剪合并" @click="drawerOpen"></el-button>
|
||||
</div>
|
||||
<div class="record-list-box" :style="recordListStyle">
|
||||
<ul v-if="detailFiles.length >0" class="infinite-list record-list" v-infinite-scroll="infiniteScroll" >
|
||||
<li v-for="item in detailFiles" class="infinite-list-item record-list-item" >
|
||||
<li v-for="(item,index) in detailFiles" :key="index" class="infinite-list-item record-list-item" >
|
||||
<el-tag v-if="choosedFile != item" @click="chooseFile(item)">
|
||||
<i class="el-icon-video-camera" ></i>
|
||||
{{ item.substring(0,17)}}
|
||||
|
@ -24,9 +25,7 @@
|
|||
<div v-if="detailFiles.length ==0" class="record-list-no-val" >暂无数据</div>
|
||||
</div>
|
||||
|
||||
<div class="record-list-option">
|
||||
<el-button size="mini" type="primary" icon="fa fa-cloud-download" style="margin: auto; " title="裁剪合并" @click="drawerOpen"></el-button>
|
||||
</div>
|
||||
|
||||
</el-aside>
|
||||
<el-main style="padding: 22px">
|
||||
<div class="playBox" :style="playerStyle">
|
||||
|
@ -45,7 +44,7 @@
|
|||
:marks="playTimeSliderMarks">
|
||||
</el-slider>
|
||||
<div class="slider-val-box">
|
||||
<div class="slider-val" v-for="item of detailFiles" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
|
||||
<div class="slider-val" v-for="(item,index) of detailFiles" :key="index" :style="'width:' + getDataWidth(item) + '%; left:' + getDataLeft(item) + '%'"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -62,7 +61,7 @@
|
|||
<el-tab-pane name="running">
|
||||
<span slot="label"><i class="el-icon-scissors"></i>进行中</span>
|
||||
<ul class="task-list">
|
||||
<li class="task-list-item" v-for="item in taskListForRuning">
|
||||
<li class="task-list-item" v-for="(item,index) in taskListForRuning" :key="index">
|
||||
<div class="task-list-item-box">
|
||||
<span>{{ item.startTime.substr(10) }}-{{item.endTime.substr(10)}}</span>
|
||||
<el-progress :percentage="(parseFloat(item.percentage)*100).toFixed(1)"></el-progress>
|
||||
|
@ -74,10 +73,10 @@
|
|||
<el-tab-pane name="ended">
|
||||
<span slot="label"><i class="el-icon-finished"></i>已完成</span>
|
||||
<ul class="task-list">
|
||||
<li class="task-list-item" v-for="item in taskListEnded">
|
||||
<li class="task-list-item" v-for="(item, index) in taskListEnded" :key="index">
|
||||
<div class="task-list-item-box" style="height: 2rem;line-height: 2rem;">
|
||||
<span>{{ item.startTime.substr(10) }}-{{item.endTime.substr(10)}}</span>
|
||||
<a class="el-icon-download download-btn" :href="basePath + '/download.html?url=../' + item.recordFile" target="_blank">
|
||||
<a class="el-icon-download download-btn" :href="mediaServerPath + '/download.html?url=../' + item.recordFile" target="_blank">
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -116,7 +115,7 @@
|
|||
props: ['recordFile', 'mediaServerId', 'dateFiles', 'mediaServerPath'],
|
||||
data() {
|
||||
return {
|
||||
basePath: `${this.mediaServerPath}`,
|
||||
basePath: `${this.mediaServerPath}/record`,
|
||||
dateFilesObj: [],
|
||||
detailFiles: [],
|
||||
chooseDate: null,
|
||||
|
@ -147,6 +146,7 @@
|
|||
"margin-bottom": "20px",
|
||||
"height": this.winHeight + "px",
|
||||
},
|
||||
timeFormat:'00:00:00',
|
||||
winHeight: window.innerHeight - 240,
|
||||
playTime: 0,
|
||||
playTimeSliderMarks: {
|
||||
|
@ -213,7 +213,7 @@
|
|||
this.currentPage = 1;
|
||||
this.sliderMIn= 0;
|
||||
this.sliderMax= 86400;
|
||||
let chooseFullDate = new Date(this.chooseDate + " " + "00:00:00");
|
||||
let chooseFullDate = new Date(this.chooseDate +" " + this.timeFormat);
|
||||
if (chooseFullDate.getFullYear() !== this.queryDate.getFullYear()
|
||||
|| chooseFullDate.getMonth() !== this.queryDate.getMonth()){
|
||||
// this.getDateInYear()
|
||||
|
@ -222,8 +222,8 @@
|
|||
if (this.detailFiles.length > 0){
|
||||
let timeForFile = this.getTimeForFile(this.detailFiles[0]);
|
||||
let lastTimeForFile = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1]);
|
||||
let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
|
||||
let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + "00:00:00").getTime()
|
||||
let timeNum = timeForFile[0].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime()
|
||||
let lastTimeNum = lastTimeForFile[1].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime()
|
||||
|
||||
this.playTime = parseInt(timeNum/1000)
|
||||
this.sliderMIn = parseInt(timeNum/1000 - timeNum/1000%(60*60))
|
||||
|
@ -241,7 +241,7 @@
|
|||
let that = this;
|
||||
that.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${that.mediaServerId}/api/record/file/list`,
|
||||
url:`./record_proxy/${that.mediaServerId}/api/record/file/list`,
|
||||
params: {
|
||||
app: that.recordFile.app,
|
||||
stream: that.recordFile.stream,
|
||||
|
@ -281,14 +281,14 @@
|
|||
},
|
||||
getDataLeft(item){
|
||||
let timeForFile = this.getTimeForFile(item);
|
||||
let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " 00:00:00").getTime()
|
||||
let differenceTime = timeForFile[0].getTime() - new Date(this.chooseDate + " " + this.timeFormat).getTime()
|
||||
return parseFloat((differenceTime - this.sliderMIn * 1000)/((this.sliderMax - this.sliderMIn)*1000))*100 ;
|
||||
},
|
||||
playTimeChange(val){
|
||||
let minTime = this.getTimeForFile(this.detailFiles[0])[0]
|
||||
let maxTime = this.getTimeForFile(this.detailFiles[this.detailFiles.length - 1])[1];
|
||||
this.chooseFile(null);
|
||||
let timeMilli = new Date(this.chooseDate + " 00:00:00").getTime() + val*1000
|
||||
let timeMilli = new Date(this.chooseDate + " " + this.timeFormat).getTime() + val*1000
|
||||
if (timeMilli >= minTime.getTime() && timeMilli <= maxTime.getTime()){
|
||||
for (let i = 0; i < this.detailFiles.length; i++) {
|
||||
let timeForFile = this.getTimeForFile(this.detailFiles[i]);
|
||||
|
@ -302,10 +302,20 @@
|
|||
},
|
||||
getTimeForFile(file){
|
||||
let timeStr = file.substring(0,17);
|
||||
let starTime = new Date(this.chooseDate + " " + timeStr.split("-")[0]);
|
||||
let endTime = new Date(this.chooseDate + " " + timeStr.split("-")[1]);
|
||||
if(timeStr.indexOf("~") > 0){
|
||||
timeStr = timeStr.replaceAll("-",":")
|
||||
}
|
||||
let timeArr = timeStr.split("~");
|
||||
let starTime = new Date(this.chooseDate + " " + timeArr[0]);
|
||||
let endTime = new Date(this.chooseDate + " " + timeArr[1]);
|
||||
if(this.checkIsOver24h(starTime,endTime)){
|
||||
endTime = new Date(this.chooseDate + " " + "23:59:59");
|
||||
}
|
||||
return [starTime, endTime, endTime.getTime() - starTime.getTime()];
|
||||
},
|
||||
checkIsOver24h(starTime,endTime){
|
||||
return starTime > endTime;
|
||||
},
|
||||
playTimeFormat(val){
|
||||
let h = parseInt(val/3600);
|
||||
let m = parseInt((val - h*3600)/60);
|
||||
|
@ -330,7 +340,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'delete',
|
||||
url:`/record_proxy/${that.mediaServerId}/api/record/delete`,
|
||||
url:`./record_proxy/${that.mediaServerId}/api/record/delete`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count
|
||||
|
@ -349,7 +359,7 @@
|
|||
that.dateFilesObj = {};
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${that.mediaServerId}/api/record/date/list`,
|
||||
url:`./record_proxy/${that.mediaServerId}/api/record/date/list`,
|
||||
params: {
|
||||
app: that.recordFile.app,
|
||||
stream: that.recordFile.stream
|
||||
|
@ -398,7 +408,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${that.mediaServerId}/api/record/file/download/task/add`,
|
||||
url:`./record_proxy/${that.mediaServerId}/api/record/file/download/task/add`,
|
||||
params: {
|
||||
app: that.recordFile.app,
|
||||
stream: that.recordFile.stream,
|
||||
|
@ -423,7 +433,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${that.mediaServerId}/api/record/file/download/task/list`,
|
||||
url:`./record_proxy/${that.mediaServerId}/api/record/file/download/task/list`,
|
||||
params: {
|
||||
isEnd: isEnd,
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ export default {
|
|||
this.getDeviceListLoading = true;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/devices`,
|
||||
url: `./api/device/query/devices`,
|
||||
params: {
|
||||
page: this.currentPage,
|
||||
count: this.count
|
||||
|
@ -182,7 +182,7 @@ export default {
|
|||
}).then(() => {
|
||||
this.$axios({
|
||||
method: 'delete',
|
||||
url: `/api/device/query/devices/${row.deviceId}/delete`
|
||||
url: `./api/device/query/devices/${row.deviceId}/delete`
|
||||
}).then((res) => {
|
||||
this.getDeviceList();
|
||||
}).catch((error) => {
|
||||
|
@ -208,7 +208,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/device/query/devices/' + itemData.deviceId + '/sync'
|
||||
url: './api/device/query/devices/' + itemData.deviceId + '/sync'
|
||||
}).then((res) => {
|
||||
console.log("刷新设备结果:" + JSON.stringify(res));
|
||||
if (res.data.code !== 0) {
|
||||
|
@ -242,7 +242,7 @@ export default {
|
|||
await this.$axios({
|
||||
method: 'get',
|
||||
async: false,
|
||||
url: `/api/device/query/${deviceId}/sync_status/`,
|
||||
url: `./api/device/query/${deviceId}/sync_status/`,
|
||||
}).then((res) => {
|
||||
if (res.data.code == 0) {
|
||||
if (res.data.data.errorMsg !== null) {
|
||||
|
@ -261,7 +261,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url: '/api/device/query/transport/' + row.deviceId + '/' + row.streamMode
|
||||
url: './api/device/query/transport/' + row.deviceId + '/' + row.streamMode
|
||||
}).then(function (res) {
|
||||
|
||||
}).catch(function (e) {
|
||||
|
|
|
@ -197,7 +197,7 @@
|
|||
this.detailFiles = [];
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime
|
||||
url: './api/gb_record/query/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' + this.endTime
|
||||
}).then((res)=>{
|
||||
this.recordsLoading = false;
|
||||
if(res.data.code === 0) {
|
||||
|
@ -249,7 +249,7 @@
|
|||
} else {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' +
|
||||
url: './api/playback/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + this.startTime + '&endTime=' +
|
||||
this.endTime
|
||||
}).then((res)=> {
|
||||
if (res.data.code === 0) {
|
||||
|
@ -273,7 +273,7 @@
|
|||
console.log('前端控制:播放');
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/playback/resume/' + this.streamId
|
||||
url: './api/playback/resume/' + this.streamId
|
||||
}).then((res)=> {
|
||||
this.$refs["recordVideoPlayer"].play(this.videoUrl)
|
||||
});
|
||||
|
@ -282,14 +282,14 @@
|
|||
console.log('前端控制:暂停');
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/playback/pause/' + this.streamId
|
||||
url: './api/playback/pause/' + this.streamId
|
||||
}).then(function (res) {});
|
||||
},
|
||||
gbScale(command){
|
||||
console.log('前端控制:倍速 ' + command);
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/playback/speed/${this.streamId }/${command}`
|
||||
url: `./api/playback/speed/${this.streamId }/${command}`
|
||||
}).then(function (res) {});
|
||||
},
|
||||
downloadRecord: function (row) {
|
||||
|
@ -311,7 +311,7 @@
|
|||
}else {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
|
||||
url: './api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' +
|
||||
row.endTime + '&downloadSpeed=4'
|
||||
}).then( (res)=> {
|
||||
if (res.data.code === 0) {
|
||||
|
@ -332,7 +332,7 @@
|
|||
this.videoUrl = '';
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
|
||||
url: './api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.streamId
|
||||
}).then((res)=> {
|
||||
if (callback) callback(res)
|
||||
});
|
||||
|
@ -342,7 +342,7 @@
|
|||
this.videoUrl = '';
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
|
||||
url: './api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
|
||||
}).then(function (res) {
|
||||
if (callback) callback()
|
||||
});
|
||||
|
|
|
@ -81,7 +81,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:"/api/user/login",
|
||||
url:"./api/user/login",
|
||||
params: loginParam
|
||||
}).then(function (res) {
|
||||
window.clearTimeout(timeoutTask)
|
||||
|
|
|
@ -128,7 +128,7 @@ export default {
|
|||
var that = this;
|
||||
that.$axios({
|
||||
method: 'delete',
|
||||
url:`/api/platform/delete/${platform.serverGBId}`
|
||||
url:`./api/platform/delete/${platform.serverGBId}`
|
||||
}).then(function (res) {
|
||||
if (res.data.code === 0) {
|
||||
that.$message({
|
||||
|
@ -162,7 +162,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/platform/query/${that.count}/${that.currentPage}`
|
||||
url:`./api/platform/query/${that.count}/${that.currentPage}`
|
||||
}).then(function (res) {
|
||||
if (res.data.code === 0) {
|
||||
that.total = res.data.data.total;
|
||||
|
|
|
@ -171,7 +171,7 @@ export default {
|
|||
this.getDeviceListLoading = true;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/push/list`,
|
||||
url: `./api/push/list`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count,
|
||||
|
@ -197,7 +197,7 @@ export default {
|
|||
this.getListLoading = true;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/push/getPlayUrl',
|
||||
url: './api/push/getPlayUrl',
|
||||
params: {
|
||||
app: row.app,
|
||||
stream: row.stream,
|
||||
|
@ -223,7 +223,7 @@ export default {
|
|||
let that = this;
|
||||
that.$axios({
|
||||
method: "post",
|
||||
url: "/api/push/stop",
|
||||
url: "./api/push/stop",
|
||||
params: {
|
||||
app: row.app,
|
||||
streamId: row.stream
|
||||
|
@ -247,7 +247,7 @@ export default {
|
|||
let that = this;
|
||||
that.$axios({
|
||||
method: "delete",
|
||||
url: "/api/push/remove_form_gb",
|
||||
url: "./api/push/remove_form_gb",
|
||||
data: row
|
||||
}).then((res) => {
|
||||
if (res.data.code === 0) {
|
||||
|
@ -274,7 +274,7 @@ export default {
|
|||
let that = this;
|
||||
that.$axios({
|
||||
method: "delete",
|
||||
url: "/api/push/batchStop",
|
||||
url: "./api/push/batchStop",
|
||||
data: {
|
||||
gbStreams: this.multipleSelection
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/proxy/list`,
|
||||
url:`./api/proxy/list`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count
|
||||
|
@ -190,7 +190,7 @@
|
|||
addOnvif: function(){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/onvif/search?timeout=3000`,
|
||||
url:`./api/onvif/search?timeout=3000`,
|
||||
}).then((res) =>{
|
||||
if (res.data.code === 0 ){
|
||||
if (res.data.data.length > 0) {
|
||||
|
@ -218,7 +218,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/push/getPlayUrl`,
|
||||
url:`./api/push/getPlayUrl`,
|
||||
params: {
|
||||
app: row.app,
|
||||
stream: row.stream,
|
||||
|
@ -247,7 +247,7 @@
|
|||
let that = this;
|
||||
that.$axios({
|
||||
method:"delete",
|
||||
url:"/api/proxy/del",
|
||||
url:"./api/proxy/del",
|
||||
params:{
|
||||
app: row.app,
|
||||
stream: row.stream
|
||||
|
@ -263,7 +263,7 @@
|
|||
this.$set(row, 'startBtnLoading', true)
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/proxy/start`,
|
||||
url:`./api/proxy/start`,
|
||||
params: {
|
||||
app: row.app,
|
||||
stream: row.stream
|
||||
|
@ -295,7 +295,7 @@
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/proxy/stop`,
|
||||
url:`./api/proxy/stop`,
|
||||
params: {
|
||||
app: row.app,
|
||||
stream: row.stream
|
||||
|
|
|
@ -99,7 +99,7 @@ export default {
|
|||
this.getUserListLoading = true;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/user/users`,
|
||||
url: `./api/user/users`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count
|
||||
|
@ -141,7 +141,7 @@ export default {
|
|||
}).then(() => {
|
||||
this.$axios({
|
||||
method: 'delete',
|
||||
url: `/api/user/delete?id=${row.id}`
|
||||
url: `./api/user/delete?id=${row.id}`
|
||||
}).then((res) => {
|
||||
this.getUserList();
|
||||
}).catch((error) => {
|
||||
|
|
|
@ -206,7 +206,7 @@ export default {
|
|||
if (typeof (this.$route.params.deviceId) == "undefined") return;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`,
|
||||
url: `./api/device/query/devices/${this.$route.params.deviceId}/channels`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count,
|
||||
|
@ -238,7 +238,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/play/start/' + deviceId + '/' + channelId
|
||||
url: './api/play/start/' + deviceId + '/' + channelId
|
||||
}).then(function (res) {
|
||||
console.log(res)
|
||||
that.isLoging = false;
|
||||
|
@ -278,7 +278,7 @@ export default {
|
|||
var that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId
|
||||
url: './api/play/stop/' + this.deviceId + "/" + itemData.channelId
|
||||
}).then(function (res) {
|
||||
that.initData();
|
||||
}).catch(function (error) {
|
||||
|
@ -334,7 +334,7 @@ export default {
|
|||
if (!this.showTree) {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`,
|
||||
url: `./api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`,
|
||||
params: {
|
||||
page: this.currentPage,
|
||||
count: this.count,
|
||||
|
@ -358,7 +358,7 @@ export default {
|
|||
}else {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/tree/channel/${this.deviceId}`,
|
||||
url: `./api/device/query/tree/channel/${this.deviceId}`,
|
||||
params: {
|
||||
parentId: this.parentChannelId,
|
||||
page: this.currentPage,
|
||||
|
@ -387,7 +387,7 @@ export default {
|
|||
updateChannel: function (row) {
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url: `/api/device/query/channel/update/${this.deviceId}`,
|
||||
url: `./api/device/query/channel/update/${this.deviceId}`,
|
||||
params: row
|
||||
}).then(function (res) {
|
||||
console.log(JSON.stringify(res));
|
||||
|
|
|
@ -114,7 +114,7 @@ export default {
|
|||
getSystemInfo: function (){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/server/system/info`,
|
||||
url: `./api/server/system/info`,
|
||||
}).then( (res)=> {
|
||||
if (res.data.code === 0) {
|
||||
this.$refs.consoleCPU.setData(res.data.data.cpu)
|
||||
|
@ -128,7 +128,7 @@ export default {
|
|||
getLoad: function (){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/server/media_server/load`,
|
||||
url: `./api/server/media_server/load`,
|
||||
}).then( (res)=> {
|
||||
if (res.data.code === 0) {
|
||||
this.$refs.consoleNodeLoad.setData(res.data.data)
|
||||
|
@ -139,7 +139,7 @@ export default {
|
|||
getResourceInfo: function (){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/server/resource/info`,
|
||||
url: `./api/server/resource/info`,
|
||||
}).then( (res)=> {
|
||||
if (res.data.code === 0) {
|
||||
this.$refs.consoleResource.setData(res.data.data)
|
||||
|
@ -151,7 +151,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/server/system/configInfo`,
|
||||
url: `./api/server/system/configInfo`,
|
||||
}).then( (res)=> {
|
||||
console.log(res)
|
||||
if (res.data.code === 0) {
|
||||
|
|
|
@ -335,7 +335,7 @@ export default {
|
|||
var that = this;
|
||||
await that.$axios({
|
||||
method: 'get',
|
||||
url:`/api/platform/exit/${deviceGbId}`
|
||||
url:`./api/platform/exit/${deviceGbId}`
|
||||
}).then(function (res) {
|
||||
result = res.data;
|
||||
}).catch(function (error) {
|
||||
|
|
|
@ -195,7 +195,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/platform/query/10000/1`
|
||||
url:`./api/platform/query/10000/1`
|
||||
}).then(function (res) {
|
||||
that.platformList = res.data.data.list;
|
||||
}).catch(function (error) {
|
||||
|
@ -212,7 +212,7 @@ export default {
|
|||
if (that.proxyParam.mediaServerId !== "auto"){
|
||||
that.$axios({
|
||||
method: 'get',
|
||||
url:`/api/proxy/ffmpeg_cmd/list`,
|
||||
url:`./api/proxy/ffmpeg_cmd/list`,
|
||||
params: {
|
||||
mediaServerId: that.proxyParam.mediaServerId
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ export default {
|
|||
this.noneReaderHandler();
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:`/api/proxy/save`,
|
||||
url:`./api/proxy/save`,
|
||||
data: this.proxyParam
|
||||
}).then((res)=> {
|
||||
this.dialogLoading = false;
|
||||
|
@ -261,7 +261,7 @@ export default {
|
|||
var that = this;
|
||||
await that.$axios({
|
||||
method: 'get',
|
||||
url:`/api/platform/exit/${deviceGbId}`
|
||||
url:`./api/platform/exit/${deviceGbId}`
|
||||
}).then(function (res) {
|
||||
result = res.data;
|
||||
}).catch(function (error) {
|
||||
|
|
|
@ -55,7 +55,7 @@ export default {
|
|||
getProgress(){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/device/query/${this.deviceId}/sync_status/`,
|
||||
url:`./api/device/query/${this.deviceId}/sync_status/`,
|
||||
}).then((res) => {
|
||||
if (res.data.code === 0) {
|
||||
if (!this.syncFlag) {
|
||||
|
|
|
@ -100,7 +100,7 @@ export default {
|
|||
onSubmit: function () {
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url: "/api/user/add",
|
||||
url: "./api/user/add",
|
||||
params: {
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
|
@ -139,7 +139,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: "/api/role/all"
|
||||
url: "./api/role/all"
|
||||
}).then((res) => {
|
||||
this.loading = true;
|
||||
if (res.data.code === 0) {
|
||||
|
|
|
@ -116,7 +116,7 @@ export default {
|
|||
console.log(this.form);
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
|
||||
url:`./api/platform/catalog/${!this.isEdit? "add":"edit"}`,
|
||||
data: this.form
|
||||
}).then((res)=> {
|
||||
if (res.data.code === 0) {
|
||||
|
|
|
@ -90,7 +90,7 @@ export default {
|
|||
onSubmit: function () {
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:"/api/user/changePassword",
|
||||
url:"./api/user/changePassword",
|
||||
params: {
|
||||
oldPassword: crypto.createHash('md5').update(this.oldPassword, "utf8").digest('hex'),
|
||||
password: this.newPassword
|
||||
|
|
|
@ -85,7 +85,7 @@ export default {
|
|||
onSubmit: function () {
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:"/api/user/changePasswordForAdmin",
|
||||
url:"./api/user/changePasswordForAdmin",
|
||||
params: {
|
||||
password: this.newPassword,
|
||||
userId: this.form.id,
|
||||
|
|
|
@ -65,7 +65,7 @@ export default {
|
|||
onSubmit: function () {
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:"/api/user/changePushKey",
|
||||
url:"./api/user/changePushKey",
|
||||
params: {
|
||||
pushKey: this.newPushKey,
|
||||
userId: this.form.id,
|
||||
|
|
|
@ -44,7 +44,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/play/start/' + deviceId + '/' + channelId
|
||||
url: './api/play/start/' + deviceId + '/' + channelId
|
||||
}).then(function (res) {
|
||||
that.isLoging = false;
|
||||
if (res.data.code === 0) {
|
||||
|
|
|
@ -98,7 +98,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:"/api/platform/update_channel_for_gb",
|
||||
url:"./api/platform/update_channel_for_gb",
|
||||
data:{
|
||||
platformId: that.platformId,
|
||||
channelReduces: that.chooseData
|
||||
|
|
|
@ -82,7 +82,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method:"get",
|
||||
url:`/api/platform/catalog`,
|
||||
url:`./api/platform/catalog`,
|
||||
params: {
|
||||
platformId: that.platformId,
|
||||
parentId: parentId
|
||||
|
@ -134,7 +134,7 @@ export default {
|
|||
removeCatalog: function (id, node){
|
||||
this.$axios({
|
||||
method:"delete",
|
||||
url:`/api/platform/catalog/del`,
|
||||
url:`./api/platform/catalog/del`,
|
||||
params: {
|
||||
id: id,
|
||||
platformId: this.platformId,
|
||||
|
@ -156,7 +156,7 @@ export default {
|
|||
setDefaultCatalog: function (id){
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:`/api/platform/catalog/default/update`,
|
||||
url:`./api/platform/catalog/default/update`,
|
||||
params: {
|
||||
platformId: this.platformId,
|
||||
catalogId: id,
|
||||
|
@ -201,7 +201,7 @@ export default {
|
|||
onClick: () => {
|
||||
this.$axios({
|
||||
method:"delete",
|
||||
url:"/api/platform/catalog/relation/del",
|
||||
url:"./api/platform/catalog/relation/del",
|
||||
data: data
|
||||
}).then((res)=>{
|
||||
console.log("移除成功")
|
||||
|
|
|
@ -121,7 +121,7 @@ export default {
|
|||
this.getCatalogFromUser((catalogId)=> {
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:"/api/platform/update_channel_for_gb",
|
||||
url:"./api/platform/update_channel_for_gb",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
all: all,
|
||||
|
@ -149,7 +149,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method:"delete",
|
||||
url:"/api/platform/del_channel_for_gb",
|
||||
url:"./api/platform/del_channel_for_gb",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
all: all,
|
||||
|
@ -248,7 +248,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method:"get",
|
||||
url:`/api/platform/channel_list`,
|
||||
url:`./api/platform/channel_list`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count,
|
||||
|
@ -290,7 +290,7 @@ export default {
|
|||
}).then(() => {
|
||||
this.$axios({
|
||||
method:"delete",
|
||||
url:"/api/platform/del_channel_for_gb",
|
||||
url:"./api/platform/del_channel_for_gb",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
channelReduces: this.multipleSelection
|
||||
|
@ -310,7 +310,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method: "post",
|
||||
url: "/api/platform/update_channel_for_gb",
|
||||
url: "./api/platform/update_channel_for_gb",
|
||||
data: {
|
||||
platformId: this.platformId,
|
||||
channelReduces: this.multipleSelection,
|
||||
|
|
|
@ -134,7 +134,7 @@ export default {
|
|||
this.getCatalogFromUser((catalogId)=>{
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:"/api/gbStream/add",
|
||||
url:"./api/gbStream/add",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
catalogId: catalogId,
|
||||
|
@ -163,7 +163,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method:"delete",
|
||||
url:"/api/gbStream/del",
|
||||
url:"./api/gbStream/del",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
all: all,
|
||||
|
@ -186,7 +186,7 @@ export default {
|
|||
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/gbStream/list`,
|
||||
url:`./api/gbStream/list`,
|
||||
params: {
|
||||
page: that.currentPage,
|
||||
count: that.count,
|
||||
|
@ -222,7 +222,7 @@ export default {
|
|||
}).then(() => {
|
||||
this.$axios({
|
||||
method:"delete",
|
||||
url:"/api/gbStream/del",
|
||||
url:"./api/gbStream/del",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
gbStreams: this.multipleSelection,
|
||||
|
@ -242,7 +242,7 @@ export default {
|
|||
this.getCatalogFromUser((catalogId)=>{
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:"/api/gbStream/add",
|
||||
url:"./api/gbStream/add",
|
||||
data:{
|
||||
platformId: this.platformId,
|
||||
catalogId: catalogId,
|
||||
|
|
|
@ -134,7 +134,7 @@ export default {
|
|||
this.form.mobilePositionSubmissionInterval = this.form.mobilePositionSubmissionInterval||0
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:`/api/device/query/device/${this.isEdit?'update':'add'}/`,
|
||||
url:`./api/device/query/device/${this.isEdit?'update':'add'}/`,
|
||||
params: this.form
|
||||
}).then((res) => {
|
||||
console.log(res.data)
|
||||
|
|
|
@ -89,7 +89,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method:"get",
|
||||
url:`/api/platform/catalog`,
|
||||
url:`./api/platform/catalog`,
|
||||
params: {
|
||||
platformId: that.platformId,
|
||||
parentId: parentId
|
||||
|
@ -111,7 +111,7 @@ export default {
|
|||
if (node.level === 0) {
|
||||
this.$axios({
|
||||
method:"get",
|
||||
url:`/api/platform/info/` + this.platformId,
|
||||
url:`./api/platform/info/` + this.platformId,
|
||||
})
|
||||
.then((res)=> {
|
||||
if (res.data.code === 0) {
|
||||
|
|
|
@ -60,7 +60,7 @@ export default {
|
|||
console.log(this.form);
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:`/api/platform/catalog/${!this.isEdit? "add":"edit"}`,
|
||||
url:`./api/platform/catalog/${!this.isEdit? "add":"edit"}`,
|
||||
data: this.form
|
||||
})
|
||||
.then((res)=> {
|
||||
|
|
|
@ -81,7 +81,7 @@ export default {
|
|||
console.log(this.form);
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`api/onvif/rtsp`,
|
||||
url:`./api/onvif/rtsp`,
|
||||
params: {
|
||||
hostname: this.form.hostName,
|
||||
timeout: 3000,
|
||||
|
|
|
@ -138,7 +138,7 @@ export default {
|
|||
showDialog: false,
|
||||
isLoging: false,
|
||||
onSubmit_text: "立即创建",
|
||||
saveUrl: "/api/platform/save",
|
||||
saveUrl: "./api/platform/save",
|
||||
|
||||
platform: {
|
||||
id: null,
|
||||
|
@ -192,7 +192,7 @@ export default {
|
|||
this.saveUrl = "/api/platform/add";
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/platform/server_config`
|
||||
url:`./api/platform/server_config`
|
||||
}).then(function (res) {
|
||||
console.log(res);
|
||||
if (res.data.code === 0) {
|
||||
|
@ -315,7 +315,7 @@ export default {
|
|||
var that = this;
|
||||
await that.$axios({
|
||||
method: 'get',
|
||||
url:`/api/platform/exit/${deviceGbId}`})
|
||||
url:`./api/platform/exit/${deviceGbId}`})
|
||||
.then(function (res) {
|
||||
if (res.data.code === 0) {
|
||||
result = res.data.data;
|
||||
|
|
|
@ -109,7 +109,7 @@ export default {
|
|||
if (this.edit) {
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:`/api/push/save_to_gb`,
|
||||
url:`./api/push/save_to_gb`,
|
||||
data: this.proxyParam
|
||||
}).then( (res) => {
|
||||
if (res.data.code === 0) {
|
||||
|
@ -129,7 +129,7 @@ export default {
|
|||
}else {
|
||||
this.$axios({
|
||||
method:"post",
|
||||
url:`/api/push/add`,
|
||||
url:`./api/push/add`,
|
||||
data: this.proxyParam
|
||||
}).then( (res) => {
|
||||
if (res.data.code === 0) {
|
||||
|
@ -159,7 +159,7 @@ export default {
|
|||
var that = this;
|
||||
await that.$axios({
|
||||
method:"get",
|
||||
url:`/api/platform/exit/${deviceGbId}`
|
||||
url:`./api/platform/exit/${deviceGbId}`
|
||||
}).then(function (res) {
|
||||
result = res.data;
|
||||
}).catch(function (error) {
|
||||
|
|
|
@ -72,7 +72,7 @@ export default {
|
|||
onSubmit: function () {
|
||||
console.log("onSubmit");
|
||||
this.isLoging = true;
|
||||
let url = `/api/position/history/${this.channel.deviceId}?start=${this.searchFrom}&end=${this.searchTo}`;
|
||||
let url = `./api/position/history/${this.channel.deviceId}?start=${this.searchFrom}&end=${this.searchTo}`;
|
||||
if (this.channel.channelId) {
|
||||
url+="&channelId=${this.channel.channelId}"
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ export default {
|
|||
getProgress: function (callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}`
|
||||
url: `./api/gb_record/download/progress/${this.deviceId}/${this.channelId}/${this.stream}`
|
||||
}).then((res)=> {
|
||||
console.log(res)
|
||||
if (res.data.code === 0) {
|
||||
|
@ -124,7 +124,7 @@ export default {
|
|||
stopDownloadRecord: function (callback) {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.stream
|
||||
url: './api/gb_record/download/stop/' + this.deviceId + "/" + this.channelId+ "/" + this.stream
|
||||
}).then((res)=> {
|
||||
if (callback) callback(res)
|
||||
});
|
||||
|
@ -132,7 +132,7 @@ export default {
|
|||
getFileDownload: function (){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/add`,
|
||||
url:`./record_proxy/${this.mediaServerId}/api/record/file/download/task/add`,
|
||||
params: {
|
||||
app: this.app,
|
||||
stream: this.stream,
|
||||
|
@ -164,7 +164,7 @@ export default {
|
|||
getProgressForFile: function (callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/list`,
|
||||
url:`./record_proxy/${this.mediaServerId}/api/record/file/download/task/list`,
|
||||
params: {
|
||||
app: this.app,
|
||||
stream: this.stream,
|
||||
|
|
|
@ -135,7 +135,7 @@ export default {
|
|||
this.loading = true
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/play/start/' + deviceId + '/' + channelId
|
||||
url: './api/play/start/' + deviceId + '/' + channelId
|
||||
}).then(function (res) {
|
||||
if (res.data.code === 0 && res.data.data) {
|
||||
let videoUrl;
|
||||
|
|
|
@ -298,7 +298,7 @@ export default {
|
|||
let that = this;
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: '/api/play/start/' + deviceId + '/' + channelId
|
||||
url: './api/play/start/' + deviceId + '/' + channelId
|
||||
}).then(function (res) {
|
||||
that.isLoging = false;
|
||||
if (res.data.code === 0) {
|
||||
|
|
|
@ -9,7 +9,7 @@ class DeviceService{
|
|||
getDeviceList(currentPage, count, callback, errorCallback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/device/query/devices`,
|
||||
url:`./api/device/query/devices`,
|
||||
params: {
|
||||
page: currentPage,
|
||||
count: count
|
||||
|
@ -25,7 +25,7 @@ class DeviceService{
|
|||
getDevice(deviceId, callback, errorCallback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/device/query/devices/${deviceId}`,
|
||||
url:`./api/device/query/devices/${deviceId}`,
|
||||
}).then((res) => {
|
||||
if (typeof (callback) == "function") callback(res.data)
|
||||
}).catch((error) => {
|
||||
|
@ -82,7 +82,7 @@ class DeviceService{
|
|||
getChanel(isCatalog, catalogUnderDevice, deviceId, currentPage, count, callback, errorCallback) {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/devices/${deviceId}/channels`,
|
||||
url: `./api/device/query/devices/${deviceId}/channels`,
|
||||
params:{
|
||||
page: currentPage,
|
||||
count: count,
|
||||
|
@ -121,7 +121,7 @@ class DeviceService{
|
|||
getSubChannel(isCatalog, deviceId, channelId, currentPage, count, callback, errorCallback) {
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/sub_channels/${deviceId}/${channelId}/channels`,
|
||||
url: `./api/device/query/sub_channels/${deviceId}/${channelId}/channels`,
|
||||
params:{
|
||||
page: currentPage,
|
||||
count: count,
|
||||
|
@ -161,7 +161,7 @@ class DeviceService{
|
|||
}
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url: `/api/device/query/tree/${deviceId}`,
|
||||
url: `./api/device/query/tree/${deviceId}`,
|
||||
params:{
|
||||
page: currentPage,
|
||||
count: count,
|
||||
|
|
|
@ -9,7 +9,7 @@ class MediaServer{
|
|||
getOnlineMediaServerList(callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/server/media_server/online/list`,
|
||||
url:`./api/server/media_server/online/list`,
|
||||
}).then((res) => {
|
||||
if (typeof (callback) == "function") callback(res.data)
|
||||
}).catch((error) => {
|
||||
|
@ -19,7 +19,7 @@ class MediaServer{
|
|||
getMediaServerList(callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/server/media_server/list`,
|
||||
url:`./api/server/media_server/list`,
|
||||
}).then(function (res) {
|
||||
if (typeof (callback) == "function") callback(res.data)
|
||||
}).catch(function (error) {
|
||||
|
@ -30,7 +30,7 @@ class MediaServer{
|
|||
getMediaServer(id, callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/server/media_server/one/` + id,
|
||||
url:`./api/server/media_server/one/` + id,
|
||||
}).then(function (res) {
|
||||
if (typeof (callback) == "function") callback(res.data)
|
||||
}).catch(function (error) {
|
||||
|
@ -41,7 +41,7 @@ class MediaServer{
|
|||
checkServer(param, callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/server/media_server/check`,
|
||||
url:`./api/server/media_server/check`,
|
||||
params: {
|
||||
ip: param.ip,
|
||||
port: param.httpPort,
|
||||
|
@ -57,7 +57,7 @@ class MediaServer{
|
|||
checkRecordServer(param, callback){
|
||||
this.$axios({
|
||||
method: 'get',
|
||||
url:`/api/server/media_server/record/check`,
|
||||
url:`./api/server/media_server/record/check`,
|
||||
params: {
|
||||
ip: param.ip,
|
||||
port: param.recordAssistPort
|
||||
|
@ -72,7 +72,7 @@ class MediaServer{
|
|||
addServer(param, callback){
|
||||
this.$axios({
|
||||
method: 'post',
|
||||
url:`/api/server/media_server/save`,
|
||||
url:`./api/server/media_server/save`,
|
||||
data: param
|
||||
}).then(function (res) {
|
||||
if (typeof (callback) == "function") callback(res.data)
|
||||
|
@ -84,7 +84,7 @@ class MediaServer{
|
|||
delete(id, callback) {
|
||||
this.$axios({
|
||||
method: 'delete',
|
||||
url:`/api/server/media_server/delete`,
|
||||
url:`./api/server/media_server/delete`,
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue