Merge remote-tracking branch 'github/wvp-28181-2.0' into wvp-28181-2.0
# Conflicts: # pom.xml # src/main/java/com/genersoft/iot/vmp/gb28181/event/record/RecordEndEventListener.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/query/cmd/RecordInfoQueryMessageHandler.java # src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
This commit is contained in:
commit
01622884a9
BIN
libs/jdbc-x86/bcprov-jdk15on-1.70.jar
Normal file
BIN
libs/jdbc-x86/bcprov-jdk15on-1.70.jar
Normal file
Binary file not shown.
BIN
libs/jdbc-x86/kingbase8-8.6.0.jar
Normal file
BIN
libs/jdbc-x86/kingbase8-8.6.0.jar
Normal file
Binary file not shown.
BIN
libs/jdbc-x86/kingbase8-8.6.0.jre6.jar
Normal file
BIN
libs/jdbc-x86/kingbase8-8.6.0.jre6.jar
Normal file
Binary file not shown.
BIN
libs/jdbc-x86/kingbase8-8.6.0.jre7.jar
Normal file
BIN
libs/jdbc-x86/kingbase8-8.6.0.jre7.jar
Normal file
Binary file not shown.
BIN
libs/jdbc-x86/postgresql-42.2.9.jar
Normal file
BIN
libs/jdbc-x86/postgresql-42.2.9.jar
Normal file
Binary file not shown.
BIN
libs/jdbc-x86/postgresql-42.2.9.jre6.jar
Normal file
BIN
libs/jdbc-x86/postgresql-42.2.9.jre6.jar
Normal file
Binary file not shown.
BIN
libs/jdbc-x86/postgresql-42.2.9.jre7.jar
Normal file
BIN
libs/jdbc-x86/postgresql-42.2.9.jre7.jar
Normal file
Binary file not shown.
30
pom.xml
30
pom.xml
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<groupId>com.genersoft</groupId>
|
<groupId>com.genersoft</groupId>
|
||||||
<artifactId>wvp-pro</artifactId>
|
<artifactId>wvp-pro</artifactId>
|
||||||
<version>2.6.9</version>
|
<version>2.7.0</version>
|
||||||
<name>web video platform</name>
|
<name>web video platform</name>
|
||||||
<description>国标28181视频平台</description>
|
<description>国标28181视频平台</description>
|
||||||
<packaging>${project.packaging}</packaging>
|
<packaging>${project.packaging}</packaging>
|
||||||
@ -50,15 +50,15 @@
|
|||||||
<maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format>
|
<maven.build.timestamp.format>MMddHHmm</maven.build.timestamp.format>
|
||||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
||||||
|
|
||||||
<!-- 依赖版本 -->
|
<!-- 依赖版本 -->
|
||||||
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
|
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
|
||||||
<asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory>
|
<asciidoctor.input.directory>${project.basedir}/docs/asciidoc</asciidoctor.input.directory>
|
||||||
<generated.asciidoc.directory>${project.build.directory}/asciidoc</generated.asciidoc.directory>
|
<generated.asciidoc.directory>${project.build.directory}/asciidoc</generated.asciidoc.directory>
|
||||||
<asciidoctor.html.output.directory>${project.build.directory}/asciidoc/html</asciidoctor.html.output.directory>
|
<asciidoctor.html.output.directory>${project.build.directory}/asciidoc/html</asciidoctor.html.output.directory>
|
||||||
<asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory>
|
<asciidoctor.pdf.output.directory>${project.build.directory}/asciidoc/pdf</asciidoctor.pdf.output.directory>
|
||||||
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
|
<org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
|
||||||
<springboot.version>2.7.2</springboot.version>
|
<springboot.version>2.7.2</springboot.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
@ -178,6 +178,20 @@
|
|||||||
<artifactId>springdoc-openapi-security</artifactId>
|
<artifactId>springdoc-openapi-security</artifactId>
|
||||||
<version>1.6.10</version>
|
<version>1.6.10</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||||
|
<version>3.6.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!--在线文档 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-ui</artifactId>
|
||||||
|
<version>1.6.10</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
alter table wvp_device_channel
|
|
||||||
change stream_id stream_id varying(255)
|
|
||||||
|
|
||||||
alter table wvp_platform
|
|
||||||
add auto_push_channel bool default false
|
|
||||||
|
|
||||||
alter table wvp_stream_proxy
|
|
||||||
add stream_key character varying(255)
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.common;
|
package com.genersoft.iot.vmp.common;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -76,6 +77,8 @@ public class StreamInfo implements Serializable, Cloneable{
|
|||||||
private String endTime;
|
private String endTime;
|
||||||
@Schema(description = "进度(录像下载使用)")
|
@Schema(description = "进度(录像下载使用)")
|
||||||
private double progress;
|
private double progress;
|
||||||
|
@Schema(description = "文件下载地址(录像下载使用)")
|
||||||
|
private DownloadFileInfo downLoadFilePath;
|
||||||
|
|
||||||
@Schema(description = "是否暂停(录像回放使用)")
|
@Schema(description = "是否暂停(录像回放使用)")
|
||||||
private boolean pause;
|
private boolean pause;
|
||||||
@ -605,5 +608,11 @@ public class StreamInfo implements Serializable, Cloneable{
|
|||||||
this.subStream = subStream;
|
this.subStream = subStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DownloadFileInfo getDownLoadFilePath() {
|
||||||
|
return downLoadFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) {
|
||||||
|
this.downLoadFilePath = downLoadFilePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ public class VideoManagerConstants {
|
|||||||
|
|
||||||
public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_MEDIA_TRANSACTION_";
|
public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_MEDIA_TRANSACTION_";
|
||||||
|
|
||||||
public static final String MEDIA_STREAM_AUTHORITY = "MEDIA_STREAM_AUTHORITY_";
|
public static final String MEDIA_STREAM_AUTHORITY = "VMP_MEDIA_STREAM_AUTHORITY_";
|
||||||
|
|
||||||
public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";
|
public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";
|
||||||
|
|
||||||
@ -70,6 +70,7 @@ public class VideoManagerConstants {
|
|||||||
public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
|
public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
|
||||||
|
|
||||||
public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_";
|
public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_";
|
||||||
|
public static final String PUSH_STREAM_LIST = "VMP_PUSH_STREAM_LIST_";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.genersoft.iot.vmp.conf;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.CloudRecordItem;
|
||||||
|
import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.cloudRecord.CloudRecordController;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 录像文件定时删除
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CloudRecordTimer {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(CloudRecordTimer.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CloudRecordServiceMapper cloudRecordServiceMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时查询待删除的录像文件
|
||||||
|
*/
|
||||||
|
// @Scheduled(fixedRate = 10000) //每五秒执行一次,方便测试
|
||||||
|
@Scheduled(cron = "0 0 0 * * ?") //每天的0点执行
|
||||||
|
public void execute(){
|
||||||
|
logger.info("[录像文件定时清理] 开始清理过期录像文件");
|
||||||
|
// 获取配置了assist的流媒体节点
|
||||||
|
List<MediaServerItem> mediaServerItemList = mediaServerService.getAllOnline();
|
||||||
|
if (mediaServerItemList.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long result = 0;
|
||||||
|
for (MediaServerItem mediaServerItem : mediaServerItemList) {
|
||||||
|
|
||||||
|
Calendar lastCalendar = Calendar.getInstance();
|
||||||
|
if (mediaServerItem.getRecordDay() > 0) {
|
||||||
|
lastCalendar.setTime(new Date());
|
||||||
|
// 获取保存的最后截至日[期,因为每个节点都有一个日期,也就是支持每个节点设置不同的保存日期,
|
||||||
|
lastCalendar.add(Calendar.DAY_OF_MONTH, -mediaServerItem.getRecordDay());
|
||||||
|
Long lastDate = lastCalendar.getTimeInMillis();
|
||||||
|
|
||||||
|
// 获取到截至日期之前的录像文件列表,文件列表满足未被收藏和保持的。这两个字段目前共能一致,
|
||||||
|
// 为我自己业务系统相关的代码,大家使用的时候直接使用收藏(collect)这一个类型即可
|
||||||
|
List<CloudRecordItem> cloudRecordItemList = cloudRecordServiceMapper.queryRecordListForDelete(lastDate, mediaServerItem.getId());
|
||||||
|
if (cloudRecordItemList.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO 后续可以删除空了的过期日期文件夹
|
||||||
|
for (CloudRecordItem cloudRecordItem : cloudRecordItemList) {
|
||||||
|
String date = new File(cloudRecordItem.getFilePath()).getParentFile().getName();
|
||||||
|
JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServerItem, cloudRecordItem.getApp(),
|
||||||
|
cloudRecordItem.getStream(), date, cloudRecordItem.getFileName());
|
||||||
|
if (jsonObject.getInteger("code") != 0) {
|
||||||
|
logger.warn("[录像文件定时清理] 删除磁盘文件错误: {}:{}", cloudRecordItem.getFilePath(), jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result += cloudRecordServiceMapper.deleteList(cloudRecordItemList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("[录像文件定时清理] 共清理{}个过期录像文件", result);
|
||||||
|
}
|
||||||
|
}
|
@ -86,6 +86,12 @@ public class MediaConfig{
|
|||||||
@Value("${media.record-assist-port:0}")
|
@Value("${media.record-assist-port:0}")
|
||||||
private Integer recordAssistPort = 0;
|
private Integer recordAssistPort = 0;
|
||||||
|
|
||||||
|
@Value("${media.record-day:7}")
|
||||||
|
private Integer recordDay;
|
||||||
|
|
||||||
|
@Value("${media.record-path:}")
|
||||||
|
private String recordPath;
|
||||||
|
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -218,13 +224,32 @@ public class MediaConfig{
|
|||||||
mediaServerItem.setRecordAssistIp(recordAssistIp);
|
mediaServerItem.setRecordAssistIp(recordAssistIp);
|
||||||
mediaServerItem.setRecordAssistPort(recordAssistPort);
|
mediaServerItem.setRecordAssistPort(recordAssistPort);
|
||||||
mediaServerItem.setHookAliveInterval(30.00f);
|
mediaServerItem.setHookAliveInterval(30.00f);
|
||||||
|
mediaServerItem.setRecordDay(recordDay);
|
||||||
|
if (recordPath != null) {
|
||||||
|
mediaServerItem.setRecordPath(recordPath);
|
||||||
|
}
|
||||||
mediaServerItem.setCreateTime(DateUtil.getNow());
|
mediaServerItem.setCreateTime(DateUtil.getNow());
|
||||||
mediaServerItem.setUpdateTime(DateUtil.getNow());
|
mediaServerItem.setUpdateTime(DateUtil.getNow());
|
||||||
|
|
||||||
return mediaServerItem;
|
return mediaServerItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getRecordDay() {
|
||||||
|
return recordDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecordDay(Integer recordDay) {
|
||||||
|
this.recordDay = recordDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecordPath() {
|
||||||
|
return recordPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecordPath(String recordPath) {
|
||||||
|
this.recordPath = recordPath;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRtpSendPortRange() {
|
public String getRtpSendPortRange() {
|
||||||
return rtpSendPortRange;
|
return rtpSendPortRange;
|
||||||
}
|
}
|
||||||
|
@ -39,4 +39,6 @@ public class SystemInfoTimerTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ public class UserSetting {
|
|||||||
|
|
||||||
private Integer playTimeout = 18000;
|
private Integer playTimeout = 18000;
|
||||||
|
|
||||||
private int platformPlayTimeout = 60000;
|
private int platformPlayTimeout = 20000;
|
||||||
|
|
||||||
private Boolean interfaceAuthentication = Boolean.TRUE;
|
private Boolean interfaceAuthentication = Boolean.TRUE;
|
||||||
|
|
||||||
@ -61,8 +61,6 @@ public class UserSetting {
|
|||||||
|
|
||||||
private String serverId = "000000";
|
private String serverId = "000000";
|
||||||
|
|
||||||
private String recordPath = null;
|
|
||||||
|
|
||||||
private String thirdPartyGBIdReg = "[\\s\\S]*";
|
private String thirdPartyGBIdReg = "[\\s\\S]*";
|
||||||
|
|
||||||
private String civilCodeFile = "classpath:civilCode.csv";
|
private String civilCodeFile = "classpath:civilCode.csv";
|
||||||
@ -257,14 +255,6 @@ public class UserSetting {
|
|||||||
this.refuseChannelStatusChannelFormNotify = refuseChannelStatusChannelFormNotify;
|
this.refuseChannelStatusChannelFormNotify = refuseChannelStatusChannelFormNotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRecordPath() {
|
|
||||||
return recordPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRecordPath(String recordPath) {
|
|
||||||
this.recordPath = recordPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxNotifyCountQueue() {
|
public int getMaxNotifyCountQueue() {
|
||||||
return maxNotifyCountQueue;
|
return maxNotifyCountQueue;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class RecordEndEventListener implements ApplicationListener<RecordEndEven
|
|||||||
event.getRecordInfo().getDeviceId(),
|
event.getRecordInfo().getDeviceId(),
|
||||||
event.getRecordInfo().getChannelId(), count,sumNum);
|
event.getRecordInfo().getChannelId(), count,sumNum);
|
||||||
logger.debug("handlerMap.size => {}", handlerMap.size());
|
logger.debug("handlerMap.size => {}", handlerMap.size());
|
||||||
if (handlerMap.size() > 0) {
|
if (!handlerMap.isEmpty()) {
|
||||||
String key = deviceId + channelId + sn;
|
String key = deviceId + channelId + sn;
|
||||||
logger.debug("handlerMap.keys => {}", handlerMap.keySet());
|
logger.debug("handlerMap.keys => {}", handlerMap.keySet());
|
||||||
RecordEndEventHandler handler = handlerMap.get(deviceId + channelId + sn);
|
RecordEndEventHandler handler = handlerMap.get(deviceId + channelId + sn);
|
||||||
@ -63,6 +63,9 @@ public class RecordEndEventListener implements ApplicationListener<RecordEndEven
|
|||||||
scheduleMap.put(key,schedule);
|
scheduleMap.put(key,schedule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
logger.info("录像查询完成事件触发, 但是订阅为空,取消发送,deviceId:{}, channelId: {}",
|
||||||
|
event.getRecordInfo().getDeviceId(), event.getRecordInfo().getChannelId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,13 +148,13 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
|||||||
if (event.getDeviceChannels() != null) {
|
if (event.getDeviceChannels() != null) {
|
||||||
deviceChannelList.addAll(event.getDeviceChannels());
|
deviceChannelList.addAll(event.getDeviceChannels());
|
||||||
}
|
}
|
||||||
if (event.getGbStreams() != null && event.getGbStreams().size() > 0){
|
if (event.getGbStreams() != null && !event.getGbStreams().isEmpty()){
|
||||||
for (GbStream gbStream : event.getGbStreams()) {
|
for (GbStream gbStream : event.getGbStreams()) {
|
||||||
deviceChannelList.add(
|
deviceChannelList.add(
|
||||||
gbStreamService.getDeviceChannelListByStreamWithStatus(gbStream, gbStream.getCatalogId(), parentPlatform));
|
gbStreamService.getDeviceChannelListByStreamWithStatus(gbStream, gbStream.getCatalogId(), parentPlatform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deviceChannelList.size() > 0) {
|
if (!deviceChannelList.isEmpty()) {
|
||||||
logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
|
logger.info("[Catalog事件: {}]平台:{},影响通道{}个", event.getType(), event.getPlatformId(), deviceChannelList.size());
|
||||||
try {
|
try {
|
||||||
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
|
sipCommanderFroPlatform.sendNotifyForCatalogAddOrUpdate(event.getType(), parentPlatform, deviceChannelList, subscribe, null);
|
||||||
@ -163,10 +163,10 @@ public class CatalogEventLister implements ApplicationListener<CatalogEvent> {
|
|||||||
logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
|
logger.error("[命令发送失败] 国标级联 Catalog通知: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if (parentPlatformMap.keySet().size() > 0) {
|
}else if (!parentPlatformMap.keySet().isEmpty()) {
|
||||||
for (String gbId : parentPlatformMap.keySet()) {
|
for (String gbId : parentPlatformMap.keySet()) {
|
||||||
List<ParentPlatform> parentPlatforms = parentPlatformMap.get(gbId);
|
List<ParentPlatform> parentPlatforms = parentPlatformMap.get(gbId);
|
||||||
if (parentPlatforms != null && parentPlatforms.size() > 0) {
|
if (parentPlatforms != null && !parentPlatforms.isEmpty()) {
|
||||||
for (ParentPlatform platform : parentPlatforms) {
|
for (ParentPlatform platform : parentPlatforms) {
|
||||||
SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId());
|
SubscribeInfo subscribeInfo = subscribeHolder.getCatalogSubscribe(platform.getServerGBId());
|
||||||
if (subscribeInfo == null) {
|
if (subscribeInfo == null) {
|
||||||
|
@ -75,6 +75,33 @@ public class VideoStreamSessionManager {
|
|||||||
return (SsrcTransaction)redisTemplate.opsForValue().get(scanResult.get(0));
|
return (SsrcTransaction)redisTemplate.opsForValue().get(scanResult.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SsrcTransaction getSsrcTransactionByCallId(String callId){
|
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(callId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_*_*_" + callId+ "_*";
|
||||||
|
List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
|
||||||
|
if (!scanResult.isEmpty()) {
|
||||||
|
return (SsrcTransaction)redisTemplate.opsForValue().get(scanResult.get(0));
|
||||||
|
}else {
|
||||||
|
key = VideoManagerConstants.MEDIA_TRANSACTION_USED_PREFIX + userSetting.getServerId() + "_*_*_play_*";
|
||||||
|
scanResult = RedisUtil.scan(redisTemplate, key);
|
||||||
|
if (scanResult.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (Object keyObj : scanResult) {
|
||||||
|
SsrcTransaction ssrcTransaction = (SsrcTransaction)redisTemplate.opsForValue().get(keyObj);
|
||||||
|
if (ssrcTransaction.getSipTransactionInfo() != null &&
|
||||||
|
ssrcTransaction.getSipTransactionInfo().getCallId().equals(callId)) {
|
||||||
|
return ssrcTransaction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public List<SsrcTransaction> getSsrcTransactionForAll(String deviceId, String channelId, String callId, String stream){
|
public List<SsrcTransaction> getSsrcTransactionForAll(String deviceId, String channelId, String callId, String stream){
|
||||||
if (ObjectUtils.isEmpty(deviceId)) {
|
if (ObjectUtils.isEmpty(deviceId)) {
|
||||||
deviceId ="*";
|
deviceId ="*";
|
||||||
|
@ -129,4 +129,6 @@ public class SipRunner implements CommandLineRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,17 +66,17 @@ public class SIPSender {
|
|||||||
// 添加错误订阅
|
// 添加错误订阅
|
||||||
if (errorEvent != null) {
|
if (errorEvent != null) {
|
||||||
sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (eventResult -> {
|
sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (eventResult -> {
|
||||||
errorEvent.response(eventResult);
|
|
||||||
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
||||||
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
||||||
|
errorEvent.response(eventResult);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// 添加订阅
|
// 添加订阅
|
||||||
if (okEvent != null) {
|
if (okEvent != null) {
|
||||||
sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), eventResult -> {
|
sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), eventResult -> {
|
||||||
okEvent.response(eventResult);
|
|
||||||
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
sipSubscribe.removeOkSubscribe(eventResult.callId);
|
||||||
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
sipSubscribe.removeErrorSubscribe(eventResult.callId);
|
||||||
|
okEvent.response(eventResult);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ("TCP".equals(transport)) {
|
if ("TCP".equals(transport)) {
|
||||||
|
@ -557,7 +557,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException {
|
public void sendNotifyForCatalogAddOrUpdate(String type, ParentPlatform parentPlatform, List<DeviceChannel> deviceChannels, SubscribeInfo subscribeInfo, Integer index) throws InvalidArgumentException, ParseException, NoSuchFieldException, SipException, IllegalAccessException {
|
||||||
if (parentPlatform == null || deviceChannels == null || deviceChannels.size() == 0 || subscribeInfo == null) {
|
if (parentPlatform == null || deviceChannels == null || deviceChannels.isEmpty() || subscribeInfo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
@ -575,6 +575,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
Integer finalIndex = index;
|
Integer finalIndex = index;
|
||||||
String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channels,
|
String catalogXmlContent = getCatalogXmlContentForCatalogAddOrUpdate(parentPlatform, channels,
|
||||||
deviceChannels.size(), type, subscribeInfo);
|
deviceChannels.size(), type, subscribeInfo);
|
||||||
|
logger.info("[发送NOTIFY通知]类型: {},发送数量: {}", type, channels.size());
|
||||||
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
||||||
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
logger.error("发送NOTIFY通知消息失败。错误:{} {}", eventResult.statusCode, eventResult.msg);
|
||||||
}, (eventResult -> {
|
}, (eventResult -> {
|
||||||
@ -598,7 +599,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
|
|
||||||
SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
|
SIPRequest notifyRequest = headerProviderPlatformProvider.createNotifyRequest(parentPlatform, catalogXmlContent, subscribeInfo);
|
||||||
|
|
||||||
sipSender.transmitRequest(parentPlatform.getDeviceIp(), notifyRequest);
|
sipSender.transmitRequest(parentPlatform.getDeviceIp(), notifyRequest, errorEvent, okEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) {
|
private String getCatalogXmlContentForCatalogAddOrUpdate(ParentPlatform parentPlatform, List<DeviceChannel> channels, int sumNum, String type, SubscribeInfo subscribeInfo) {
|
||||||
@ -610,9 +611,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
.append("<CmdType>Catalog</CmdType>\r\n")
|
.append("<CmdType>Catalog</CmdType>\r\n")
|
||||||
.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n")
|
.append("<SN>" + (int) ((Math.random() * 9 + 1) * 100000) + "</SN>\r\n")
|
||||||
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n")
|
||||||
.append("<SumNum>1</SumNum>\r\n")
|
.append("<SumNum>"+ sumNum +"</SumNum>\r\n")
|
||||||
.append("<DeviceList Num=\"" + channels.size() + "\">\r\n");
|
.append("<DeviceList Num=\"" + channels.size() + "\">\r\n");
|
||||||
if (channels.size() > 0) {
|
if (!channels.isEmpty()) {
|
||||||
for (DeviceChannel channel : channels) {
|
for (DeviceChannel channel : channels) {
|
||||||
if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
|
if (parentPlatform.getServerGBId().equals(channel.getParentId())) {
|
||||||
channel.setParentId(parentPlatform.getDeviceGBId());
|
channel.setParentId(parentPlatform.getDeviceGBId());
|
||||||
@ -679,6 +680,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
}else {
|
}else {
|
||||||
channels = deviceChannels.subList(index, deviceChannels.size());
|
channels = deviceChannels.subList(index, deviceChannels.size());
|
||||||
}
|
}
|
||||||
|
logger.info("[发送NOTIFY通知]类型: {},发送数量: {}", type, channels.size());
|
||||||
Integer finalIndex = index;
|
Integer finalIndex = index;
|
||||||
String catalogXmlContent = getCatalogXmlContentForCatalogOther(parentPlatform, channels, type);
|
String catalogXmlContent = getCatalogXmlContentForCatalogOther(parentPlatform, channels, type);
|
||||||
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
sendNotify(parentPlatform, catalogXmlContent, subscribeInfo, eventResult -> {
|
||||||
@ -725,13 +727,14 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
if ( parentPlatform ==null) {
|
if ( parentPlatform ==null) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
logger.info("[国标级联] 发送录像数据通道: {}", recordInfo.getChannelId());
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
StringBuffer recordXml = new StringBuffer(600);
|
StringBuffer recordXml = new StringBuffer(600);
|
||||||
recordXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
recordXml.append("<?xml version=\"1.0\" encoding=\"" + characterSet + "\"?>\r\n")
|
||||||
.append("<Response>\r\n")
|
.append("<Response>\r\n")
|
||||||
.append("<CmdType>RecordInfo</CmdType>\r\n")
|
.append("<CmdType>RecordInfo</CmdType>\r\n")
|
||||||
.append("<SN>" +recordInfo.getSn() + "</SN>\r\n")
|
.append("<SN>" +recordInfo.getSn() + "</SN>\r\n")
|
||||||
.append("<DeviceID>" + recordInfo.getChannelId() + "</DeviceID>\r\n")
|
.append("<DeviceID>" + deviceChannel.getChannelId() + "</DeviceID>\r\n")
|
||||||
.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
|
.append("<SumNum>" + recordInfo.getSumNum() + "</SumNum>\r\n");
|
||||||
if (recordInfo.getRecordList() == null ) {
|
if (recordInfo.getRecordList() == null ) {
|
||||||
recordXml.append("<RecordList Num=\"0\">\r\n");
|
recordXml.append("<RecordList Num=\"0\">\r\n");
|
||||||
@ -741,7 +744,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
for (RecordItem recordItem : recordInfo.getRecordList()) {
|
for (RecordItem recordItem : recordInfo.getRecordList()) {
|
||||||
recordXml.append("<Item>\r\n");
|
recordXml.append("<Item>\r\n");
|
||||||
if (deviceChannel != null) {
|
if (deviceChannel != null) {
|
||||||
recordXml.append("<DeviceID>" + recordItem.getDeviceId() + "</DeviceID>\r\n")
|
recordXml.append("<DeviceID>" + deviceChannel.getChannelId() + "</DeviceID>\r\n")
|
||||||
.append("<Name>" + recordItem.getName() + "</Name>\r\n")
|
.append("<Name>" + recordItem.getName() + "</Name>\r\n")
|
||||||
.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getStartTime()) + "</StartTime>\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("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(recordItem.getEndTime()) + "</EndTime>\r\n")
|
||||||
@ -761,12 +764,14 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
|||||||
|
|
||||||
recordXml.append("</RecordList>\r\n")
|
recordXml.append("</RecordList>\r\n")
|
||||||
.append("</Response>\r\n");
|
.append("</Response>\r\n");
|
||||||
|
logger.info("[国标级联] 发送录像数据通道:{}, 内容: {}", recordInfo.getChannelId(), recordXml);
|
||||||
// callid
|
// callid
|
||||||
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(parentPlatform.getDeviceIp(),parentPlatform.getTransport());
|
||||||
|
|
||||||
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
Request request = headerProviderPlatformProvider.createMessageRequest(parentPlatform, recordXml.toString(), fromTag, SipUtils.getNewViaTag(), callIdHeader);
|
||||||
sipSender.transmitRequest(parentPlatform.getDeviceIp(), request);
|
sipSender.transmitRequest(parentPlatform.getDeviceIp(), request, null, eventResult -> {
|
||||||
|
logger.info("[国标级联] 发送录像数据通道:{}, 发送成功", recordInfo.getChannelId());
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import javax.sip.header.CallIdHeader;
|
|||||||
import javax.sip.message.Response;
|
import javax.sip.message.Response;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,7 +150,7 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||||||
}else {
|
}else {
|
||||||
|
|
||||||
// 可能是设备发送的停止
|
// 可能是设备发送的停止
|
||||||
SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(null, null, callIdHeader.getCallId(), null);
|
SsrcTransaction ssrcTransaction = streamSession.getSsrcTransactionByCallId(callIdHeader.getCallId());
|
||||||
if (ssrcTransaction == null) {
|
if (ssrcTransaction == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
String requesterId = SipUtils.getUserIdFromFromHeader(request);
|
String requesterId = SipUtils.getUserIdFromFromHeader(request);
|
||||||
CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
|
CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
|
||||||
if (requesterId == null || channelId == null) {
|
if (requesterId == null || channelId == null) {
|
||||||
logger.info("无法从FromHeader的Address中获取到平台id,返回400");
|
logger.info("无法从请求中获取到平台id,返回400");
|
||||||
// 参数不全, 发400,请求错误
|
// 参数不全, 发400,请求错误
|
||||||
try {
|
try {
|
||||||
responseAck(request, Response.BAD_REQUEST);
|
responseAck(request, Response.BAD_REQUEST);
|
||||||
@ -155,6 +155,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info("[INVITE] requesterId: {}, callId: {}, 来自:{}:{}",
|
||||||
|
requesterId, callIdHeader.getCallId(), request.getRemoteAddress(), request.getRemotePort());
|
||||||
|
|
||||||
// 查询请求是否来自上级平台\设备
|
// 查询请求是否来自上级平台\设备
|
||||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
|
ParentPlatform platform = storager.queryParentPlatByServerGBId(requesterId);
|
||||||
@ -415,7 +417,16 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
// 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口
|
// 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口
|
||||||
localPort = new Random().nextInt(65535) + 1;
|
localPort = new Random().nextInt(65535) + 1;
|
||||||
}
|
}
|
||||||
content.append("m=video " + localPort + " RTP/AVP 96\r\n");
|
if (sendRtpItem.isTcp()) {
|
||||||
|
content.append("m=video " + localPort + " TCP/RTP/AVP 96\r\n");
|
||||||
|
if (!sendRtpItem.isTcpActive()) {
|
||||||
|
content.append("a=setup:active\r\n");
|
||||||
|
} else {
|
||||||
|
content.append("a=setup:passive\r\n");
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
content.append("m=video " + localPort + " RTP/AVP 96\r\n");
|
||||||
|
}
|
||||||
content.append("a=sendonly\r\n");
|
content.append("a=sendonly\r\n");
|
||||||
content.append("a=rtpmap:96 PS/90000\r\n");
|
content.append("a=rtpmap:96 PS/90000\r\n");
|
||||||
content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
|
content.append("y=" + sendRtpItem.getSsrc() + "\r\n");
|
||||||
@ -540,7 +551,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
sendRtpItem.setPlayType(InviteStreamType.PLAY);
|
||||||
|
String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
|
||||||
|
sendRtpItem.setStreamId(streamId);
|
||||||
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
||||||
SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> {
|
SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> {
|
||||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||||
hookEvent.run(code, msg, data);
|
hookEvent.run(code, msg, data);
|
||||||
@ -552,9 +566,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
errorEvent.run(code, msg, data);
|
errorEvent.run(code, msg, data);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
sendRtpItem.setPlayType(InviteStreamType.PLAY);
|
|
||||||
String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
|
|
||||||
sendRtpItem.setStreamId(streamId);
|
|
||||||
sendRtpItem.setSsrc(ssrcInfo.getSsrc());
|
sendRtpItem.setSsrc(ssrcInfo.getSsrc());
|
||||||
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
||||||
|
|
||||||
@ -736,9 +747,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
|
zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
|
||||||
dynamicTask.stop(callIdHeader.getCallId());
|
dynamicTask.stop(callIdHeader.getCallId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else if ("push".equals(gbStream.getStreamType())) {
|
} else if ("push".equals(gbStream.getStreamType())) {
|
||||||
if (!platform.isStartOfflinePush()) {
|
if (!platform.isStartOfflinePush()) {
|
||||||
// 平台设置中关闭了拉起离线的推流则直接回复
|
// 平台设置中关闭了拉起离线的推流则直接回复
|
||||||
@ -761,13 +769,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
|
dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
|
||||||
logger.info("[ app={}, stream={} ] 等待设备开始推流超时", gbStream.getApp(), gbStream.getStream());
|
logger.info("[ app={}, stream={} ] 等待设备开始推流超时", gbStream.getApp(), gbStream.getStream());
|
||||||
try {
|
try {
|
||||||
|
redisPushStreamResponseListener.removeEvent(gbStream.getApp(), gbStream.getStream());
|
||||||
mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
|
mediaListManager.removedChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream());
|
||||||
responseAck(request, Response.REQUEST_TIMEOUT); // 超时
|
responseAck(request, Response.REQUEST_TIMEOUT); // 超时
|
||||||
} catch (SipException e) {
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
logger.error("未处理的异常 ", e);
|
|
||||||
} catch (InvalidArgumentException e) {
|
|
||||||
logger.error("未处理的异常 ", e);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
logger.error("未处理的异常 ", e);
|
logger.error("未处理的异常 ", e);
|
||||||
}
|
}
|
||||||
}, userSetting.getPlatformPlayTimeout());
|
}, userSetting.getPlatformPlayTimeout());
|
||||||
@ -778,6 +783,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||||||
// 添加在本机上线的通知
|
// 添加在本机上线的通知
|
||||||
mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
|
mediaListManager.addChannelOnlineEventLister(gbStream.getApp(), gbStream.getStream(), (app, stream, serverId) -> {
|
||||||
dynamicTask.stop(callIdHeader.getCallId());
|
dynamicTask.stop(callIdHeader.getCallId());
|
||||||
|
redisPushStreamResponseListener.removeEvent(gbStream.getApp(), gbStream.getStream());
|
||||||
if (serverId.equals(userSetting.getServerId())) {
|
if (serverId.equals(userSetting.getServerId())) {
|
||||||
SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
|
SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
|
||||||
app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
|
app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
|
||||||
|
@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
|||||||
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||||
import com.genersoft.iot.vmp.service.IDeviceChannelService;
|
import com.genersoft.iot.vmp.service.IDeviceChannelService;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
import org.dom4j.Element;
|
import org.dom4j.Element;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -185,6 +186,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||||||
// 判断此通道是否存在
|
// 判断此通道是否存在
|
||||||
DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, channel.getChannelId());
|
DeviceChannel deviceChannel = deviceChannelService.getOne(deviceId, channel.getChannelId());
|
||||||
if (deviceChannel != null) {
|
if (deviceChannel != null) {
|
||||||
|
logger.info("[增加通道] 已存在,不发送通知只更新,设备: {}, 通道 {}", device.getDeviceId(), channel.getChannelId());
|
||||||
channel.setId(deviceChannel.getId());
|
channel.setId(deviceChannel.getId());
|
||||||
updateChannelMap.put(channel.getChannelId(), channel);
|
updateChannelMap.put(channel.getChannelId(), channel);
|
||||||
if (updateChannelMap.keySet().size() > 300) {
|
if (updateChannelMap.keySet().size() > 300) {
|
||||||
@ -222,6 +224,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||||||
DeviceChannel deviceChannelForUpdate = deviceChannelService.getOne(deviceId, channel.getChannelId());
|
DeviceChannel deviceChannelForUpdate = deviceChannelService.getOne(deviceId, channel.getChannelId());
|
||||||
if (deviceChannelForUpdate != null) {
|
if (deviceChannelForUpdate != null) {
|
||||||
channel.setId(deviceChannelForUpdate.getId());
|
channel.setId(deviceChannelForUpdate.getId());
|
||||||
|
channel.setUpdateTime(DateUtil.getNow());
|
||||||
updateChannelMap.put(channel.getChannelId(), channel);
|
updateChannelMap.put(channel.getChannelId(), channel);
|
||||||
if (updateChannelMap.keySet().size() > 300) {
|
if (updateChannelMap.keySet().size() > 300) {
|
||||||
executeSaveForUpdate();
|
executeSaveForUpdate();
|
||||||
@ -244,11 +247,11 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||||||
// 转发变化信息
|
// 转发变化信息
|
||||||
eventPublisher.catalogEventPublish(null, channel, event);
|
eventPublisher.catalogEventPublish(null, channel, event);
|
||||||
|
|
||||||
if (updateChannelMap.keySet().size() > 0
|
if (!updateChannelMap.keySet().isEmpty()
|
||||||
|| addChannelMap.keySet().size() > 0
|
|| !addChannelMap.keySet().isEmpty()
|
||||||
|| updateChannelOnlineList.size() > 0
|
|| !updateChannelOnlineList.isEmpty()
|
||||||
|| updateChannelOfflineList.size() > 0
|
|| !updateChannelOfflineList.isEmpty()
|
||||||
|| deleteChannelList.size() > 0) {
|
|| !deleteChannelList.isEmpty()) {
|
||||||
|
|
||||||
if (!dynamicTask.contains(talkKey)) {
|
if (!dynamicTask.contains(talkKey)) {
|
||||||
dynamicTask.startDelay(talkKey, this::executeSave, 1000);
|
dynamicTask.startDelay(talkKey, this::executeSave, 1000);
|
||||||
@ -262,16 +265,36 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void executeSave(){
|
private void executeSave(){
|
||||||
executeSaveForAdd();
|
try {
|
||||||
executeSaveForUpdate();
|
executeSaveForAdd();
|
||||||
executeSaveForDelete();
|
} catch (Exception e) {
|
||||||
executeSaveForOnline();
|
logger.error("[存储收到的增加通道] 异常: ", e );
|
||||||
executeSaveForOffline();
|
}
|
||||||
|
try {
|
||||||
|
executeSaveForUpdate();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[存储收到的更新通道] 异常: ", e );
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
executeSaveForDelete();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[存储收到的删除通道] 异常: ", e );
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
executeSaveForOnline();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[存储收到的通道上线] 异常: ", e );
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
executeSaveForOffline();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("[存储收到的通道离线] 异常: ", e );
|
||||||
|
}
|
||||||
dynamicTask.stop(talkKey);
|
dynamicTask.stop(talkKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeSaveForUpdate(){
|
private void executeSaveForUpdate(){
|
||||||
if (updateChannelMap.values().size() > 0) {
|
if (!updateChannelMap.values().isEmpty()) {
|
||||||
ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(updateChannelMap.values());
|
ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(updateChannelMap.values());
|
||||||
updateChannelMap.clear();
|
updateChannelMap.clear();
|
||||||
deviceChannelService.batchUpdateChannel(deviceChannels);
|
deviceChannelService.batchUpdateChannel(deviceChannels);
|
||||||
@ -280,7 +303,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void executeSaveForAdd(){
|
private void executeSaveForAdd(){
|
||||||
if (addChannelMap.values().size() > 0) {
|
if (!addChannelMap.values().isEmpty()) {
|
||||||
ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(addChannelMap.values());
|
ArrayList<DeviceChannel> deviceChannels = new ArrayList<>(addChannelMap.values());
|
||||||
addChannelMap.clear();
|
addChannelMap.clear();
|
||||||
deviceChannelService.batchAddChannel(deviceChannels);
|
deviceChannelService.batchAddChannel(deviceChannels);
|
||||||
@ -288,21 +311,21 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void executeSaveForDelete(){
|
private void executeSaveForDelete(){
|
||||||
if (deleteChannelList.size() > 0) {
|
if (!deleteChannelList.isEmpty()) {
|
||||||
deviceChannelService.deleteChannels(deleteChannelList);
|
deviceChannelService.deleteChannels(deleteChannelList);
|
||||||
deleteChannelList.clear();
|
deleteChannelList.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeSaveForOnline(){
|
private void executeSaveForOnline(){
|
||||||
if (updateChannelOnlineList.size() > 0) {
|
if (!updateChannelOnlineList.isEmpty()) {
|
||||||
deviceChannelService.channelsOnline(updateChannelOnlineList);
|
deviceChannelService.channelsOnline(updateChannelOnlineList);
|
||||||
updateChannelOnlineList.clear();
|
updateChannelOnlineList.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeSaveForOffline(){
|
private void executeSaveForOffline(){
|
||||||
if (updateChannelOfflineList.size() > 0) {
|
if (!updateChannelOfflineList.isEmpty()) {
|
||||||
deviceChannelService.channelsOffline(updateChannelOfflineList);
|
deviceChannelService.channelsOffline(updateChannelOfflineList);
|
||||||
updateChannelOfflineList.clear();
|
updateChannelOfflineList.clear();
|
||||||
}
|
}
|
||||||
|
@ -103,23 +103,27 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen
|
|||||||
String title = registerFlag ? "[注册请求]": "[注销请求]";
|
String title = registerFlag ? "[注册请求]": "[注销请求]";
|
||||||
logger.info(title + "设备:{}, 开始处理: {}", deviceId, requestAddress);
|
logger.info(title + "设备:{}, 开始处理: {}", deviceId, requestAddress);
|
||||||
if (device != null &&
|
if (device != null &&
|
||||||
device.getSipTransactionInfo() != null &&
|
device.getSipTransactionInfo() != null &&
|
||||||
request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) {
|
request.getCallIdHeader().getCallId().equals(device.getSipTransactionInfo().getCallId())) {
|
||||||
logger.info(title + "设备:{}, 注册续订: {}",device.getDeviceId(), device.getDeviceId());
|
logger.info(title + "设备:{}, 注册续订: {}",device.getDeviceId(), device.getDeviceId());
|
||||||
device.setExpires(request.getExpires().getExpires());
|
if (registerFlag) {
|
||||||
device.setIp(remoteAddressInfo.getIp());
|
device.setExpires(request.getExpires().getExpires());
|
||||||
device.setPort(remoteAddressInfo.getPort());
|
device.setIp(remoteAddressInfo.getIp());
|
||||||
device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
|
device.setPort(remoteAddressInfo.getPort());
|
||||||
device.setLocalIp(request.getLocalAddress().getHostAddress());
|
device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
|
||||||
Response registerOkResponse = getRegisterOkResponse(request);
|
device.setLocalIp(request.getLocalAddress().getHostAddress());
|
||||||
// 判断TCP还是UDP
|
Response registerOkResponse = getRegisterOkResponse(request);
|
||||||
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
// 判断TCP还是UDP
|
||||||
String transport = reqViaHeader.getTransport();
|
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
||||||
device.setTransport("TCP".equalsIgnoreCase(transport) ? "TCP" : "UDP");
|
String transport = reqViaHeader.getTransport();
|
||||||
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), registerOkResponse);
|
device.setTransport("TCP".equalsIgnoreCase(transport) ? "TCP" : "UDP");
|
||||||
device.setRegisterTime(DateUtil.getNow());
|
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), registerOkResponse);
|
||||||
SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)registerOkResponse);
|
device.setRegisterTime(DateUtil.getNow());
|
||||||
deviceService.online(device, sipTransactionInfo);
|
SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)registerOkResponse);
|
||||||
|
deviceService.online(device, sipTransactionInfo);
|
||||||
|
}else {
|
||||||
|
deviceService.offline(deviceId, "主动注销");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword();
|
String password = (device != null && !ObjectUtils.isEmpty(device.getPassword()))? device.getPassword() : sipConfig.getPassword();
|
||||||
|
@ -76,7 +76,7 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp
|
|||||||
|
|
||||||
RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress());
|
RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress());
|
||||||
if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort()) {
|
if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort()) {
|
||||||
logger.info("[心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort());
|
logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort());
|
||||||
device.setPort(remoteAddressInfo.getPort());
|
device.setPort(remoteAddressInfo.getPort());
|
||||||
device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
|
device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort())));
|
||||||
device.setIp(remoteAddressInfo.getIp());
|
device.setIp(remoteAddressInfo.getIp());
|
||||||
|
@ -2,19 +2,27 @@ package com.genersoft.iot.vmp.media.zlm;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import okhttp3.*;
|
import okhttp3.*;
|
||||||
import okhttp3.logging.HttpLoggingInterceptor;
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class AssistRESTfulUtils {
|
public class AssistRESTfulUtils {
|
||||||
@ -22,21 +30,41 @@ public class AssistRESTfulUtils {
|
|||||||
private final static Logger logger = LoggerFactory.getLogger(AssistRESTfulUtils.class);
|
private final static Logger logger = LoggerFactory.getLogger(AssistRESTfulUtils.class);
|
||||||
|
|
||||||
|
|
||||||
|
private OkHttpClient client;
|
||||||
|
|
||||||
|
|
||||||
public interface RequestCallback{
|
public interface RequestCallback{
|
||||||
void run(JSONObject response);
|
void run(JSONObject response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OkHttpClient getClient(){
|
private OkHttpClient getClient(){
|
||||||
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
|
return getClient(null);
|
||||||
if (logger.isDebugEnabled()) {
|
}
|
||||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
|
|
||||||
logger.debug("http请求参数:" + message);
|
private OkHttpClient getClient(Integer readTimeOut){
|
||||||
});
|
if (client == null) {
|
||||||
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
|
if (readTimeOut == null) {
|
||||||
// OkHttp進行添加攔截器loggingInterceptor
|
readTimeOut = 10;
|
||||||
httpClientBuilder.addInterceptor(logging);
|
}
|
||||||
|
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
|
||||||
|
// 设置连接超时时间
|
||||||
|
httpClientBuilder.connectTimeout(8, TimeUnit.SECONDS);
|
||||||
|
// 设置读取超时时间
|
||||||
|
httpClientBuilder.readTimeout(readTimeOut,TimeUnit.SECONDS);
|
||||||
|
// 设置连接池
|
||||||
|
httpClientBuilder.connectionPool(new ConnectionPool(16, 5, TimeUnit.MINUTES));
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {
|
||||||
|
logger.debug("http请求参数:" + message);
|
||||||
|
});
|
||||||
|
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
|
||||||
|
// OkHttp進行添加攔截器loggingInterceptor
|
||||||
|
httpClientBuilder.addInterceptor(logging);
|
||||||
|
}
|
||||||
|
client = httpClientBuilder.build();
|
||||||
}
|
}
|
||||||
return httpClientBuilder.build();
|
return client;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -50,11 +78,11 @@ public class AssistRESTfulUtils {
|
|||||||
logger.warn("未启用Assist服务");
|
logger.warn("未启用Assist服务");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StringBuffer stringBuffer = new StringBuffer();
|
StringBuilder stringBuffer = new StringBuilder();
|
||||||
stringBuffer.append(String.format("http://%s:%s/%s", mediaServerItem.getIp(), mediaServerItem.getRecordAssistPort(), api));
|
stringBuffer.append(api);
|
||||||
JSONObject responseJSON = null;
|
JSONObject responseJSON = null;
|
||||||
|
|
||||||
if (param != null && param.keySet().size() > 0) {
|
if (param != null && !param.keySet().isEmpty()) {
|
||||||
stringBuffer.append("?");
|
stringBuffer.append("?");
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (String key : param.keySet()){
|
for (String key : param.keySet()){
|
||||||
@ -69,6 +97,7 @@ public class AssistRESTfulUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String url = stringBuffer.toString();
|
String url = stringBuffer.toString();
|
||||||
|
logger.info("[访问assist]: {}", url);
|
||||||
Request request = new Request.Builder()
|
Request request = new Request.Builder()
|
||||||
.get()
|
.get()
|
||||||
.url(url)
|
.url(url)
|
||||||
@ -124,13 +153,92 @@ public class AssistRESTfulUtils {
|
|||||||
return responseJSON;
|
return responseJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject sendPost(MediaServerItem mediaServerItem, String url,
|
||||||
|
JSONObject param, ZLMRESTfulUtils.RequestCallback callback,
|
||||||
|
Integer readTimeOut) {
|
||||||
|
OkHttpClient client = getClient(readTimeOut);
|
||||||
|
|
||||||
public JSONObject fileDuration(MediaServerItem mediaServerItem, String app, String stream, RequestCallback callback){
|
if (mediaServerItem == null) {
|
||||||
Map<String, Object> param = new HashMap<>();
|
return null;
|
||||||
param.put("app",app);
|
}
|
||||||
param.put("stream",stream);
|
JSONObject responseJSON = new JSONObject();
|
||||||
param.put("recordIng",true);
|
//-2自定义流媒体 调用错误码
|
||||||
return sendGet(mediaServerItem, "api/record/file/duration",param, callback);
|
responseJSON.put("code",-2);
|
||||||
|
responseJSON.put("msg","ASSIST调用失败");
|
||||||
|
|
||||||
|
RequestBody requestBodyJson = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), param.toString());
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.post(requestBodyJson)
|
||||||
|
.url(url)
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.build();
|
||||||
|
if (callback == null) {
|
||||||
|
try {
|
||||||
|
Response response = client.newCall(request).execute();
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
ResponseBody responseBody = response.body();
|
||||||
|
if (responseBody != null) {
|
||||||
|
String responseStr = responseBody.string();
|
||||||
|
responseJSON = JSON.parseObject(responseStr);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
response.close();
|
||||||
|
Objects.requireNonNull(response.body()).close();
|
||||||
|
}
|
||||||
|
}catch (IOException e) {
|
||||||
|
logger.error(String.format("[ %s ]ASSIST请求失败: %s", url, e.getMessage()));
|
||||||
|
|
||||||
|
if(e instanceof SocketTimeoutException){
|
||||||
|
//读取超时超时异常
|
||||||
|
logger.error(String.format("读取ASSIST数据失败: %s, %s", url, e.getMessage()));
|
||||||
|
}
|
||||||
|
if(e instanceof ConnectException){
|
||||||
|
//判断连接异常,我这里是报Failed to connect to 10.7.5.144
|
||||||
|
logger.error(String.format("连接ASSIST失败: %s, %s", url, e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch (Exception e){
|
||||||
|
logger.error(String.format("访问ASSIST失败: %s, %s", url, e.getMessage()));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
client.newCall(request).enqueue(new Callback(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NotNull Call call, @NotNull Response response){
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
try {
|
||||||
|
String responseStr = Objects.requireNonNull(response.body()).string();
|
||||||
|
callback.run(JSON.parseObject(responseStr));
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(String.format("[ %s ]请求失败: %s", url, e.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}else {
|
||||||
|
response.close();
|
||||||
|
Objects.requireNonNull(response.body()).close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NotNull Call call, @NotNull IOException e) {
|
||||||
|
logger.error(String.format("连接ZLM失败: %s, %s", call.request().toString(), e.getMessage()));
|
||||||
|
|
||||||
|
if(e instanceof SocketTimeoutException){
|
||||||
|
//读取超时超时异常
|
||||||
|
logger.error(String.format("读取ZLM数据失败: %s, %s", call.request().toString(), e.getMessage()));
|
||||||
|
}
|
||||||
|
if(e instanceof ConnectException){
|
||||||
|
//判断连接异常,我这里是报Failed to connect to 10.7.5.144
|
||||||
|
logger.error(String.format("连接ZLM失败: %s, %s", call.request().toString(), e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return responseJSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject getInfo(MediaServerItem mediaServerItem, RequestCallback callback){
|
public JSONObject getInfo(MediaServerItem mediaServerItem, RequestCallback callback){
|
||||||
@ -138,33 +246,43 @@ public class AssistRESTfulUtils {
|
|||||||
return sendGet(mediaServerItem, "api/record/info",param, callback);
|
return sendGet(mediaServerItem, "api/record/info",param, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject addStreamCallInfo(MediaServerItem mediaServerItem, String app, String stream, String callId, RequestCallback callback){
|
public JSONObject addTask(MediaServerItem mediaServerItem, String app, String stream, String startTime,
|
||||||
Map<String, Object> param = new HashMap<>();
|
String endTime, String callId, List<String> filePathList, String remoteHost) {
|
||||||
param.put("app",app);
|
|
||||||
param.put("stream",stream);
|
JSONObject videoTaskInfoJSON = new JSONObject();
|
||||||
param.put("callId",callId);
|
videoTaskInfoJSON.put("app", app);
|
||||||
return sendGet(mediaServerItem, "api/record/addStreamCallInfo",param, callback);
|
videoTaskInfoJSON.put("stream", stream);
|
||||||
|
videoTaskInfoJSON.put("startTime", startTime);
|
||||||
|
videoTaskInfoJSON.put("endTime", endTime);
|
||||||
|
videoTaskInfoJSON.put("callId", callId);
|
||||||
|
videoTaskInfoJSON.put("filePathList", filePathList);
|
||||||
|
if (!ObjectUtils.isEmpty(remoteHost)) {
|
||||||
|
videoTaskInfoJSON.put("remoteHost", remoteHost);
|
||||||
|
}
|
||||||
|
String urlStr = String.format("%s/api/record/file/download/task/add", remoteHost);;
|
||||||
|
return sendPost(mediaServerItem, urlStr, videoTaskInfoJSON, null, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject getDateList(MediaServerItem mediaServerItem, String app, String stream, int year, int month) {
|
public JSONObject queryTaskList(MediaServerItem mediaServerItem, String app, String stream, String callId,
|
||||||
|
String taskId, Boolean isEnd, String scheme) {
|
||||||
Map<String, Object> param = new HashMap<>();
|
Map<String, Object> param = new HashMap<>();
|
||||||
param.put("app", app);
|
if (!ObjectUtils.isEmpty(app)) {
|
||||||
param.put("stream", stream);
|
param.put("app", app);
|
||||||
param.put("year", year);
|
}
|
||||||
param.put("month", month);
|
if (!ObjectUtils.isEmpty(stream)) {
|
||||||
return sendGet(mediaServerItem, "api/record/date/list", param, null);
|
param.put("stream", stream);
|
||||||
|
}
|
||||||
|
if (!ObjectUtils.isEmpty(callId)) {
|
||||||
|
param.put("callId", callId);
|
||||||
|
}
|
||||||
|
if (!ObjectUtils.isEmpty(taskId)) {
|
||||||
|
param.put("taskId", taskId);
|
||||||
|
}
|
||||||
|
if (!ObjectUtils.isEmpty(isEnd)) {
|
||||||
|
param.put("isEnd", isEnd);
|
||||||
|
}
|
||||||
|
String urlStr = String.format("%s://%s:%s/api/record/file/download/task/list",
|
||||||
|
scheme, mediaServerItem.getIp(), mediaServerItem.getRecordAssistPort());;
|
||||||
|
return sendGet(mediaServerItem, urlStr, param, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject getFileList(MediaServerItem mediaServerItem, int page, int count, String app, String stream,
|
|
||||||
String startTime, String endTime) {
|
|
||||||
Map<String, Object> param = new HashMap<>();
|
|
||||||
param.put("app", app);
|
|
||||||
param.put("stream", stream);
|
|
||||||
param.put("page", page);
|
|
||||||
param.put("count", count);
|
|
||||||
param.put("startTime", startTime);
|
|
||||||
param.put("endTime", endTime);
|
|
||||||
return sendGet(mediaServerItem, "api/record/file/listWithDate", param, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,9 @@ public class ZLMHttpHookListener {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ICloudRecordService cloudRecordService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private VideoStreamSessionManager sessionManager;
|
private VideoStreamSessionManager sessionManager;
|
||||||
|
|
||||||
@ -231,12 +234,6 @@ public class ZLMHttpHookListener {
|
|||||||
streamAuthorityInfo.setSign(sign);
|
streamAuthorityInfo.setSign(sign);
|
||||||
// 鉴权通过
|
// 鉴权通过
|
||||||
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
|
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
|
||||||
// 通知assist新的callId
|
|
||||||
if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) {
|
|
||||||
taskExecutor.execute(() -> {
|
|
||||||
assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId());
|
zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId());
|
||||||
@ -262,7 +259,6 @@ public class ZLMHttpHookListener {
|
|||||||
} else {
|
} else {
|
||||||
result.setEnable_mp4(userSetting.isRecordPushLive());
|
result.setEnable_mp4(userSetting.isRecordPushLive());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 国标流
|
// 国标流
|
||||||
if ("rtp".equals(param.getApp()) ) {
|
if ("rtp".equals(param.getApp()) ) {
|
||||||
|
|
||||||
@ -279,9 +275,17 @@ public class ZLMHttpHookListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置音频信息及录制信息
|
// 设置音频信息及录制信息
|
||||||
List<SsrcTransaction> ssrcTransactionForAll = (inviteInfo == null ? null :
|
List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream());
|
||||||
sessionManager.getSsrcTransactionForAll(inviteInfo.getDeviceId(), inviteInfo.getChannelId(), null, null));
|
|
||||||
if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) {
|
if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) {
|
||||||
|
|
||||||
|
// 为录制国标模拟一个鉴权信息, 方便后续写入录像文件时使用
|
||||||
|
StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
|
||||||
|
streamAuthorityInfo.setApp(param.getApp());
|
||||||
|
streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream());
|
||||||
|
streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId());
|
||||||
|
|
||||||
|
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo);
|
||||||
|
|
||||||
String deviceId = ssrcTransactionForAll.get(0).getDeviceId();
|
String deviceId = ssrcTransactionForAll.get(0).getDeviceId();
|
||||||
String channelId = ssrcTransactionForAll.get(0).getChannelId();
|
String channelId = ssrcTransactionForAll.get(0).getChannelId();
|
||||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||||
@ -290,26 +294,16 @@ public class ZLMHttpHookListener {
|
|||||||
}
|
}
|
||||||
// 如果是录像下载就设置视频间隔十秒
|
// 如果是录像下载就设置视频间隔十秒
|
||||||
if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) {
|
if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) {
|
||||||
result.setMp4_max_second(10);
|
// 获取录像的总时长,然后设置为这个视频的时长
|
||||||
result.setEnable_mp4(true);
|
InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, param.getStream());
|
||||||
}
|
if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) {
|
||||||
}
|
String startTime = inviteInfoForDownload.getStreamInfo().getStartTime();
|
||||||
}
|
String endTime = inviteInfoForDownload.getStreamInfo().getEndTime();
|
||||||
|
long difference = DateUtil.getDifference(startTime, endTime) / 1000;
|
||||||
if (mediaInfo.getRecordAssistPort() > 0 && userSetting.getRecordPath() == null) {
|
result.setMp4_max_second((int) difference);
|
||||||
logger.info("推流时发现尚未设置录像路径,从assist服务中读取");
|
result.setEnable_mp4(true);
|
||||||
JSONObject info = assistRESTfulUtils.getInfo(mediaInfo, null);
|
// 设置为2保证得到的mp4的时长是正常的
|
||||||
if (info != null && info.getInteger("code") != null && info.getInteger("code") == 0 ) {
|
result.setModify_stamp(2);
|
||||||
JSONObject dataJson = info.getJSONObject("data");
|
|
||||||
if (dataJson != null) {
|
|
||||||
String recordPath = dataJson.getString("record");
|
|
||||||
userSetting.setRecordPath(recordPath);
|
|
||||||
result.setMp4_save_path(recordPath);
|
|
||||||
// 修改zlm中的录像路径
|
|
||||||
if (mediaInfo.isAutoConfig()) {
|
|
||||||
taskExecutor.execute(() -> {
|
|
||||||
mediaServerService.setZLMConfig(mediaInfo, false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,13 +351,11 @@ public class ZLMHttpHookListener {
|
|||||||
|
|
||||||
List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
|
List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
|
||||||
// TODO 重构此处逻辑
|
// TODO 重构此处逻辑
|
||||||
boolean isPush = false;
|
|
||||||
if (param.isRegist()) {
|
if (param.isRegist()) {
|
||||||
// 处理流注册的鉴权信息
|
// 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖
|
||||||
if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
|
if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
|
||||||
|| param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|
|| param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|
||||||
|| param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
|
|| param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
|
||||||
isPush = true;
|
|
||||||
StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
|
StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
|
||||||
if (streamAuthorityInfo == null) {
|
if (streamAuthorityInfo == null) {
|
||||||
streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
|
streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
|
||||||
@ -373,8 +365,6 @@ public class ZLMHttpHookListener {
|
|||||||
}
|
}
|
||||||
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
|
redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
redisCatchStorage.removeStreamAuthorityInfo(param.getApp(), param.getStream());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("rtsp".equals(param.getSchema())) {
|
if ("rtsp".equals(param.getSchema())) {
|
||||||
@ -415,6 +405,9 @@ public class ZLMHttpHookListener {
|
|||||||
|| param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
|
|| param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
|
||||||
param.setSeverId(userSetting.getServerId());
|
param.setSeverId(userSetting.getServerId());
|
||||||
zlmMediaListManager.addPush(param);
|
zlmMediaListManager.addPush(param);
|
||||||
|
|
||||||
|
// 冗余数据,自己系统中自用
|
||||||
|
redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 兼容流注销时类型从redis记录获取
|
// 兼容流注销时类型从redis记录获取
|
||||||
@ -423,6 +416,10 @@ public class ZLMHttpHookListener {
|
|||||||
if (onStreamChangedHookParam != null) {
|
if (onStreamChangedHookParam != null) {
|
||||||
type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType();
|
type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType();
|
||||||
redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream());
|
redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream());
|
||||||
|
if ("PUSH".equalsIgnoreCase(type)) {
|
||||||
|
// 冗余数据,自己系统中自用
|
||||||
|
redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
|
GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
|
||||||
if (gbStream != null) {
|
if (gbStream != null) {
|
||||||
@ -771,7 +768,7 @@ public class ZLMHttpHookListener {
|
|||||||
taskExecutor.execute(() -> {
|
taskExecutor.execute(() -> {
|
||||||
JSONObject json = (JSONObject) JSON.toJSON(param);
|
JSONObject json = (JSONObject) JSON.toJSON(param);
|
||||||
List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout);
|
List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout);
|
||||||
if (subscribes != null && subscribes.size() > 0) {
|
if (subscribes != null && !subscribes.isEmpty()) {
|
||||||
for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
|
for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
|
||||||
subscribe.response(null, param);
|
subscribe.response(null, param);
|
||||||
}
|
}
|
||||||
@ -781,6 +778,28 @@ public class ZLMHttpHookListener {
|
|||||||
return HookResult.SUCCESS();
|
return HookResult.SUCCESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 录像完成事件
|
||||||
|
*/
|
||||||
|
@ResponseBody
|
||||||
|
@PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8")
|
||||||
|
public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) {
|
||||||
|
logger.info("[ZLM HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path());
|
||||||
|
|
||||||
|
taskExecutor.execute(() -> {
|
||||||
|
List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4);
|
||||||
|
if (subscribes != null && !subscribes.isEmpty()) {
|
||||||
|
for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
|
||||||
|
subscribe.response(null, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cloudRecordService.addRecord(param);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return HookResult.SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
private Map<String, String> urlParamToMap(String params) {
|
private Map<String, String> urlParamToMap(String params) {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
if (ObjectUtils.isEmpty(params)) {
|
if (ObjectUtils.isEmpty(params)) {
|
||||||
|
@ -25,8 +25,6 @@ public class ZLMRESTfulUtils {
|
|||||||
|
|
||||||
private OkHttpClient client;
|
private OkHttpClient client;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface RequestCallback{
|
public interface RequestCallback{
|
||||||
void run(JSONObject response);
|
void run(JSONObject response);
|
||||||
}
|
}
|
||||||
@ -398,4 +396,14 @@ public class ZLMRESTfulUtils {
|
|||||||
param.put("stream_id", streamId);
|
param.put("stream_id", streamId);
|
||||||
return sendPost(mediaServerItem, "updateRtpServerSSRC",param, null);
|
return sendPost(mediaServerItem, "updateRtpServerSSRC",param, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JSONObject deleteRecordDirectory(MediaServerItem mediaServerItem, String app, String stream, String date, String fileName) {
|
||||||
|
Map<String, Object> param = new HashMap<>(1);
|
||||||
|
param.put("vhost", "__defaultVhost__");
|
||||||
|
param.put("app", app);
|
||||||
|
param.put("stream", stream);
|
||||||
|
param.put("period", date);
|
||||||
|
param.put("name", fileName);
|
||||||
|
return sendPost(mediaServerItem, "deleteRecordDirectory",param, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,4 +41,15 @@ public class HookSubscribeFactory {
|
|||||||
|
|
||||||
return hookSubscribe;
|
return hookSubscribe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HookSubscribeForRecordMp4 on_record_mp4(String mediaServerId, String app, String stream) {
|
||||||
|
HookSubscribeForRecordMp4 hookSubscribe = new HookSubscribeForRecordMp4();
|
||||||
|
JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject();
|
||||||
|
subscribeKey.put("app", app);
|
||||||
|
subscribeKey.put("stream", stream);
|
||||||
|
subscribeKey.put("mediaServerId", mediaServerId);
|
||||||
|
hookSubscribe.setContent(subscribeKey);
|
||||||
|
|
||||||
|
return hookSubscribe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.genersoft.iot.vmp.media.zlm.dto;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hook订阅-录像完成
|
||||||
|
* @author lin
|
||||||
|
*/
|
||||||
|
public class HookSubscribeForRecordMp4 implements IHookSubscribe{
|
||||||
|
|
||||||
|
private HookType hookType = HookType.on_record_mp4;
|
||||||
|
|
||||||
|
private JSONObject content;
|
||||||
|
|
||||||
|
@JSONField(format="yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Instant expires;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HookType getHookType() {
|
||||||
|
return hookType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(JSONObject content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Instant getExpires() {
|
||||||
|
return expires;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExpires(Instant expires) {
|
||||||
|
this.expires = expires;
|
||||||
|
}
|
||||||
|
}
|
@ -85,9 +85,11 @@ public class MediaServerItem{
|
|||||||
@Schema(description = "是否是默认ZLM")
|
@Schema(description = "是否是默认ZLM")
|
||||||
private boolean defaultServer;
|
private boolean defaultServer;
|
||||||
|
|
||||||
@Schema(description = "当前使用到的端口")
|
@Schema(description = "录像存储时长")
|
||||||
private int currentPort;
|
private int recordDay;
|
||||||
|
|
||||||
|
@Schema(description = "录像存储路径")
|
||||||
|
private String recordPath;
|
||||||
|
|
||||||
public MediaServerItem() {
|
public MediaServerItem() {
|
||||||
}
|
}
|
||||||
@ -274,14 +276,6 @@ public class MediaServerItem{
|
|||||||
this.updateTime = updateTime;
|
this.updateTime = updateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentPort() {
|
|
||||||
return currentPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentPort(int currentPort) {
|
|
||||||
this.currentPort = currentPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isStatus() {
|
public boolean isStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -313,4 +307,20 @@ public class MediaServerItem{
|
|||||||
public void setSendRtpPortRange(String sendRtpPortRange) {
|
public void setSendRtpPortRange(String sendRtpPortRange) {
|
||||||
this.sendRtpPortRange = sendRtpPortRange;
|
this.sendRtpPortRange = sendRtpPortRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRecordDay() {
|
||||||
|
return recordDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecordDay(int recordDay) {
|
||||||
|
this.recordDay = recordDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRecordPath() {
|
||||||
|
return recordPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecordPath(String recordPath) {
|
||||||
|
this.recordPath = recordPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ public class HookResultForOnPublish extends HookResult{
|
|||||||
private int mp4_max_second;
|
private int mp4_max_second;
|
||||||
private String mp4_save_path;
|
private String mp4_save_path;
|
||||||
private String stream_replace;
|
private String stream_replace;
|
||||||
|
private Integer modify_stamp;
|
||||||
|
|
||||||
public HookResultForOnPublish() {
|
public HookResultForOnPublish() {
|
||||||
}
|
}
|
||||||
@ -60,14 +61,23 @@ public class HookResultForOnPublish extends HookResult{
|
|||||||
this.stream_replace = stream_replace;
|
this.stream_replace = stream_replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getModify_stamp() {
|
||||||
|
return modify_stamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModify_stamp(Integer modify_stamp) {
|
||||||
|
this.modify_stamp = modify_stamp;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "HookResultForOnPublish{" +
|
return "HookResultForOnPublish{" +
|
||||||
"enable_audio=" + enable_audio +
|
"enable_audio=" + enable_audio +
|
||||||
", enable_mp4=" + enable_mp4 +
|
", enable_mp4=" + enable_mp4 +
|
||||||
", mp4_max_second=" + mp4_max_second +
|
", mp4_max_second=" + mp4_max_second +
|
||||||
", stream_replace=" + stream_replace +
|
|
||||||
", mp4_save_path='" + mp4_save_path + '\'' +
|
", mp4_save_path='" + mp4_save_path + '\'' +
|
||||||
|
", stream_replace='" + stream_replace + '\'' +
|
||||||
|
", modify_stamp='" + modify_stamp + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
114
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRecordMp4HookParam.java
Executable file
114
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRecordMp4HookParam.java
Executable file
@ -0,0 +1,114 @@
|
|||||||
|
package com.genersoft.iot.vmp.media.zlm.dto.hook;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zlm hook事件中的on_rtp_server_timeout事件的参数
|
||||||
|
* @author lin
|
||||||
|
*/
|
||||||
|
public class OnRecordMp4HookParam extends HookParam{
|
||||||
|
private String app;
|
||||||
|
private String stream;
|
||||||
|
private String file_name;
|
||||||
|
private String file_path;
|
||||||
|
private long file_size;
|
||||||
|
private String folder;
|
||||||
|
private String url;
|
||||||
|
private String vhost;
|
||||||
|
private long start_time;
|
||||||
|
private double time_len;
|
||||||
|
|
||||||
|
public String getApp() {
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp(String app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStream() {
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStream(String stream) {
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFile_name() {
|
||||||
|
return file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile_name(String file_name) {
|
||||||
|
this.file_name = file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFile_path() {
|
||||||
|
return file_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile_path(String file_path) {
|
||||||
|
this.file_path = file_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFile_size() {
|
||||||
|
return file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFile_size(long file_size) {
|
||||||
|
this.file_size = file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFolder() {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFolder(String folder) {
|
||||||
|
this.folder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVhost() {
|
||||||
|
return vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVhost(String vhost) {
|
||||||
|
this.vhost = vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStart_time() {
|
||||||
|
return start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStart_time(long start_time) {
|
||||||
|
this.start_time = start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTime_len() {
|
||||||
|
return time_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime_len(double time_len) {
|
||||||
|
this.time_len = time_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OnRecordMp4HookParam{" +
|
||||||
|
"app='" + app + '\'' +
|
||||||
|
", stream='" + stream + '\'' +
|
||||||
|
", file_name='" + file_name + '\'' +
|
||||||
|
", file_path='" + file_path + '\'' +
|
||||||
|
", file_size='" + file_size + '\'' +
|
||||||
|
", folder='" + folder + '\'' +
|
||||||
|
", url='" + url + '\'' +
|
||||||
|
", vhost='" + vhost + '\'' +
|
||||||
|
", start_time=" + start_time +
|
||||||
|
", time_len=" + time_len +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
59
src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java
Executable file
59
src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
package com.genersoft.iot.vmp.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.CloudRecordItem;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端录像管理
|
||||||
|
* @author lin
|
||||||
|
*/
|
||||||
|
public interface ICloudRecordService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页回去云端录像列表
|
||||||
|
*/
|
||||||
|
PageInfo<CloudRecordItem> getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List<MediaServerItem> mediaServerItems);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据hook消息增加一条记录
|
||||||
|
*/
|
||||||
|
void addRecord(OnRecordMp4HookParam param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有的日期
|
||||||
|
*/
|
||||||
|
List<String> getDateList(String app, String stream, int year, int month, List<MediaServerItem> mediaServerItems);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加合并任务
|
||||||
|
*/
|
||||||
|
String addTask(String app, String stream, MediaServerItem mediaServerItem, String startTime,
|
||||||
|
String endTime, String callId, String remoteHost, boolean filterMediaServer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询合并任务列表
|
||||||
|
*/
|
||||||
|
JSONArray queryTask(String app, String stream, String callId, String taskId, String mediaServerId, Boolean isEnd, String scheme);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏视频,收藏的视频过期不会删除
|
||||||
|
*/
|
||||||
|
int changeCollect(boolean result, String app, String stream, String mediaServerId, String startTime, String endTime, String callId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加指定录像收藏
|
||||||
|
*/
|
||||||
|
int changeCollectById(Integer recordId, boolean result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放地址
|
||||||
|
*/
|
||||||
|
DownloadFileInfo getPlayUrlPath(Integer recordId);
|
||||||
|
}
|
@ -87,21 +87,12 @@ public interface IMediaServerService {
|
|||||||
|
|
||||||
void updateMediaServerKeepalive(String mediaServerId, ServerKeepaliveData data);
|
void updateMediaServerKeepalive(String mediaServerId, ServerKeepaliveData data);
|
||||||
|
|
||||||
boolean checkRtpServer(MediaServerItem mediaServerItem, String rtp, String stream);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取负载信息
|
* 获取负载信息
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
MediaServerLoad getLoad(MediaServerItem mediaServerItem);
|
MediaServerLoad getLoad(MediaServerItem mediaServerItem);
|
||||||
|
|
||||||
/**
|
List<MediaServerItem> getAllWithAssistPort();
|
||||||
* 按时间查找录像文件
|
|
||||||
*/
|
|
||||||
List<RecordFile> getRecords(String app, String stream, String startTime, String endTime, List<MediaServerItem> mediaServerItems);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找存在录像文件的时间
|
|
||||||
*/
|
|
||||||
List<String> getRecordDates(String app, String stream, int year, int month, List<MediaServerItem> mediaServerItems);
|
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,6 @@ public interface IPlayService {
|
|||||||
|
|
||||||
MediaServerItem getNewMediaServerItem(Device device);
|
MediaServerItem getNewMediaServerItem(Device device);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取包含assist服务的节点
|
|
||||||
*/
|
|
||||||
MediaServerItem getNewMediaServerItemHasAssist(Device device);
|
|
||||||
|
|
||||||
void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
|
void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
|
||||||
void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
|
void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
|
||||||
void zlmServerOffline(String mediaServerId);
|
void zlmServerOffline(String mediaServerId);
|
||||||
@ -44,5 +39,4 @@ public interface IPlayService {
|
|||||||
|
|
||||||
void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
|
void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -114,4 +114,5 @@ public interface IStreamPushService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ResourceBaseInfo getOverview();
|
ResourceBaseInfo getOverview();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,205 @@
|
|||||||
|
package com.genersoft.iot.vmp.service.bean;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 云端录像数据
|
||||||
|
*/
|
||||||
|
public class CloudRecordItem {
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用名
|
||||||
|
*/
|
||||||
|
private String app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流
|
||||||
|
*/
|
||||||
|
private String stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 健全ID
|
||||||
|
*/
|
||||||
|
private String callId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private long startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private long endTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ZLM Id
|
||||||
|
*/
|
||||||
|
private String mediaServerId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件名称
|
||||||
|
*/
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件路径
|
||||||
|
*/
|
||||||
|
private String filePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件夹
|
||||||
|
*/
|
||||||
|
private String folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏,收藏的文件不移除
|
||||||
|
*/
|
||||||
|
private Boolean collect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保留,收藏的文件不移除
|
||||||
|
*/
|
||||||
|
private Boolean reserve;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小
|
||||||
|
*/
|
||||||
|
private long fileSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件时长
|
||||||
|
*/
|
||||||
|
private long timeLen;
|
||||||
|
|
||||||
|
public static CloudRecordItem getInstance(OnRecordMp4HookParam param) {
|
||||||
|
CloudRecordItem cloudRecordItem = new CloudRecordItem();
|
||||||
|
cloudRecordItem.setApp(param.getApp());
|
||||||
|
cloudRecordItem.setStream(param.getStream());
|
||||||
|
cloudRecordItem.setStartTime(param.getStart_time()*1000);
|
||||||
|
cloudRecordItem.setFileName(param.getFile_name());
|
||||||
|
cloudRecordItem.setFolder(param.getFolder());
|
||||||
|
cloudRecordItem.setFileSize(param.getFile_size());
|
||||||
|
cloudRecordItem.setFilePath(param.getFile_path());
|
||||||
|
cloudRecordItem.setMediaServerId(param.getMediaServerId());
|
||||||
|
cloudRecordItem.setTimeLen((long) param.getTime_len() * 1000);
|
||||||
|
cloudRecordItem.setEndTime((param.getStart_time() + (long)param.getTime_len()) * 1000);
|
||||||
|
return cloudRecordItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp() {
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp(String app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStream() {
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStream(String stream) {
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCallId() {
|
||||||
|
return callId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCallId(String callId) {
|
||||||
|
this.callId = callId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStartTime() {
|
||||||
|
return startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartTime(long startTime) {
|
||||||
|
this.startTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getEndTime() {
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndTime(long endTime) {
|
||||||
|
this.endTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMediaServerId() {
|
||||||
|
return mediaServerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMediaServerId(String mediaServerId) {
|
||||||
|
this.mediaServerId = mediaServerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilePath() {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilePath(String filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFolder() {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFolder(String folder) {
|
||||||
|
this.folder = folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileSize(long fileSize) {
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeLen() {
|
||||||
|
return timeLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeLen(long timeLen) {
|
||||||
|
this.timeLen = timeLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getCollect() {
|
||||||
|
return collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCollect(Boolean collect) {
|
||||||
|
this.collect = collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getReserve() {
|
||||||
|
return reserve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReserve(Boolean reserve) {
|
||||||
|
this.reserve = reserve;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.genersoft.iot.vmp.service.bean;
|
||||||
|
|
||||||
|
public class DownloadFileInfo {
|
||||||
|
|
||||||
|
private String httpPath;
|
||||||
|
private String httpsPath;
|
||||||
|
private String httpDomainPath;
|
||||||
|
private String httpsDomainPath;
|
||||||
|
|
||||||
|
public String getHttpPath() {
|
||||||
|
return httpPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpPath(String httpPath) {
|
||||||
|
this.httpPath = httpPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHttpsPath() {
|
||||||
|
return httpsPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpsPath(String httpsPath) {
|
||||||
|
this.httpsPath = httpsPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHttpDomainPath() {
|
||||||
|
return httpDomainPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpDomainPath(String httpDomainPath) {
|
||||||
|
this.httpDomainPath = httpDomainPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHttpsDomainPath() {
|
||||||
|
return httpsDomainPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHttpsDomainPath(String httpsDomainPath) {
|
||||||
|
this.httpsDomainPath = httpsDomainPath;
|
||||||
|
}
|
||||||
|
}
|
@ -29,12 +29,12 @@ public class WvpRedisMsg {
|
|||||||
* 消息的ID
|
* 消息的ID
|
||||||
*/
|
*/
|
||||||
private String serial;
|
private String serial;
|
||||||
private Object content;
|
private String content;
|
||||||
|
|
||||||
private final static String requestTag = "req";
|
private final static String requestTag = "req";
|
||||||
private final static String responseTag = "res";
|
private final static String responseTag = "res";
|
||||||
|
|
||||||
public static WvpRedisMsg getRequestInstance(String fromId, String toId, String cmd, String serial, Object content) {
|
public static WvpRedisMsg getRequestInstance(String fromId, String toId, String cmd, String serial, String content) {
|
||||||
WvpRedisMsg wvpRedisMsg = new WvpRedisMsg();
|
WvpRedisMsg wvpRedisMsg = new WvpRedisMsg();
|
||||||
wvpRedisMsg.setType(requestTag);
|
wvpRedisMsg.setType(requestTag);
|
||||||
wvpRedisMsg.setFromId(fromId);
|
wvpRedisMsg.setFromId(fromId);
|
||||||
@ -51,7 +51,7 @@ public class WvpRedisMsg {
|
|||||||
return wvpRedisMsg;
|
return wvpRedisMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WvpRedisMsg getResponseInstance(String fromId, String toId, String cmd, String serial, Object content) {
|
public static WvpRedisMsg getResponseInstance(String fromId, String toId, String cmd, String serial, String content) {
|
||||||
WvpRedisMsg wvpRedisMsg = new WvpRedisMsg();
|
WvpRedisMsg wvpRedisMsg = new WvpRedisMsg();
|
||||||
wvpRedisMsg.setType(responseTag);
|
wvpRedisMsg.setType(responseTag);
|
||||||
wvpRedisMsg.setFromId(fromId);
|
wvpRedisMsg.setFromId(fromId);
|
||||||
@ -106,11 +106,11 @@ public class WvpRedisMsg {
|
|||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getContent() {
|
public String getContent() {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContent(Object content) {
|
public void setContent(String content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,235 @@
|
|||||||
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
|
||||||
|
import com.genersoft.iot.vmp.service.ICloudRecordService;
|
||||||
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.CloudRecordItem;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
|
import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
|
||||||
|
import com.genersoft.iot.vmp.utils.CloudRecordUtils;
|
||||||
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@DS("share")
|
||||||
|
public class CloudRecordServiceImpl implements ICloudRecordService {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(CloudRecordServiceImpl.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CloudRecordServiceMapper cloudRecordServiceMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AssistRESTfulUtils assistRESTfulUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VideoStreamSessionManager streamSession;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageInfo<CloudRecordItem> getList(int page, int count, String query, String app, String stream, String startTime, String endTime, List<MediaServerItem> mediaServerItems) {
|
||||||
|
// 开始时间和结束时间在数据库中都是以秒为单位的
|
||||||
|
Long startTimeStamp = null;
|
||||||
|
Long endTimeStamp = null;
|
||||||
|
if (startTime != null ) {
|
||||||
|
if (!DateUtil.verification(startTime, DateUtil.formatter)) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "开始时间格式错误,正确格式为: " + DateUtil.formatter);
|
||||||
|
}
|
||||||
|
startTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (endTime != null ) {
|
||||||
|
if (!DateUtil.verification(endTime, DateUtil.formatter)) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "结束时间格式错误,正确格式为: " + DateUtil.formatter);
|
||||||
|
}
|
||||||
|
endTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
PageHelper.startPage(page, count);
|
||||||
|
List<CloudRecordItem> all = cloudRecordServiceMapper.getList(query, app, stream, startTimeStamp, endTimeStamp,
|
||||||
|
null, mediaServerItems);
|
||||||
|
return new PageInfo<>(all);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getDateList(String app, String stream, int year, int month, List<MediaServerItem> mediaServerItems) {
|
||||||
|
LocalDate startDate = LocalDate.of(year, month, 1);
|
||||||
|
LocalDate endDate;
|
||||||
|
if (month == 12) {
|
||||||
|
endDate = LocalDate.of(year + 1, 1, 1);
|
||||||
|
}else {
|
||||||
|
endDate = LocalDate.of(year, month + 1, 1);
|
||||||
|
}
|
||||||
|
long startTimeStamp = startDate.atStartOfDay().toInstant(ZoneOffset.ofHours(8)).getEpochSecond();
|
||||||
|
long endTimeStamp = endDate.atStartOfDay().toInstant(ZoneOffset.ofHours(8)).getEpochSecond();
|
||||||
|
List<CloudRecordItem> cloudRecordItemList = cloudRecordServiceMapper.getList(null, app, stream, startTimeStamp,
|
||||||
|
endTimeStamp, null, mediaServerItems);
|
||||||
|
if (cloudRecordItemList.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
Set<String> resultSet = new HashSet<>();
|
||||||
|
cloudRecordItemList.stream().forEach(cloudRecordItem -> {
|
||||||
|
String date = DateUtil.timestampTo_yyyy_MM_dd(cloudRecordItem.getStartTime());
|
||||||
|
resultSet.add(date);
|
||||||
|
});
|
||||||
|
return new ArrayList<>(resultSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addRecord(OnRecordMp4HookParam param) {
|
||||||
|
CloudRecordItem cloudRecordItem = CloudRecordItem.getInstance(param);
|
||||||
|
StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
|
||||||
|
if (streamAuthorityInfo != null) {
|
||||||
|
cloudRecordItem.setCallId(streamAuthorityInfo.getCallId());
|
||||||
|
}
|
||||||
|
logger.info("[添加录像记录] {}/{} 文件大小:{}, 时长: {}秒", param.getApp(), param.getStream(), param.getFile_size(),param.getTime_len());
|
||||||
|
cloudRecordServiceMapper.add(cloudRecordItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String addTask(String app, String stream, MediaServerItem mediaServerItem, String startTime, String endTime,
|
||||||
|
String callId, String remoteHost, boolean filterMediaServer) {
|
||||||
|
// 参数校验
|
||||||
|
assert app != null;
|
||||||
|
assert stream != null;
|
||||||
|
if (mediaServerItem.getRecordAssistPort() == 0) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "为配置Assist服务");
|
||||||
|
}
|
||||||
|
Long startTimeStamp = null;
|
||||||
|
Long endTimeStamp = null;
|
||||||
|
if (startTime != null) {
|
||||||
|
startTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime);
|
||||||
|
}
|
||||||
|
if (endTime != null) {
|
||||||
|
endTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MediaServerItem> mediaServers = new ArrayList<>();
|
||||||
|
mediaServers.add(mediaServerItem);
|
||||||
|
// 检索相关的录像文件
|
||||||
|
List<String> filePathList = cloudRecordServiceMapper.queryRecordFilePathList(app, stream, startTimeStamp,
|
||||||
|
endTimeStamp, callId, filterMediaServer ? mediaServers : null);
|
||||||
|
if (filePathList == null || filePathList.isEmpty()) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未检索到视频文件");
|
||||||
|
}
|
||||||
|
JSONObject result = assistRESTfulUtils.addTask(mediaServerItem, app, stream, startTime, endTime, callId, filePathList, remoteHost);
|
||||||
|
if (result.getInteger("code") != 0) {
|
||||||
|
throw new ControllerException(result.getInteger("code"), result.getString("msg"));
|
||||||
|
}
|
||||||
|
return result.getString("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONArray queryTask(String app, String stream, String callId, String taskId, String mediaServerId,
|
||||||
|
Boolean isEnd, String scheme) {
|
||||||
|
MediaServerItem mediaServerItem = null;
|
||||||
|
if (mediaServerId == null) {
|
||||||
|
mediaServerItem = mediaServerService.getDefaultMediaServer();
|
||||||
|
}else {
|
||||||
|
mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||||
|
}
|
||||||
|
if (mediaServerItem == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的流媒体");
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject result = assistRESTfulUtils.queryTaskList(mediaServerItem, app, stream, callId, taskId, isEnd, scheme);
|
||||||
|
if (result == null || result.getInteger("code") != 0) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), result == null ? "查询任务列表失败" : result.getString("msg"));
|
||||||
|
}
|
||||||
|
return result.getJSONArray("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int changeCollect(boolean result, String app, String stream, String mediaServerId, String startTime, String endTime, String callId) {
|
||||||
|
// 开始时间和结束时间在数据库中都是以秒为单位的
|
||||||
|
Long startTimeStamp = null;
|
||||||
|
Long endTimeStamp = null;
|
||||||
|
if (startTime != null ) {
|
||||||
|
if (!DateUtil.verification(startTime, DateUtil.formatter)) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "开始时间格式错误,正确格式为: " + DateUtil.formatter);
|
||||||
|
}
|
||||||
|
startTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (endTime != null ) {
|
||||||
|
if (!DateUtil.verification(endTime, DateUtil.formatter)) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "结束时间格式错误,正确格式为: " + DateUtil.formatter);
|
||||||
|
}
|
||||||
|
endTimeStamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MediaServerItem> mediaServerItems;
|
||||||
|
if (!ObjectUtils.isEmpty(mediaServerId)) {
|
||||||
|
mediaServerItems = new ArrayList<>();
|
||||||
|
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||||
|
if (mediaServerItem == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到流媒体: " + mediaServerId);
|
||||||
|
}
|
||||||
|
mediaServerItems.add(mediaServerItem);
|
||||||
|
} else {
|
||||||
|
mediaServerItems = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CloudRecordItem> all = cloudRecordServiceMapper.getList(null, app, stream, startTimeStamp, endTimeStamp,
|
||||||
|
callId, mediaServerItems);
|
||||||
|
if (all.isEmpty()) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到待收藏的视频");
|
||||||
|
}
|
||||||
|
int limitCount = 50;
|
||||||
|
int resultCount = 0;
|
||||||
|
if (all.size() > limitCount) {
|
||||||
|
for (int i = 0; i < all.size(); i += limitCount) {
|
||||||
|
int toIndex = i + limitCount;
|
||||||
|
if (i + limitCount > all.size()) {
|
||||||
|
toIndex = all.size();
|
||||||
|
}
|
||||||
|
resultCount += cloudRecordServiceMapper.updateCollectList(result, all.subList(i, toIndex));
|
||||||
|
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
resultCount = cloudRecordServiceMapper.updateCollectList(result, all);
|
||||||
|
}
|
||||||
|
return resultCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int changeCollectById(Integer recordId, boolean result) {
|
||||||
|
return cloudRecordServiceMapper.changeCollectById(result, recordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DownloadFileInfo getPlayUrlPath(Integer recordId) {
|
||||||
|
CloudRecordItem recordItem = cloudRecordServiceMapper.queryOne(recordId);
|
||||||
|
if (recordItem == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "资源不存在");
|
||||||
|
}
|
||||||
|
String filePath = recordItem.getFilePath();
|
||||||
|
MediaServerItem mediaServerItem = mediaServerService.getOne(recordItem.getMediaServerId());
|
||||||
|
return CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||||
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
import com.genersoft.iot.vmp.service.IDeviceAlarmService;
|
||||||
@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class DeviceAlarmServiceImpl implements IDeviceAlarmService {
|
public class DeviceAlarmServiceImpl implements IDeviceAlarmService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
@ -27,6 +28,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(DeviceChannelServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(DeviceChannelServiceImpl.class);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
@ -45,6 +46,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* 设备业务(目录订阅)
|
* 设备业务(目录订阅)
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class DeviceServiceImpl implements IDeviceService {
|
public class DeviceServiceImpl implements IDeviceService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);
|
||||||
@ -152,6 +154,19 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
sync(device);
|
sync(device);
|
||||||
// TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
|
// TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台
|
||||||
}
|
}
|
||||||
|
// 上线添加订阅
|
||||||
|
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||||
|
// 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
|
||||||
|
addCatalogSubscribe(device);
|
||||||
|
}
|
||||||
|
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
||||||
|
addMobilePositionSubscribe(device);
|
||||||
|
}
|
||||||
|
if (userSetting.getDeviceStatusNotify()) {
|
||||||
|
// 发送redis消息
|
||||||
|
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
}else {
|
}else {
|
||||||
if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).isEmpty()) {
|
if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).isEmpty()) {
|
||||||
logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId());
|
logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId());
|
||||||
@ -164,22 +179,10 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 上线添加订阅
|
|
||||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
|
||||||
// 查询在线设备那些开启了订阅,为设备开启定时的目录订阅
|
|
||||||
addCatalogSubscribe(device);
|
|
||||||
}
|
|
||||||
if (device.getSubscribeCycleForMobilePosition() > 0) {
|
|
||||||
addMobilePositionSubscribe(device);
|
|
||||||
}
|
|
||||||
// 刷新过期任务
|
// 刷新过期任务
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + device.getDeviceId();
|
||||||
// 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
|
// 如果第一次注册那么必须在60 * 3时间内收到一个心跳,否则设备离线
|
||||||
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3);
|
dynamicTask.startDelay(registerExpireTaskKey, ()-> offline(device.getDeviceId(), "首次注册后未能收到心跳"), device.getKeepaliveIntervalTime() * 1000 * 3);
|
||||||
if (userSetting.getDeviceStatusNotify()) {
|
|
||||||
// 发送redis消息
|
|
||||||
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// try {
|
// try {
|
||||||
@ -203,6 +206,13 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
}
|
}
|
||||||
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
|
String registerExpireTaskKey = VideoManagerConstants.REGISTER_EXPIRE_TASK_KEY_PREFIX + deviceId;
|
||||||
dynamicTask.stop(registerExpireTaskKey);
|
dynamicTask.stop(registerExpireTaskKey);
|
||||||
|
if (device.isOnLine()) {
|
||||||
|
if (userSetting.getDeviceStatusNotify()) {
|
||||||
|
// 发送redis消息
|
||||||
|
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
device.setOnLine(false);
|
device.setOnLine(false);
|
||||||
redisCatchStorage.updateDevice(device);
|
redisCatchStorage.updateDevice(device);
|
||||||
deviceMapper.update(device);
|
deviceMapper.update(device);
|
||||||
@ -220,11 +230,6 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
// 移除订阅
|
// 移除订阅
|
||||||
removeCatalogSubscribe(device);
|
removeCatalogSubscribe(device);
|
||||||
removeMobilePositionSubscribe(device);
|
removeMobilePositionSubscribe(device);
|
||||||
if (userSetting.getDeviceStatusNotify()) {
|
|
||||||
// 发送redis消息
|
|
||||||
redisCatchStorage.sendDeviceOrChannelStatus(device.getDeviceId(), null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -271,7 +276,7 @@ public class DeviceServiceImpl implements IDeviceService {
|
|||||||
// 设置最小值为30
|
// 设置最小值为30
|
||||||
int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30);
|
int subscribeCycleForCatalog = Math.max(device.getSubscribeCycleForMobilePosition(),30);
|
||||||
// 刷新订阅
|
// 刷新订阅
|
||||||
dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, (subscribeCycleForCatalog) * 1000);
|
dynamicTask.startCron(device.getDeviceId() + "mobile_position" , mobilePositionSubscribeTask, subscribeCycleForCatalog * 1000);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||||
@ -25,6 +26,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class GbStreamServiceImpl implements IGbStreamService {
|
public class GbStreamServiceImpl implements IGbStreamService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(GbStreamServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(GbStreamServiceImpl.class);
|
||||||
@ -77,8 +79,6 @@ public class GbStreamServiceImpl implements IGbStreamService {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
List<DeviceChannel> deviceChannelList = new ArrayList<>();
|
List<DeviceChannel> deviceChannelList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < gbStreams.size(); i++) {
|
for (int i = 0; i < gbStreams.size(); i++) {
|
||||||
GbStream gbStream = gbStreams.get(i);
|
GbStream gbStream = gbStreams.get(i);
|
||||||
gbStream.setCatalogId(catalogId);
|
gbStream.setCatalogId(catalogId);
|
||||||
@ -251,18 +251,17 @@ public class GbStreamServiceImpl implements IGbStreamService {
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
if (ObjectUtils.isEmpty(catalogId)) {
|
if (ObjectUtils.isEmpty(catalogId)) {
|
||||||
catalogId = platform.getDeviceGBId();
|
catalogId = null;
|
||||||
}
|
}
|
||||||
if (platformGbStreamMapper.delByPlatformAndCatalogId(platformId, catalogId) > 0) {
|
List<GbStream> gbStreams = platformGbStreamMapper.queryChannelInParentPlatformAndCatalog(platformId, catalogId);
|
||||||
List<GbStream> gbStreams = platformGbStreamMapper.queryChannelInParentPlatformAndCatalog(platformId, catalogId);
|
List<DeviceChannel> deviceChannelList = new ArrayList<>();
|
||||||
List<DeviceChannel> deviceChannelList = new ArrayList<>();
|
for (GbStream gbStream : gbStreams) {
|
||||||
for (GbStream gbStream : gbStreams) {
|
DeviceChannel deviceChannel = new DeviceChannel();
|
||||||
DeviceChannel deviceChannel = new DeviceChannel();
|
deviceChannel.setChannelId(gbStream.getGbId());
|
||||||
deviceChannel.setChannelId(gbStream.getGbId());
|
deviceChannelList.add(deviceChannel);
|
||||||
deviceChannelList.add(deviceChannel);
|
|
||||||
}
|
|
||||||
eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.DEL);
|
|
||||||
}
|
}
|
||||||
|
eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.DEL);
|
||||||
|
platformGbStreamMapper.delByPlatformAndCatalogId(platformId, catalogId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionStatus;
|
import com.genersoft.iot.vmp.common.InviteSessionStatus;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
@ -20,6 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class InviteStreamServiceImpl implements IInviteStreamService {
|
public class InviteStreamServiceImpl implements IInviteStreamService {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(InviteStreamServiceImpl.class);
|
private final Logger logger = LoggerFactory.getLogger(InviteStreamServiceImpl.class);
|
||||||
@ -116,9 +118,12 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
|
|||||||
":" + (stream != null ? stream : "*")
|
":" + (stream != null ? stream : "*")
|
||||||
+ ":*";
|
+ ":*";
|
||||||
List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
|
List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
|
||||||
if (scanResult.size() != 1) {
|
if (scanResult.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (scanResult.size() != 1) {
|
||||||
|
logger.warn("[获取InviteInfo] 发现 key: {}存在多条", key);
|
||||||
|
}
|
||||||
|
|
||||||
return (InviteInfo) redisTemplate.opsForValue().get(scanResult.get(0));
|
return (InviteInfo) redisTemplate.opsForValue().get(scanResult.get(0));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
||||||
import com.genersoft.iot.vmp.service.ILogService;
|
import com.genersoft.iot.vmp.service.ILogService;
|
||||||
import com.genersoft.iot.vmp.storager.dao.LogMapper;
|
import com.genersoft.iot.vmp.storager.dao.LogMapper;
|
||||||
@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class LogServiceImpl implements ILogService {
|
public class LogServiceImpl implements ILogService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.service.impl;
|
|||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.CommonCallback;
|
import com.genersoft.iot.vmp.common.CommonCallback;
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
@ -55,6 +56,7 @@ import java.util.concurrent.ExecutionException;
|
|||||||
* 媒体服务器节点管理
|
* 媒体服务器节点管理
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MediaServerServiceImpl implements IMediaServerService {
|
public class MediaServerServiceImpl implements IMediaServerService {
|
||||||
|
|
||||||
@ -309,7 +311,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaServerItem getDefaultMediaServer() {
|
public MediaServerItem getDefaultMediaServer() {
|
||||||
|
|
||||||
return mediaServerMapper.queryDefault();
|
return mediaServerMapper.queryDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,17 +425,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
|
|
||||||
|
|
||||||
if (serverItem.isAutoConfig()) {
|
if (serverItem.isAutoConfig()) {
|
||||||
// 查看assist服务的录像路径配置
|
|
||||||
if (serverItem.getRecordAssistPort() > 0 && userSetting.getRecordPath() == null) {
|
|
||||||
JSONObject info = assistRESTfulUtils.getInfo(serverItem, null);
|
|
||||||
if (info != null && info.getInteger("code") != null && info.getInteger("code") == 0 ) {
|
|
||||||
JSONObject dataJson = info.getJSONObject("data");
|
|
||||||
if (dataJson != null) {
|
|
||||||
String recordPath = dataJson.getString("record");
|
|
||||||
userSetting.setRecordPath(recordPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
|
setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
|
||||||
}
|
}
|
||||||
final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId();
|
final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + serverItem.getId();
|
||||||
@ -569,7 +559,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
logger.info("[ZLM] 正在设置 :{} -> {}:{}",
|
logger.info("[ZLM] 正在设置 :{} -> {}:{}",
|
||||||
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
|
mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort());
|
||||||
String protocol = sslEnabled ? "https" : "http";
|
String protocol = sslEnabled ? "https" : "http";
|
||||||
String hookPrex = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort);
|
String hookPrefix = String.format("%s://%s:%s/index/hook", protocol, mediaServerItem.getHookIp(), serverPort);
|
||||||
|
|
||||||
Map<String, Object> param = new HashMap<>();
|
Map<String, Object> param = new HashMap<>();
|
||||||
param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline
|
param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline
|
||||||
@ -578,20 +568,21 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
}
|
}
|
||||||
param.put("hook.enable","1");
|
param.put("hook.enable","1");
|
||||||
param.put("hook.on_flow_report","");
|
param.put("hook.on_flow_report","");
|
||||||
param.put("hook.on_play",String.format("%s/on_play", hookPrex));
|
param.put("hook.on_play",String.format("%s/on_play", hookPrefix));
|
||||||
param.put("hook.on_http_access","");
|
param.put("hook.on_http_access","");
|
||||||
param.put("hook.on_publish", String.format("%s/on_publish", hookPrex));
|
param.put("hook.on_publish", String.format("%s/on_publish", hookPrefix));
|
||||||
param.put("hook.on_record_ts","");
|
param.put("hook.on_record_ts","");
|
||||||
param.put("hook.on_rtsp_auth","");
|
param.put("hook.on_rtsp_auth","");
|
||||||
param.put("hook.on_rtsp_realm","");
|
param.put("hook.on_rtsp_realm","");
|
||||||
param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrex));
|
param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrefix));
|
||||||
param.put("hook.on_shell_login","");
|
param.put("hook.on_shell_login","");
|
||||||
param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex));
|
param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrefix));
|
||||||
param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
|
param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrefix));
|
||||||
param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
|
param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrefix));
|
||||||
param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex));
|
param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrefix));
|
||||||
param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrex));
|
param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrefix));
|
||||||
param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrex));
|
param.put("hook.on_rtp_server_timeout",String.format("%s/on_rtp_server_timeout", hookPrefix));
|
||||||
|
param.put("hook.on_record_mp4",String.format("%s/on_record_mp4", hookPrefix));
|
||||||
if (mediaServerItem.getRecordAssistPort() > 0) {
|
if (mediaServerItem.getRecordAssistPort() > 0) {
|
||||||
if(mediaConfig.getRecordAssistIp().equals("127.0.0.1")){
|
if(mediaConfig.getRecordAssistIp().equals("127.0.0.1")){
|
||||||
param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort()));
|
param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort()));
|
||||||
@ -610,15 +601,14 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
param.put("protocol.continue_push_ms", "3000" );
|
param.put("protocol.continue_push_ms", "3000" );
|
||||||
// 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流,
|
// 最多等待未初始化的Track时间,单位毫秒,超时之后会忽略未初始化的Track, 设置此选项优化那些音频错误的不规范流,
|
||||||
// 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项
|
// 等zlm支持给每个rtpServer设置关闭音频的时候可以不设置此选项
|
||||||
// param.put("general.wait_track_ready_ms", "3000" );
|
|
||||||
if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) {
|
if (mediaServerItem.isRtpEnable() && !ObjectUtils.isEmpty(mediaServerItem.getRtpPortRange())) {
|
||||||
param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-"));
|
param.put("rtp_proxy.port_range", mediaServerItem.getRtpPortRange().replace(",", "-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userSetting.getRecordPath() != null) {
|
if (!ObjectUtils.isEmpty(mediaServerItem.getRecordPath())) {
|
||||||
File recordPathFile = new File(userSetting.getRecordPath());
|
File recordPathFile = new File(mediaServerItem.getRecordPath());
|
||||||
File mp4SavePathFile = recordPathFile.getParentFile().getAbsoluteFile();
|
param.put("protocol.mp4_save_path", recordPathFile.getParentFile().getPath());
|
||||||
param.put("protocol.mp4_save_path", mp4SavePathFile.getAbsoluteFile());
|
param.put("protocol.downloadRoot", recordPathFile.getParentFile().getPath());
|
||||||
param.put("record.appName", recordPathFile.getName());
|
param.put("record.appName", recordPathFile.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,6 +713,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null);
|
ssrcFactory.initMediaServerSSRC(mediaServerItem.getId(), null);
|
||||||
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
|
String key = VideoManagerConstants.MEDIA_SERVER_PREFIX + userSetting.getServerId() + "_" + mediaServerItem.getId();
|
||||||
redisTemplate.opsForValue().set(key, mediaServerItem);
|
redisTemplate.opsForValue().set(key, mediaServerItem);
|
||||||
|
resetOnlineServerItem(mediaServerItem);
|
||||||
clearRTPServer(mediaServerItem);
|
clearRTPServer(mediaServerItem);
|
||||||
}
|
}
|
||||||
final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId();
|
final String zlmKeepaliveKey = zlmKeepaliveKeyPrefix + mediaServerItem.getId();
|
||||||
@ -750,15 +741,6 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkRtpServer(MediaServerItem mediaServerItem, String app, String stream) {
|
|
||||||
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(mediaServerItem, stream);
|
|
||||||
if(rtpInfo.getInteger("code") == 0){
|
|
||||||
return rtpInfo.getBoolean("exist");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaServerLoad getLoad(MediaServerItem mediaServerItem) {
|
public MediaServerLoad getLoad(MediaServerItem mediaServerItem) {
|
||||||
MediaServerLoad result = new MediaServerLoad();
|
MediaServerLoad result = new MediaServerLoad();
|
||||||
@ -772,88 +754,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RecordFile> getRecords(String app, String stream, String startTime, String endTime, List<MediaServerItem> mediaServerItems) {
|
public List<MediaServerItem> getAllWithAssistPort() {
|
||||||
Assert.notNull(app, "app不存在");
|
return mediaServerMapper.queryAllWithAssistPort();
|
||||||
Assert.notNull(stream, "stream不存在");
|
|
||||||
Assert.notNull(startTime, "startTime不存在");
|
|
||||||
Assert.notNull(endTime, "endTime不存在");
|
|
||||||
Assert.notEmpty(mediaServerItems, "流媒体列表为空");
|
|
||||||
|
|
||||||
CompletableFuture[] completableFutures = new CompletableFuture[mediaServerItems.size()];
|
|
||||||
for (int i = 0; i < mediaServerItems.size(); i++) {
|
|
||||||
completableFutures[i] = getRecordFilesForOne(app, stream, startTime, endTime, mediaServerItems.get(i));
|
|
||||||
}
|
|
||||||
List<RecordFile> result = new ArrayList<>();
|
|
||||||
for (int i = 0; i < completableFutures.length; i++) {
|
|
||||||
try {
|
|
||||||
List<RecordFile> list = (List<RecordFile>) completableFutures[i].get();
|
|
||||||
if (!list.isEmpty()) {
|
|
||||||
for (int g = 0; g < list.size(); g++) {
|
|
||||||
list.get(g).setMediaServerId(mediaServerItems.get(i).getId());
|
|
||||||
}
|
|
||||||
result.addAll(list);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Comparator<RecordFile> comparator = Comparator.comparing(RecordFile::getFileName);
|
|
||||||
result.sort(comparator);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getRecordDates(String app, String stream, int year, int month, List<MediaServerItem> mediaServerItems) {
|
|
||||||
Assert.notNull(app, "app不存在");
|
|
||||||
Assert.notNull(stream, "stream不存在");
|
|
||||||
Assert.notEmpty(mediaServerItems, "流媒体列表为空");
|
|
||||||
CompletableFuture[] completableFutures = new CompletableFuture[mediaServerItems.size()];
|
|
||||||
|
|
||||||
for (int i = 0; i < mediaServerItems.size(); i++) {
|
|
||||||
completableFutures[i] = getRecordDatesForOne(app, stream, year, month, mediaServerItems.get(i));
|
|
||||||
}
|
|
||||||
List<String> result = new ArrayList<>();
|
|
||||||
CompletableFuture.allOf(completableFutures).join();
|
|
||||||
for (CompletableFuture completableFuture : completableFutures) {
|
|
||||||
try {
|
|
||||||
List<String> list = (List<String>) completableFuture.get();
|
|
||||||
result.addAll(list);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collections.sort(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Async
|
|
||||||
public CompletableFuture<List<String>> getRecordDatesForOne(String app, String stream, int year, int month, MediaServerItem mediaServerItem) {
|
|
||||||
JSONObject fileListJson = assistRESTfulUtils.getDateList(mediaServerItem, app, stream, year, month);
|
|
||||||
if (fileListJson != null && !fileListJson.isEmpty()) {
|
|
||||||
if (fileListJson.getString("code") != null && fileListJson.getInteger("code") == 0) {
|
|
||||||
JSONArray data = fileListJson.getJSONArray("data");
|
|
||||||
return CompletableFuture.completedFuture(data.toJavaList(String.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CompletableFuture.completedFuture(new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Async
|
|
||||||
public CompletableFuture<List<RecordFile>> getRecordFilesForOne(String app, String stream, String startTime, String endTime, MediaServerItem mediaServerItem) {
|
|
||||||
JSONObject fileListJson = assistRESTfulUtils.getFileList(mediaServerItem, 1, 100000000, app, stream, startTime, endTime);
|
|
||||||
if (fileListJson != null && !fileListJson.isEmpty()) {
|
|
||||||
if (fileListJson.getString("code") != null && fileListJson.getInteger("code") == 0) {
|
|
||||||
JSONObject data = fileListJson.getJSONObject("data");
|
|
||||||
JSONArray list = data.getJSONArray("list");
|
|
||||||
if (list != null) {
|
|
||||||
return CompletableFuture.completedFuture(list.toJavaList(RecordFile.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CompletableFuture.completedFuture(new ArrayList<>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public class MediaServiceImpl implements IMediaService {
|
|||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JSONObject mediaJSON = JSON.parseObject(JSON.toJSONString(data.get(0)), JSONObject.class);
|
JSONObject mediaJSON = data.getJSONObject(0);
|
||||||
JSONArray tracks = mediaJSON.getJSONArray("tracks");
|
JSONArray tracks = mediaJSON.getJSONArray("tracks");
|
||||||
if (authority) {
|
if (authority) {
|
||||||
streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, addr, calld);
|
streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, addr, calld);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||||
@ -27,6 +28,7 @@ import java.util.Map;
|
|||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(PlatformChannelServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(PlatformChannelServiceImpl.class);
|
||||||
@ -165,10 +167,9 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService {
|
|||||||
catalogId = null;
|
catalogId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result = platformChannelMapper.delChannelForGBByCatalogId(platformId, catalogId)) > 0) {
|
List<DeviceChannel> deviceChannels = platformChannelMapper.queryAllChannelInCatalog(platformId, catalogId);
|
||||||
List<DeviceChannel> deviceChannels = platformChannelMapper.queryAllChannelInCatalog(platformId, catalogId);
|
eventPublisher.catalogEventPublish(platformId, deviceChannels, CatalogEvent.DEL);
|
||||||
eventPublisher.catalogEventPublish(platformId, deviceChannels, CatalogEvent.DEL);
|
|
||||||
}
|
return platformChannelMapper.delChannelForGBByCatalogId(platformId, catalogId);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
@ -38,6 +39,7 @@ import java.util.*;
|
|||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class PlatformServiceImpl implements IPlatformService {
|
public class PlatformServiceImpl implements IPlatformService {
|
||||||
|
|
||||||
private final static String REGISTER_KEY_PREFIX = "platform_register_";
|
private final static String REGISTER_KEY_PREFIX = "platform_register_";
|
||||||
@ -149,7 +151,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
dynamicTask.stop(registerTaskKey);
|
dynamicTask.stop(registerTaskKey);
|
||||||
// 注销旧的
|
// 注销旧的
|
||||||
try {
|
try {
|
||||||
if (parentPlatformOld.isStatus()) {
|
if (parentPlatformOld.isStatus() && parentPlatformCatchOld != null) {
|
||||||
logger.info("保存平台{}时发现旧平台在线,发送注销命令", parentPlatformOld.getServerGBId());
|
logger.info("保存平台{}时发现旧平台在线,发送注销命令", parentPlatformOld.getServerGBId());
|
||||||
commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> {
|
commanderForPlatform.unregister(parentPlatformOld, parentPlatformCatchOld.getSipTransactionInfo(), null, eventResult -> {
|
||||||
logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId());
|
logger.info("[国标级联] 注销成功, 平台:{}", parentPlatformOld.getServerGBId());
|
||||||
@ -266,6 +268,7 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
}
|
}
|
||||||
if (parentPlatform.isAutoPushChannel()) {
|
if (parentPlatform.isAutoPushChannel()) {
|
||||||
if (subscribeHolder.getCatalogSubscribe(parentPlatform.getServerGBId()) == null) {
|
if (subscribeHolder.getCatalogSubscribe(parentPlatform.getServerGBId()) == null) {
|
||||||
|
logger.info("[国标级联]:{}, 添加自动通道推送模拟订阅信息", parentPlatform.getServerGBId());
|
||||||
addSimulatedSubscribeInfo(parentPlatform);
|
addSimulatedSubscribeInfo(parentPlatform);
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
@ -344,9 +347,16 @@ public class PlatformServiceImpl implements IPlatformService {
|
|||||||
// 清除心跳任务
|
// 清除心跳任务
|
||||||
dynamicTask.stop(keepaliveTaskKey);
|
dynamicTask.stop(keepaliveTaskKey);
|
||||||
}
|
}
|
||||||
// 停止目录订阅回复
|
// 停止订阅回复
|
||||||
logger.info("[平台离线] {}, 停止订阅回复", parentPlatform.getServerGBId());
|
SubscribeInfo catalogSubscribe = subscribeHolder.getCatalogSubscribe(parentPlatform.getServerGBId());
|
||||||
subscribeHolder.removeAllSubscribe(parentPlatform.getServerGBId());
|
if (catalogSubscribe != null) {
|
||||||
|
if (catalogSubscribe.getExpires() > 0) {
|
||||||
|
logger.info("[平台离线] {}, 停止目录订阅回复", parentPlatform.getServerGBId());
|
||||||
|
subscribeHolder.removeCatalogSubscribe(parentPlatform.getServerGBId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("[平台离线] {}, 停止移动位置订阅回复", parentPlatform.getServerGBId());
|
||||||
|
subscribeHolder.removeMobilePositionSubscribe(parentPlatform.getServerGBId());
|
||||||
// 发起定时自动重新注册
|
// 发起定时自动重新注册
|
||||||
if (!stopRegister) {
|
if (!stopRegister) {
|
||||||
// 设置为60秒自动尝试重新注册
|
// 设置为60秒自动尝试重新注册
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionStatus;
|
import com.genersoft.iot.vmp.common.InviteSessionStatus;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
@ -13,25 +15,22 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
|||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
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.cmd.impl.SIPCommanderFroPlatform;
|
||||||
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
|
||||||
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
|
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
|
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
|
import com.genersoft.iot.vmp.media.zlm.dto.*;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
|
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
|
import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
|
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
|
||||||
import com.genersoft.iot.vmp.service.*;
|
import com.genersoft.iot.vmp.service.*;
|
||||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
import com.genersoft.iot.vmp.service.bean.*;
|
||||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
|
||||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
|
import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
|
||||||
|
import com.genersoft.iot.vmp.utils.CloudRecordUtils;
|
||||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import gov.nist.javax.sip.message.SIPResponse;
|
import gov.nist.javax.sip.message.SIPResponse;
|
||||||
@ -56,6 +55,7 @@ import java.util.Vector;
|
|||||||
|
|
||||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class PlayServiceImpl implements IPlayService {
|
public class PlayServiceImpl implements IPlayService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(PlayServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(PlayServiceImpl.class);
|
||||||
@ -76,7 +76,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
private IInviteStreamService inviteStreamService;
|
private IInviteStreamService inviteStreamService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeferredResultHolder resultHolder;
|
private ZlmHttpHookSubscribe subscribe;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||||
@ -84,9 +84,6 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ZLMServerFactory zlmServerFactory;
|
private ZLMServerFactory zlmServerFactory;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AssistRESTfulUtils assistRESTfulUtils;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMediaService mediaService;
|
private IMediaService mediaService;
|
||||||
|
|
||||||
@ -106,7 +103,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
private DynamicTask dynamicTask;
|
private DynamicTask dynamicTask;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ZlmHttpHookSubscribe subscribe;
|
private CloudRecordServiceMapper cloudRecordServiceMapper;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -444,23 +441,6 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
return mediaServerItem;
|
return mediaServerItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public MediaServerItem getNewMediaServerItemHasAssist(Device device) {
|
|
||||||
if (device == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
MediaServerItem mediaServerItem;
|
|
||||||
if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) {
|
|
||||||
mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(true);
|
|
||||||
} else {
|
|
||||||
mediaServerItem = mediaServerService.getOne(device.getMediaServerId());
|
|
||||||
}
|
|
||||||
if (mediaServerItem == null) {
|
|
||||||
logger.warn("[获取可用的ZLM节点]未找到可使用的ZLM...");
|
|
||||||
}
|
|
||||||
return mediaServerItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playBack(String deviceId, String channelId, String startTime,
|
public void playBack(String deviceId, String channelId, String startTime,
|
||||||
String endTime, ErrorCallback<Object> callback) {
|
String endTime, ErrorCallback<Object> callback) {
|
||||||
@ -678,7 +658,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
if (device == null) {
|
if (device == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MediaServerItem newMediaServerItem = getNewMediaServerItemHasAssist(device);
|
MediaServerItem newMediaServerItem = this.getNewMediaServerItem(device);
|
||||||
if (newMediaServerItem == null) {
|
if (newMediaServerItem == null) {
|
||||||
callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(),
|
callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(),
|
||||||
InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getMsg(),
|
InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getMsg(),
|
||||||
@ -759,6 +739,28 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
// 处理收到200ok后的TCP主动连接以及SSRC不一致的问题
|
// 处理收到200ok后的TCP主动连接以及SSRC不一致的问题
|
||||||
InviteOKHandler(eventResult, ssrcInfo, mediaServerItem, device, channelId,
|
InviteOKHandler(eventResult, ssrcInfo, mediaServerItem, device, channelId,
|
||||||
downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD);
|
downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD);
|
||||||
|
|
||||||
|
// 注册录像回调事件,录像下载结束后写入下载地址
|
||||||
|
ZlmHttpHookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> {
|
||||||
|
logger.info("[录像下载] 收到录像写入磁盘消息: , {}/{}-{}",
|
||||||
|
inviteInfo.getDeviceId(), inviteInfo.getChannelId(), ssrcInfo.getStream());
|
||||||
|
logger.info("[录像下载] 收到录像写入磁盘消息内容: " + hookParam);
|
||||||
|
OnRecordMp4HookParam recordMp4HookParam = (OnRecordMp4HookParam)hookParam;
|
||||||
|
String filePath = recordMp4HookParam.getFile_path();
|
||||||
|
DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath);
|
||||||
|
InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId()
|
||||||
|
, inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||||
|
inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo);
|
||||||
|
inviteStreamService.updateInviteInfo(inviteInfoForNew);
|
||||||
|
};
|
||||||
|
HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4(
|
||||||
|
mediaServerItem.getId(), "rtp", ssrcInfo.getStream());
|
||||||
|
|
||||||
|
// 设置过期时间,下载失败时自动处理订阅数据
|
||||||
|
// long difference = DateUtil.getDifference(startTime, endTime)/1000;
|
||||||
|
// Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(difference * 2));
|
||||||
|
// hookSubscribe.setExpires(expiresInstant);
|
||||||
|
subscribe.addSubscribe(hookSubscribe, hookEventForRecord);
|
||||||
});
|
});
|
||||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||||
logger.error("[命令发送失败] 录像下载: {}", e.getMessage());
|
logger.error("[命令发送失败] 录像下载: {}", e.getMessage());
|
||||||
@ -774,47 +776,71 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
@Override
|
@Override
|
||||||
public StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream) {
|
public StreamInfo getDownLoadInfo(String deviceId, String channelId, String stream) {
|
||||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, stream);
|
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, stream);
|
||||||
|
if (inviteInfo == null || inviteInfo.getStreamInfo() == null) {
|
||||||
|
logger.warn("[获取下载进度] 未查询到录像下载的信息");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (inviteInfo != null && inviteInfo.getStreamInfo() != null) {
|
if (inviteInfo.getStreamInfo().getProgress() == 1) {
|
||||||
if (inviteInfo.getStreamInfo().getProgress() == 1) {
|
|
||||||
return inviteInfo.getStreamInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前已下载时长
|
|
||||||
String mediaServerId = inviteInfo.getStreamInfo().getMediaServerId();
|
|
||||||
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
|
||||||
if (mediaServerItem == null) {
|
|
||||||
logger.warn("查询录像信息时发现节点已离线");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (mediaServerItem.getRecordAssistPort() > 0) {
|
|
||||||
JSONObject jsonObject = assistRESTfulUtils.fileDuration(mediaServerItem, inviteInfo.getStreamInfo().getApp(), inviteInfo.getStreamInfo().getStream(), null);
|
|
||||||
if (jsonObject == null) {
|
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接Assist服务失败");
|
|
||||||
}
|
|
||||||
if (jsonObject.getInteger("code") == 0) {
|
|
||||||
long duration = jsonObject.getLong("data");
|
|
||||||
|
|
||||||
if (duration == 0) {
|
|
||||||
inviteInfo.getStreamInfo().setProgress(0);
|
|
||||||
} else {
|
|
||||||
String startTime = inviteInfo.getStreamInfo().getStartTime();
|
|
||||||
String endTime = inviteInfo.getStreamInfo().getEndTime();
|
|
||||||
long start = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime);
|
|
||||||
long end = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime);
|
|
||||||
|
|
||||||
BigDecimal currentCount = new BigDecimal(duration / 1000);
|
|
||||||
BigDecimal totalCount = new BigDecimal(end - start);
|
|
||||||
BigDecimal divide = currentCount.divide(totalCount, 2, RoundingMode.HALF_UP);
|
|
||||||
double process = divide.doubleValue();
|
|
||||||
inviteInfo.getStreamInfo().setProgress(process);
|
|
||||||
}
|
|
||||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inviteInfo.getStreamInfo();
|
return inviteInfo.getStreamInfo();
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
// 获取当前已下载时长
|
||||||
|
String mediaServerId = inviteInfo.getStreamInfo().getMediaServerId();
|
||||||
|
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||||
|
if (mediaServerItem == null) {
|
||||||
|
logger.warn("[获取下载进度] 查询录像信息时发现节点不存在");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(deviceId, channelId, null, stream);
|
||||||
|
|
||||||
|
if (ssrcTransaction == null) {
|
||||||
|
logger.warn("[获取下载进度] 下载已结束");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject mediaListJson= zlmresTfulUtils.getMediaList(mediaServerItem, "rtp", stream);
|
||||||
|
if (mediaListJson == null) {
|
||||||
|
logger.warn("[获取下载进度] 从zlm查询进度失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (mediaListJson.getInteger("code") != 0) {
|
||||||
|
logger.warn("[获取下载进度] 从zlm查询进度出现错误: {}", mediaListJson.getString("msg"));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONArray data = mediaListJson.getJSONArray("data");
|
||||||
|
if (data == null) {
|
||||||
|
logger.warn("[获取下载进度] 从zlm查询进度时未返回数据");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject mediaJSON = data.getJSONObject(0);
|
||||||
|
JSONArray tracks = mediaJSON.getJSONArray("tracks");
|
||||||
|
if (tracks.isEmpty()) {
|
||||||
|
logger.warn("[获取下载进度] 从zlm查询进度时未返回数据");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = tracks.getJSONObject(0);
|
||||||
|
long duration = jsonObject.getLongValue("duration");
|
||||||
|
if (duration == 0) {
|
||||||
|
inviteInfo.getStreamInfo().setProgress(0);
|
||||||
|
} else {
|
||||||
|
String startTime = inviteInfo.getStreamInfo().getStartTime();
|
||||||
|
String endTime = inviteInfo.getStreamInfo().getEndTime();
|
||||||
|
// 此时start和end单位是秒
|
||||||
|
long start = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime);
|
||||||
|
long end = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime);
|
||||||
|
|
||||||
|
BigDecimal currentCount = new BigDecimal(duration);
|
||||||
|
BigDecimal totalCount = new BigDecimal((end - start) * 1000);
|
||||||
|
BigDecimal divide = currentCount.divide(totalCount, 2, RoundingMode.HALF_UP);
|
||||||
|
double process = divide.doubleValue();
|
||||||
|
if (process > 0.999) {
|
||||||
|
process = 1.0;
|
||||||
|
}
|
||||||
|
inviteInfo.getStreamInfo().setProgress(process);
|
||||||
|
}
|
||||||
|
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||||
|
return inviteInfo.getStreamInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) {
|
private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) {
|
||||||
@ -948,7 +974,12 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
throw new ServiceException("mediaServer不存在");
|
throw new ServiceException("mediaServer不存在");
|
||||||
}
|
}
|
||||||
// zlm 暂停RTP超时检查
|
// zlm 暂停RTP超时检查
|
||||||
JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, streamId);
|
// 使用zlm中的流ID
|
||||||
|
String streamKey = inviteInfo.getStream();
|
||||||
|
if (!mediaServerItem.isRtpEnable()) {
|
||||||
|
streamKey = Long.toHexString(Long.parseLong(inviteInfo.getSsrcInfo().getSsrc())).toUpperCase();
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, streamKey);
|
||||||
if (jsonObject == null || jsonObject.getInteger("code") != 0) {
|
if (jsonObject == null || jsonObject.getInteger("code") != 0) {
|
||||||
throw new ServiceException("暂停RTP接收失败");
|
throw new ServiceException("暂停RTP接收失败");
|
||||||
}
|
}
|
||||||
@ -971,7 +1002,12 @@ public class PlayServiceImpl implements IPlayService {
|
|||||||
throw new ServiceException("mediaServer不存在");
|
throw new ServiceException("mediaServer不存在");
|
||||||
}
|
}
|
||||||
// zlm 暂停RTP超时检查
|
// zlm 暂停RTP超时检查
|
||||||
JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, streamId);
|
// 使用zlm中的流ID
|
||||||
|
String streamKey = inviteInfo.getStream();
|
||||||
|
if (!mediaServerItem.isRtpEnable()) {
|
||||||
|
streamKey = Long.toHexString(Long.parseLong(inviteInfo.getSsrcInfo().getSsrc())).toUpperCase();
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, streamKey);
|
||||||
if (jsonObject == null || jsonObject.getInteger("code") != 0) {
|
if (jsonObject == null || jsonObject.getInteger("code") != 0) {
|
||||||
throw new ServiceException("继续RTP接收失败");
|
throw new ServiceException("继续RTP接收失败");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.service.IRoleService;
|
import com.genersoft.iot.vmp.service.IRoleService;
|
||||||
import com.genersoft.iot.vmp.storager.dao.RoleMapper;
|
import com.genersoft.iot.vmp.storager.dao.RoleMapper;
|
||||||
import com.genersoft.iot.vmp.storager.dao.dto.Role;
|
import com.genersoft.iot.vmp.storager.dao.dto.Role;
|
||||||
@ -9,6 +10,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class RoleServerImpl implements IRoleService {
|
public class RoleServerImpl implements IRoleService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service.impl;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.common.GeneralCallback;
|
import com.genersoft.iot.vmp.common.GeneralCallback;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
@ -53,6 +54,7 @@ import java.util.stream.Collectors;
|
|||||||
* 视频代理业务
|
* 视频代理业务
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class StreamProxyServiceImpl implements IStreamProxyService {
|
public class StreamProxyServiceImpl implements IStreamProxyService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(StreamProxyServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(StreamProxyServiceImpl.class);
|
||||||
@ -132,7 +134,13 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
|||||||
}
|
}
|
||||||
JSONArray dataArray = jsonObject.getJSONArray("data");
|
JSONArray dataArray = jsonObject.getJSONArray("data");
|
||||||
JSONObject mediaServerConfig = dataArray.getJSONObject(0);
|
JSONObject mediaServerConfig = dataArray.getJSONObject(0);
|
||||||
|
if (ObjectUtils.isEmpty(param.getFfmpegCmdKey())) {
|
||||||
|
param.setFfmpegCmdKey("ffmpeg.cmd");
|
||||||
|
}
|
||||||
String ffmpegCmd = mediaServerConfig.getString(param.getFfmpegCmdKey());
|
String ffmpegCmd = mediaServerConfig.getString(param.getFfmpegCmdKey());
|
||||||
|
if (ffmpegCmd == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法获取ffmpeg cmd");
|
||||||
|
}
|
||||||
String schema = getSchemaFromFFmpegCmd(ffmpegCmd);
|
String schema = getSchemaFromFFmpegCmd(ffmpegCmd);
|
||||||
if (schema == null) {
|
if (schema == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法从ffmpeg cmd中获取到输出格式");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法从ffmpeg cmd中获取到输出格式");
|
||||||
@ -460,7 +468,7 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
|||||||
streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId);
|
streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId);
|
||||||
|
|
||||||
// 移除拉流代理生成的流信息
|
// 移除拉流代理生成的流信息
|
||||||
// syncPullStream(mediaServerId);
|
syncPullStream(mediaServerId);
|
||||||
|
|
||||||
// 恢复流代理, 只查找这个这个流媒体
|
// 恢复流代理, 只查找这个这个流媒体
|
||||||
List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
|
List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
|
||||||
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.alibaba.fastjson2.TypeReference;
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.conf.MediaConfig;
|
import com.genersoft.iot.vmp.conf.MediaConfig;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
@ -36,6 +37,7 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class StreamPushServiceImpl implements IStreamPushService {
|
public class StreamPushServiceImpl implements IStreamPushService {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(StreamPushServiceImpl.class);
|
private final static Logger logger = LoggerFactory.getLogger(StreamPushServiceImpl.class);
|
||||||
@ -282,6 +284,8 @@ public class StreamPushServiceImpl implements IStreamPushService {
|
|||||||
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
|
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
|
||||||
// 移除redis内流的信息
|
// 移除redis内流的信息
|
||||||
redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream());
|
redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream());
|
||||||
|
// 冗余数据,自己系统中自用
|
||||||
|
redisCatchStorage.removePushListItem(offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream(), mediaServerItem.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +323,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
|
|||||||
jsonObject.put("register", false);
|
jsonObject.put("register", false);
|
||||||
jsonObject.put("mediaServerId", mediaServerId);
|
jsonObject.put("mediaServerId", mediaServerId);
|
||||||
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
|
redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
|
||||||
|
|
||||||
|
// 冗余数据,自己系统中自用
|
||||||
|
redisCatchStorage.removePushListItem(onStreamChangedHookParam.getApp(), onStreamChangedHookParam.getStream(), mediaServerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.genersoft.iot.vmp.service.IUserService;
|
import com.genersoft.iot.vmp.service.IUserService;
|
||||||
import com.genersoft.iot.vmp.storager.dao.UserMapper;
|
import com.genersoft.iot.vmp.storager.dao.UserMapper;
|
||||||
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
import com.genersoft.iot.vmp.storager.dao.dto.User;
|
||||||
@ -12,6 +13,7 @@ import org.springframework.util.DigestUtils;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@DS("master")
|
||||||
public class UserServiceImpl implements IUserService {
|
public class UserServiceImpl implements IUserService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -13,6 +13,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
|
|||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
import com.genersoft.iot.vmp.service.bean.*;
|
import com.genersoft.iot.vmp.service.bean.*;
|
||||||
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -77,6 +78,9 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IRedisCatchStorage redisCatchStorage;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DynamicTask dynamicTask;
|
private DynamicTask dynamicTask;
|
||||||
@ -113,8 +117,8 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
while (!taskQueue.isEmpty()) {
|
while (!taskQueue.isEmpty()) {
|
||||||
Message msg = taskQueue.poll();
|
Message msg = taskQueue.poll();
|
||||||
try {
|
try {
|
||||||
JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class);
|
WvpRedisMsg wvpRedisMsg = JSON.parseObject(msg.getBody(), WvpRedisMsg.class);
|
||||||
WvpRedisMsg wvpRedisMsg = JSON.to(WvpRedisMsg.class, msgJSON);
|
logger.info("[收到REDIS通知] 消息: {}", JSON.toJSONString(wvpRedisMsg));
|
||||||
if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
|
if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -123,7 +127,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
|
|
||||||
switch (wvpRedisMsg.getCmd()){
|
switch (wvpRedisMsg.getCmd()){
|
||||||
case WvpRedisMsgCmd.GET_SEND_ITEM:
|
case WvpRedisMsgCmd.GET_SEND_ITEM:
|
||||||
RequestSendItemMsg content = JSON.to(RequestSendItemMsg.class, wvpRedisMsg.getContent());
|
RequestSendItemMsg content = JSON.parseObject(wvpRedisMsg.getContent(), RequestSendItemMsg.class);
|
||||||
requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
|
requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial());
|
||||||
break;
|
break;
|
||||||
case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
|
case WvpRedisMsgCmd.REQUEST_PUSH_STREAM:
|
||||||
@ -242,7 +246,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
result.setData(content);
|
result.setData(content);
|
||||||
|
|
||||||
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(userSetting.getServerId(), toId,
|
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(userSetting.getServerId(), toId,
|
||||||
WvpRedisMsgCmd.REQUEST_PUSH_STREAM, serial, result);
|
WvpRedisMsgCmd.REQUEST_PUSH_STREAM, serial, JSON.toJSONString(result));
|
||||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
||||||
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
||||||
}
|
}
|
||||||
@ -260,7 +264,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
result.setMsg("流媒体不存在");
|
result.setMsg("流媒体不存在");
|
||||||
|
|
||||||
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(userSetting.getServerId(), toId,
|
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(userSetting.getServerId(), toId,
|
||||||
WvpRedisMsgCmd.GET_SEND_ITEM, serial, result);
|
WvpRedisMsgCmd.GET_SEND_ITEM, serial, JSON.toJSONString(result));
|
||||||
|
|
||||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
||||||
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
||||||
@ -283,7 +287,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
WVPResult<SendRtpItem> result = new WVPResult<>();
|
WVPResult<SendRtpItem> result = new WVPResult<>();
|
||||||
result.setCode(ERROR_CODE_TIMEOUT);
|
result.setCode(ERROR_CODE_TIMEOUT);
|
||||||
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(
|
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(
|
||||||
userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, result
|
userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, JSON.toJSONString(result)
|
||||||
);
|
);
|
||||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
||||||
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
||||||
@ -322,9 +326,10 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
responseSendItemMsg.setSendRtpItem(sendRtpItem);
|
responseSendItemMsg.setSendRtpItem(sendRtpItem);
|
||||||
responseSendItemMsg.setMediaServerItem(mediaServerItem);
|
responseSendItemMsg.setMediaServerItem(mediaServerItem);
|
||||||
result.setData(responseSendItemMsg);
|
result.setData(responseSendItemMsg);
|
||||||
|
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
||||||
|
|
||||||
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(
|
WvpRedisMsg response = WvpRedisMsg.getResponseInstance(
|
||||||
userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, result
|
userSetting.getServerId(), toId, WvpRedisMsgCmd.GET_SEND_ITEM, serial, JSON.toJSONString(result)
|
||||||
);
|
);
|
||||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
JSONObject jsonObject = (JSONObject)JSON.toJSON(response);
|
||||||
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
redisTemplate.convertAndSend(WVP_PUSH_STREAM_KEY, jsonObject);
|
||||||
@ -350,7 +355,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
requestSendItemMsg.setServerId(serverId);
|
requestSendItemMsg.setServerId(serverId);
|
||||||
String key = UUID.randomUUID().toString();
|
String key = UUID.randomUUID().toString();
|
||||||
WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId, WvpRedisMsgCmd.GET_SEND_ITEM,
|
WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId, WvpRedisMsgCmd.GET_SEND_ITEM,
|
||||||
key, requestSendItemMsg);
|
key, JSON.toJSONString(requestSendItemMsg));
|
||||||
|
|
||||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(redisMsg);
|
JSONObject jsonObject = (JSONObject)JSON.toJSON(redisMsg);
|
||||||
logger.info("[请求推流SendItem] {}: {}", serverId, jsonObject);
|
logger.info("[请求推流SendItem] {}: {}", serverId, jsonObject);
|
||||||
@ -375,7 +380,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
|||||||
public void sendMsgForStartSendRtpStream(String serverId, RequestPushStreamMsg param, PlayMsgCallbackForStartSendRtpStream callback) {
|
public void sendMsgForStartSendRtpStream(String serverId, RequestPushStreamMsg param, PlayMsgCallbackForStartSendRtpStream callback) {
|
||||||
String key = UUID.randomUUID().toString();
|
String key = UUID.randomUUID().toString();
|
||||||
WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId,
|
WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId,
|
||||||
WvpRedisMsgCmd.REQUEST_PUSH_STREAM, key, param);
|
WvpRedisMsgCmd.REQUEST_PUSH_STREAM, key, JSON.toJSONString(param));
|
||||||
|
|
||||||
JSONObject jsonObject = (JSONObject)JSON.toJSON(redisMsg);
|
JSONObject jsonObject = (JSONObject)JSON.toJSON(redisMsg);
|
||||||
logger.info("[REDIS 请求其他平台推流] {}: {}", serverId, jsonObject);
|
logger.info("[REDIS 请求其他平台推流] {}: {}", serverId, jsonObject);
|
||||||
|
@ -50,11 +50,12 @@ public class RedisGpsMsgListener implements MessageListener {
|
|||||||
Message msg = taskQueue.poll();
|
Message msg = taskQueue.poll();
|
||||||
try {
|
try {
|
||||||
GPSMsgInfo gpsMsgInfo = JSON.parseObject(msg.getBody(), GPSMsgInfo.class);
|
GPSMsgInfo gpsMsgInfo = JSON.parseObject(msg.getBody(), GPSMsgInfo.class);
|
||||||
|
logger.info("[REDIS的位置变化通知], {}", JSON.toJSONString(gpsMsgInfo));
|
||||||
// 只是放入redis缓存起来
|
// 只是放入redis缓存起来
|
||||||
redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo);
|
redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo);
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
logger.warn("[REDIS的ALARM通知] 发现未处理的异常, \r\n{}", JSON.toJSONString(message));
|
logger.warn("[REDIS的位置变化通知] 发现未处理的异常, \r\n{}", JSON.toJSONString(message));
|
||||||
logger.error("[REDIS的ALARM通知] 异常内容: ", e);
|
logger.error("[REDIS的位置变化通知] 异常内容: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -73,12 +73,20 @@ public class RedisPushStreamCloseResponseListener implements MessageListener {
|
|||||||
MessageForPushChannel pushChannel = JSON.parseObject(message.getBody(), MessageForPushChannel.class);
|
MessageForPushChannel pushChannel = JSON.parseObject(message.getBody(), MessageForPushChannel.class);
|
||||||
StreamPushItem push = streamPushService.getPush(pushChannel.getApp(), pushChannel.getStream());
|
StreamPushItem push = streamPushService.getPush(pushChannel.getApp(), pushChannel.getStream());
|
||||||
if (push != null) {
|
if (push != null) {
|
||||||
if (redisCatchStorage.isChannelSendingRTP(push.getGbId())) {
|
List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId(
|
||||||
List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId(
|
push.getGbId());
|
||||||
push.getGbId());
|
if (!sendRtpItems.isEmpty()) {
|
||||||
if (sendRtpItems.size() > 0) {
|
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
||||||
for (SendRtpItem sendRtpItem : sendRtpItems) {
|
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
||||||
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
|
if (parentPlatform != null) {
|
||||||
|
redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
||||||
|
try {
|
||||||
|
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem);
|
||||||
|
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||||
|
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (push.isSelf()) {
|
||||||
// 停止向上级推流
|
// 停止向上级推流
|
||||||
String streamId = sendRtpItem.getStreamId();
|
String streamId = sendRtpItem.getStreamId();
|
||||||
Map<String, Object> param = new HashMap<>();
|
Map<String, Object> param = new HashMap<>();
|
||||||
@ -90,12 +98,6 @@ public class RedisPushStreamCloseResponseListener implements MessageListener {
|
|||||||
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
||||||
redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), sendRtpItem.getCallId(), sendRtpItem.getStreamId());
|
||||||
zlmServerFactory.stopSendRtpStream(mediaInfo, param);
|
zlmServerFactory.stopSendRtpStream(mediaInfo, param);
|
||||||
|
|
||||||
try {
|
|
||||||
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem);
|
|
||||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
|
||||||
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
|
if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
|
||||||
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
|
MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0,
|
||||||
sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(),
|
sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getChannelId(),
|
||||||
|
@ -208,4 +208,8 @@ public interface IRedisCatchStorage {
|
|||||||
void sendPlatformStartPlayMsg(MessageForPushChannel messageForPushChannel);
|
void sendPlatformStartPlayMsg(MessageForPushChannel messageForPushChannel);
|
||||||
|
|
||||||
void sendPlatformStopPlayMsg(MessageForPushChannel messageForPushChannel);
|
void sendPlatformStopPlayMsg(MessageForPushChannel messageForPushChannel);
|
||||||
|
|
||||||
|
void addPushListItem(String app, String stream, OnStreamChangedHookParam param);
|
||||||
|
|
||||||
|
void removePushListItem(String app, String stream, String mediaServerId);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
package com.genersoft.iot.vmp.storager.dao;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.CloudRecordItem;
|
||||||
|
import org.apache.ibatis.annotations.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CloudRecordServiceMapper {
|
||||||
|
|
||||||
|
@Insert(" <script>" +
|
||||||
|
"INSERT INTO wvp_cloud_record (" +
|
||||||
|
" app," +
|
||||||
|
" stream," +
|
||||||
|
"<if test=\"callId != null\"> call_id,</if>" +
|
||||||
|
" start_time," +
|
||||||
|
" end_time," +
|
||||||
|
" media_server_id," +
|
||||||
|
" file_name," +
|
||||||
|
" folder," +
|
||||||
|
" file_path," +
|
||||||
|
" file_size," +
|
||||||
|
" time_len ) " +
|
||||||
|
"VALUES (" +
|
||||||
|
" #{app}," +
|
||||||
|
" #{stream}," +
|
||||||
|
" <if test=\"callId != null\"> #{callId},</if>" +
|
||||||
|
" #{startTime}," +
|
||||||
|
" #{endTime}," +
|
||||||
|
" #{mediaServerId}," +
|
||||||
|
" #{fileName}," +
|
||||||
|
" #{folder}," +
|
||||||
|
" #{filePath}," +
|
||||||
|
" #{fileSize}," +
|
||||||
|
" #{timeLen})" +
|
||||||
|
" </script>")
|
||||||
|
int add(CloudRecordItem cloudRecordItem);
|
||||||
|
|
||||||
|
@Select(" <script>" +
|
||||||
|
"select * " +
|
||||||
|
" from wvp_cloud_record " +
|
||||||
|
" where 0 = 0" +
|
||||||
|
" <if test='query != null'> AND (app LIKE concat('%',#{query},'%') OR stream LIKE concat('%',#{query},'%') )</if> " +
|
||||||
|
" <if test= 'app != null '> and app=#{app}</if>" +
|
||||||
|
" <if test= 'stream != null '> and stream=#{stream}</if>" +
|
||||||
|
" <if test= 'startTimeStamp != null '> and end_time >= #{startTimeStamp}</if>" +
|
||||||
|
" <if test= 'endTimeStamp != null '> and start_time <= #{endTimeStamp}</if>" +
|
||||||
|
" <if test= 'callId != null '> and call_id = #{callId}</if>" +
|
||||||
|
" <if test= 'mediaServerItemList != null ' > and media_server_id in " +
|
||||||
|
" <foreach collection='mediaServerItemList' item='item' open='(' separator=',' close=')' > #{item.id}</foreach>" +
|
||||||
|
" </if>" +
|
||||||
|
" order by start_time DESC" +
|
||||||
|
|
||||||
|
" </script>")
|
||||||
|
List<CloudRecordItem> getList(@Param("query") String query, @Param("app") String app, @Param("stream") String stream,
|
||||||
|
@Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp,
|
||||||
|
@Param("callId")String callId, List<MediaServerItem> mediaServerItemList);
|
||||||
|
|
||||||
|
|
||||||
|
@Select(" <script>" +
|
||||||
|
"select file_path" +
|
||||||
|
" from wvp_cloud_record " +
|
||||||
|
" where 0 = 0" +
|
||||||
|
" <if test= 'app != null '> and app=#{app}</if>" +
|
||||||
|
" <if test= 'stream != null '> and stream=#{stream}</if>" +
|
||||||
|
" <if test= 'startTimeStamp != null '> and end_time >= #{startTimeStamp}</if>" +
|
||||||
|
" <if test= 'endTimeStamp != null '> and start_time <= #{endTimeStamp}</if>" +
|
||||||
|
" <if test= 'callId != null '> and call_id = #{callId}</if>" +
|
||||||
|
" <if test= 'mediaServerItemList != null ' > and media_server_id in " +
|
||||||
|
" <foreach collection='mediaServerItemList' item='item' open='(' separator=',' close=')' > #{item.id}</foreach>" +
|
||||||
|
" </if>" +
|
||||||
|
" </script>")
|
||||||
|
List<String> queryRecordFilePathList(@Param("app") String app, @Param("stream") String stream,
|
||||||
|
@Param("startTimeStamp")Long startTimeStamp, @Param("endTimeStamp")Long endTimeStamp,
|
||||||
|
@Param("callId")String callId, List<MediaServerItem> mediaServerItemList);
|
||||||
|
|
||||||
|
@Update(" <script>" +
|
||||||
|
"update wvp_cloud_record set collect = #{collect} where file_path in " +
|
||||||
|
" <foreach collection='cloudRecordItemList' item='item' open='(' separator=',' close=')' > #{item.filePath}</foreach>" +
|
||||||
|
" </script>")
|
||||||
|
int updateCollectList(@Param("collect") boolean collect, List<CloudRecordItem> cloudRecordItemList);
|
||||||
|
|
||||||
|
@Delete(" <script>" +
|
||||||
|
"delete from wvp_cloud_record where media_server_id=#{mediaServerId} and file_path in " +
|
||||||
|
" <foreach collection='filePathList' item='item' open='(' separator=',' close=')' > #{item}</foreach>" +
|
||||||
|
" </script>")
|
||||||
|
void deleteByFileList(List<String> filePathList, @Param("mediaServerId") String mediaServerId);
|
||||||
|
|
||||||
|
|
||||||
|
@Select(" <script>" +
|
||||||
|
"select *" +
|
||||||
|
" from wvp_cloud_record " +
|
||||||
|
" where collect = false and end_time <= #{endTimeStamp} and media_server_id = #{mediaServerId} " +
|
||||||
|
" </script>")
|
||||||
|
List<CloudRecordItem> queryRecordListForDelete(@Param("endTimeStamp")Long endTimeStamp, String mediaServerId);
|
||||||
|
|
||||||
|
@Update(" <script>" +
|
||||||
|
"update wvp_cloud_record set collect = #{collect} where id = #{recordId} " +
|
||||||
|
" </script>")
|
||||||
|
int changeCollectById(@Param("collect") boolean collect, @Param("recordId") Integer recordId);
|
||||||
|
|
||||||
|
@Delete(" <script>" +
|
||||||
|
"delete from wvp_cloud_record where id in " +
|
||||||
|
" <foreach collection='cloudRecordItemIdList' item='item' open='(' separator=',' close=')' > #{item.id}</foreach>" +
|
||||||
|
" </script>")
|
||||||
|
int deleteList(List<CloudRecordItem> cloudRecordItemIdList);
|
||||||
|
|
||||||
|
@Select(" <script>" +
|
||||||
|
"select *" +
|
||||||
|
" from wvp_cloud_record " +
|
||||||
|
"where call_id = #{callId}" +
|
||||||
|
" </script>")
|
||||||
|
List<CloudRecordItem> getListByCallId(@Param("callId") String callId);
|
||||||
|
|
||||||
|
@Select(" <script>" +
|
||||||
|
"select *" +
|
||||||
|
" from wvp_cloud_record " +
|
||||||
|
"where id = #{id}" +
|
||||||
|
" </script>")
|
||||||
|
CloudRecordItem queryOne(@Param("id") Integer id);
|
||||||
|
}
|
@ -107,7 +107,11 @@ public interface DeviceChannelMapper {
|
|||||||
"wvp_device_channel dc " +
|
"wvp_device_channel dc " +
|
||||||
"WHERE " +
|
"WHERE " +
|
||||||
"dc.device_id = #{deviceId} " +
|
"dc.device_id = #{deviceId} " +
|
||||||
" <if test='query != null'> AND (dc.channel_id LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%') OR dc.name LIKE concat('%',#{query},'%'))</if> " +
|
" <if test='query != null'> AND (" +
|
||||||
|
"dc.channel_id LIKE concat('%',#{query},'%') " +
|
||||||
|
"OR dc.name LIKE concat('%',#{query},'%') " +
|
||||||
|
"OR dc.custom_name LIKE concat('%',#{query},'%')" +
|
||||||
|
")</if> " +
|
||||||
" <if test='parentChannelId != null'> AND (dc.parent_id=#{parentChannelId} OR dc.civil_code = #{parentChannelId}) </if> " +
|
" <if test='parentChannelId != null'> AND (dc.parent_id=#{parentChannelId} OR dc.civil_code = #{parentChannelId}) </if> " +
|
||||||
" <if test='online == true' > AND dc.status= true</if>" +
|
" <if test='online == true' > AND dc.status= true</if>" +
|
||||||
" <if test='online == false' > AND dc.status= false</if>" +
|
" <if test='online == false' > AND dc.status= false</if>" +
|
||||||
|
@ -158,7 +158,7 @@ public interface GbStreamMapper {
|
|||||||
" <foreach collection='list' item='item' index='index' separator=';'>"+
|
" <foreach collection='list' item='item' index='index' separator=';'>"+
|
||||||
"UPDATE wvp_gb_stream " +
|
"UPDATE wvp_gb_stream " +
|
||||||
" SET name=#{item.name},"+
|
" SET name=#{item.name},"+
|
||||||
" gb_id=#{item.gb_id}"+
|
" gb_id=#{item.gbId}"+
|
||||||
" WHERE app=#{item.app} and stream=#{item.stream}"+
|
" WHERE app=#{item.app} and stream=#{item.stream}"+
|
||||||
"</foreach>"+
|
"</foreach>"+
|
||||||
"</script>")
|
"</script>")
|
||||||
|
@ -31,6 +31,8 @@ public interface MediaServerMapper {
|
|||||||
"rtp_port_range,"+
|
"rtp_port_range,"+
|
||||||
"send_rtp_port_range,"+
|
"send_rtp_port_range,"+
|
||||||
"record_assist_port,"+
|
"record_assist_port,"+
|
||||||
|
"record_day,"+
|
||||||
|
"record_path,"+
|
||||||
"default_server,"+
|
"default_server,"+
|
||||||
"create_time,"+
|
"create_time,"+
|
||||||
"update_time,"+
|
"update_time,"+
|
||||||
@ -55,6 +57,8 @@ public interface MediaServerMapper {
|
|||||||
"#{rtpPortRange}, " +
|
"#{rtpPortRange}, " +
|
||||||
"#{sendRtpPortRange}, " +
|
"#{sendRtpPortRange}, " +
|
||||||
"#{recordAssistPort}, " +
|
"#{recordAssistPort}, " +
|
||||||
|
"#{recordDay}, " +
|
||||||
|
"#{recordPath}, " +
|
||||||
"#{defaultServer}, " +
|
"#{defaultServer}, " +
|
||||||
"#{createTime}, " +
|
"#{createTime}, " +
|
||||||
"#{updateTime}, " +
|
"#{updateTime}, " +
|
||||||
@ -82,6 +86,8 @@ public interface MediaServerMapper {
|
|||||||
"<if test=\"secret != null\">, secret=#{secret}</if>" +
|
"<if test=\"secret != null\">, secret=#{secret}</if>" +
|
||||||
"<if test=\"recordAssistPort != null\">, record_assist_port=#{recordAssistPort}</if>" +
|
"<if test=\"recordAssistPort != null\">, record_assist_port=#{recordAssistPort}</if>" +
|
||||||
"<if test=\"hookAliveInterval != null\">, hook_alive_interval=#{hookAliveInterval}</if>" +
|
"<if test=\"hookAliveInterval != null\">, hook_alive_interval=#{hookAliveInterval}</if>" +
|
||||||
|
"<if test=\"recordDay != null\">, record_day=#{recordDay}</if>" +
|
||||||
|
"<if test=\"recordPath != null\">, record_path=#{recordPath}</if>" +
|
||||||
"WHERE id=#{id}"+
|
"WHERE id=#{id}"+
|
||||||
" </script>"})
|
" </script>"})
|
||||||
int update(MediaServerItem mediaServerItem);
|
int update(MediaServerItem mediaServerItem);
|
||||||
@ -105,6 +111,8 @@ public interface MediaServerMapper {
|
|||||||
"<if test=\"sendRtpPortRange != null\">, send_rtp_port_range=#{sendRtpPortRange}</if>" +
|
"<if test=\"sendRtpPortRange != null\">, send_rtp_port_range=#{sendRtpPortRange}</if>" +
|
||||||
"<if test=\"secret != null\">, secret=#{secret}</if>" +
|
"<if test=\"secret != null\">, secret=#{secret}</if>" +
|
||||||
"<if test=\"recordAssistPort != null\">, record_assist_port=#{recordAssistPort}</if>" +
|
"<if test=\"recordAssistPort != null\">, record_assist_port=#{recordAssistPort}</if>" +
|
||||||
|
"<if test=\"recordDay != null\">, record_day=#{recordDay}</if>" +
|
||||||
|
"<if test=\"recordPath != null\">, record_path=#{recordPath}</if>" +
|
||||||
"<if test=\"hookAliveInterval != null\">, hook_alive_interval=#{hookAliveInterval}</if>" +
|
"<if test=\"hookAliveInterval != null\">, hook_alive_interval=#{hookAliveInterval}</if>" +
|
||||||
"WHERE ip=#{ip} and http_port=#{httpPort}"+
|
"WHERE ip=#{ip} and http_port=#{httpPort}"+
|
||||||
" </script>"})
|
" </script>"})
|
||||||
@ -130,4 +138,8 @@ public interface MediaServerMapper {
|
|||||||
|
|
||||||
@Select("SELECT * FROM wvp_media_server WHERE default_server=true")
|
@Select("SELECT * FROM wvp_media_server WHERE default_server=true")
|
||||||
MediaServerItem queryDefault();
|
MediaServerItem queryDefault();
|
||||||
|
|
||||||
|
@Select("SELECT * FROM wvp_media_server WHERE record_assist_port > 0")
|
||||||
|
List<MediaServerItem> queryAllWithAssistPort();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,10 @@ public interface PlatformChannelMapper {
|
|||||||
@Select("SELECT dc.* from wvp_platform_gb_channel pgc left join wvp_device_channel dc on dc.id = pgc.device_channel_id WHERE dc.channel_id=#{channelId} and pgc.platform_id=#{platformId}")
|
@Select("SELECT dc.* from wvp_platform_gb_channel pgc left join wvp_device_channel dc on dc.id = pgc.device_channel_id WHERE dc.channel_id=#{channelId} and pgc.platform_id=#{platformId}")
|
||||||
List<DeviceChannel> queryChannelInParentPlatform(@Param("platformId") String platformId, @Param("channelId") String channelId);
|
List<DeviceChannel> queryChannelInParentPlatform(@Param("platformId") String platformId, @Param("channelId") String channelId);
|
||||||
|
|
||||||
@Select("SELECT dc.* from wvp_platform_gb_channel pgc left join wvp_device_channel dc on dc.id = pgc.device_channel_id WHERE pgc.platform_id=#{platformId} and pgc.catalog_id=#{catalogId}")
|
@Select("<script> "+
|
||||||
|
"SELECT dc.* from wvp_platform_gb_channel pgc left join wvp_device_channel dc on dc.id = pgc.device_channel_id WHERE pgc.platform_id=#{platformId} " +
|
||||||
|
" <if test='catalogId != null' > and pgc.catalog_id=#{catalogId}</if>" +
|
||||||
|
"</script>")
|
||||||
List<DeviceChannel> queryAllChannelInCatalog(@Param("platformId") String platformId, @Param("catalogId") String catalogId);
|
List<DeviceChannel> queryAllChannelInCatalog(@Param("platformId") String platformId, @Param("catalogId") String catalogId);
|
||||||
|
|
||||||
@Select(" select dc.channel_id as id, dc.name as name, pgc.platform_id as platform_id, pgc.catalog_id as parent_id, 0 as children_count, 1 as type " +
|
@Select(" select dc.channel_id as id, dc.name as name, pgc.platform_id as platform_id, pgc.catalog_id as parent_id, 0 as children_count, 1 as type " +
|
||||||
|
@ -53,11 +53,14 @@ public interface PlatformGbStreamMapper {
|
|||||||
"WHERE gs.app=#{app} AND gs.stream=#{stream} AND pgs.platform_id=#{platformId}")
|
"WHERE gs.app=#{app} AND gs.stream=#{stream} AND pgs.platform_id=#{platformId}")
|
||||||
StreamProxyItem selectOne(@Param("app") String app, @Param("stream") String stream, @Param("platformId") String platformId);
|
StreamProxyItem selectOne(@Param("app") String app, @Param("stream") String stream, @Param("platformId") String platformId);
|
||||||
|
|
||||||
@Select("select gs.* \n" +
|
@Select("<script> " +
|
||||||
"from wvp_gb_stream gs\n" +
|
"select gs.* " +
|
||||||
|
" from wvp_gb_stream gs\n" +
|
||||||
" left join wvp_platform_gb_stream pgs\n" +
|
" left join wvp_platform_gb_stream pgs\n" +
|
||||||
" on gs.gb_stream_id = pgs.gb_stream_id\n" +
|
" on gs.gb_stream_id = pgs.gb_stream_id\n" +
|
||||||
"where pgs.platform_id=#{platformId} and pgs.catalog_id=#{catalogId}")
|
" where pgs.platform_id=#{platformId} " +
|
||||||
|
" <if test='catalogId != null' > and pgs.catalog_id=#{catalogId}</if>" +
|
||||||
|
"</script>")
|
||||||
List<GbStream> queryChannelInParentPlatformAndCatalog(@Param("platformId") String platformId, @Param("catalogId") String catalogId);
|
List<GbStream> queryChannelInParentPlatformAndCatalog(@Param("platformId") String platformId, @Param("catalogId") String catalogId);
|
||||||
|
|
||||||
@Select("select gs.gb_id as id, gs.name as name, pgs.platform_id as platform_id, pgs.catalog_id as catalog_id , 0 as children_count, 2 as type\n" +
|
@Select("select gs.gb_id as id, gs.name as name, pgs.platform_id as platform_id, pgs.catalog_id as catalog_id , 0 as children_count, 2 as type\n" +
|
||||||
@ -103,6 +106,9 @@ public interface PlatformGbStreamMapper {
|
|||||||
"</script>")
|
"</script>")
|
||||||
void delByAppAndStreamsByPlatformId(@Param("gbStreams") List<GbStream> gbStreams, @Param("platformId") String platformId);
|
void delByAppAndStreamsByPlatformId(@Param("gbStreams") List<GbStream> gbStreams, @Param("platformId") String platformId);
|
||||||
|
|
||||||
@Delete("DELETE from wvp_platform_gb_stream WHERE platform_id=#{platformId} and catalog_id=#{catalogId}")
|
@Delete("<script> "+
|
||||||
|
"DELETE from wvp_platform_gb_stream WHERE platform_id=#{platformId}" +
|
||||||
|
" <if test='catalogId != null' > and catalog_id=#{catalogId}</if>" +
|
||||||
|
"</script>")
|
||||||
int delByPlatformAndCatalogId(@Param("platformId") String platformId, @Param("catalogId") String catalogId);
|
int delByPlatformAndCatalogId(@Param("platformId") String platformId, @Param("catalogId") String catalogId);
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ import java.util.List;
|
|||||||
public interface StreamPushMapper {
|
public interface StreamPushMapper {
|
||||||
|
|
||||||
@Insert("INSERT INTO wvp_stream_push (app, stream, total_reader_count, origin_type, origin_type_str, " +
|
@Insert("INSERT INTO wvp_stream_push (app, stream, total_reader_count, origin_type, origin_type_str, " +
|
||||||
"push_time, alive_second, media_server_id, update_time, create_time, push_ing, self) VALUES" +
|
"push_time, alive_second, media_server_id, server_id, update_time, create_time, push_ing, self) VALUES" +
|
||||||
"(#{app}, #{stream}, #{totalReaderCount}, #{originType}, #{originTypeStr}, " +
|
"(#{app}, #{stream}, #{totalReaderCount}, #{originType}, #{originTypeStr}, " +
|
||||||
"#{pushTime}, #{aliveSecond}, #{mediaServerId} , #{updateTime} , #{createTime}, " +
|
"#{pushTime}, #{aliveSecond}, #{mediaServerId} , #{serverId} , #{updateTime} , #{createTime}, " +
|
||||||
"#{pushIng}, #{self} )")
|
"#{pushIng}, #{self} )")
|
||||||
int add(StreamPushItem streamPushItem);
|
int add(StreamPushItem streamPushItem);
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ public interface StreamPushMapper {
|
|||||||
"UPDATE wvp_stream_push " +
|
"UPDATE wvp_stream_push " +
|
||||||
"SET update_time=#{updateTime}" +
|
"SET update_time=#{updateTime}" +
|
||||||
"<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" +
|
"<if test=\"mediaServerId != null\">, media_server_id=#{mediaServerId}</if>" +
|
||||||
|
"<if test=\"serverId != null\">, server_id=#{serverId}</if>" +
|
||||||
"<if test=\"totalReaderCount != null\">, total_reader_count=#{totalReaderCount}</if>" +
|
"<if test=\"totalReaderCount != null\">, total_reader_count=#{totalReaderCount}</if>" +
|
||||||
"<if test=\"originType != null\">, origin_type=#{originType}</if>" +
|
"<if test=\"originType != null\">, origin_type=#{originType}</if>" +
|
||||||
"<if test=\"originTypeStr != null\">, origin_type_str=#{originTypeStr}</if>" +
|
"<if test=\"originTypeStr != null\">, origin_type_str=#{originTypeStr}</if>" +
|
||||||
@ -89,10 +90,10 @@ public interface StreamPushMapper {
|
|||||||
|
|
||||||
@Insert("<script>" +
|
@Insert("<script>" +
|
||||||
"Insert INTO wvp_stream_push (app, stream, total_reader_count, origin_type, origin_type_str, " +
|
"Insert INTO wvp_stream_push (app, stream, total_reader_count, origin_type, origin_type_str, " +
|
||||||
"create_time, alive_second, media_server_id, status, push_ing) " +
|
"create_time, alive_second, media_server_id, server_id, status, push_ing) " +
|
||||||
"VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" +
|
"VALUES <foreach collection='streamPushItems' item='item' index='index' separator=','>" +
|
||||||
"( #{item.app}, #{item.stream}, #{item.totalReaderCount}, #{item.originType}, " +
|
"( #{item.app}, #{item.stream}, #{item.totalReaderCount}, #{item.originType}, " +
|
||||||
"#{item.originTypeStr},#{item.createTime}, #{item.aliveSecond}, #{item.mediaServerId}, #{item.status} ," +
|
"#{item.originTypeStr},#{item.createTime}, #{item.aliveSecond}, #{item.mediaServerId},#{item.serverId}, #{item.status} ," +
|
||||||
" #{item.pushIng} )" +
|
" #{item.pushIng} )" +
|
||||||
" </foreach>" +
|
" </foreach>" +
|
||||||
"</script>")
|
"</script>")
|
||||||
|
@ -609,14 +609,13 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||||||
@Override
|
@Override
|
||||||
public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) {
|
public void sendDeviceOrChannelStatus(String deviceId, String channelId, boolean online) {
|
||||||
String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS;
|
String key = VideoManagerConstants.VM_MSG_SUBSCRIBE_DEVICE_STATUS;
|
||||||
logger.info("[redis通知] 发送 推送设备/通道状态, {}/{}-{}", deviceId, channelId, online);
|
|
||||||
StringBuilder msg = new StringBuilder();
|
StringBuilder msg = new StringBuilder();
|
||||||
msg.append(deviceId);
|
msg.append(deviceId);
|
||||||
if (channelId != null) {
|
if (channelId != null) {
|
||||||
msg.append(":").append(channelId);
|
msg.append(":").append(channelId);
|
||||||
}
|
}
|
||||||
msg.append(" ").append(online? "ON":"OFF");
|
msg.append(" ").append(online? "ON":"OFF");
|
||||||
logger.info("[redis通知] 推送状态-> {} ", msg);
|
logger.info("[redis通知] 推送设备/通道状态-> {} ", msg);
|
||||||
// 使用 RedisTemplate<Object, Object> 发送字符串消息会导致发送的消息多带了双引号
|
// 使用 RedisTemplate<Object, Object> 发送字符串消息会导致发送的消息多带了双引号
|
||||||
stringRedisTemplate.convertAndSend(key, msg.toString());
|
stringRedisTemplate.convertAndSend(key, msg.toString());
|
||||||
}
|
}
|
||||||
@ -650,4 +649,20 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
|
|||||||
logger.info("[redis发送通知] 发送 上级平台停止观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
|
logger.info("[redis发送通知] 发送 上级平台停止观看 {}: {}/{}->{}", key, msg.getApp(), msg.getStream(), msg.getPlatFormId());
|
||||||
redisTemplate.convertAndSend(key, JSON.toJSON(msg));
|
redisTemplate.convertAndSend(key, JSON.toJSON(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addPushListItem(String app, String stream, OnStreamChangedHookParam param) {
|
||||||
|
String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream;
|
||||||
|
redisTemplate.opsForValue().set(key, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removePushListItem(String app, String stream, String mediaServerId) {
|
||||||
|
String key = VideoManagerConstants.PUSH_STREAM_LIST + app + "_" + stream;
|
||||||
|
OnStreamChangedHookParam param = (OnStreamChangedHookParam)redisTemplate.opsForValue().get(key);
|
||||||
|
if (param != null && param.getMediaServerId().equalsIgnoreCase(mediaServerId)) {
|
||||||
|
redisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.genersoft.iot.vmp.utils;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
|
|
||||||
|
public class CloudRecordUtils {
|
||||||
|
|
||||||
|
public static DownloadFileInfo getDownloadFilePath(MediaServerItem mediaServerItem, String filePath) {
|
||||||
|
DownloadFileInfo downloadFileInfo = new DownloadFileInfo();
|
||||||
|
|
||||||
|
String pathTemplate = "%s://%s:%s/index/api/downloadFile?file_path=" + filePath;
|
||||||
|
|
||||||
|
downloadFileInfo.setHttpPath(String.format(pathTemplate, "http", mediaServerItem.getStreamIp(),
|
||||||
|
mediaServerItem.getHttpPort()));
|
||||||
|
|
||||||
|
if (mediaServerItem.getHttpSSlPort() > 0) {
|
||||||
|
downloadFileInfo.setHttpsPath(String.format(pathTemplate, "https", mediaServerItem.getStreamIp(),
|
||||||
|
mediaServerItem.getHttpSSlPort()));
|
||||||
|
}
|
||||||
|
return downloadFileInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -40,11 +40,17 @@ public class DateUtil {
|
|||||||
*/
|
*/
|
||||||
public static final String URL_PATTERN = "yyyyMMddHHmmss";
|
public static final String URL_PATTERN = "yyyyMMddHHmmss";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期格式
|
||||||
|
*/
|
||||||
|
public static final String date_PATTERN = "yyyy-MM-dd";
|
||||||
|
|
||||||
public static final String zoneStr = "Asia/Shanghai";
|
public static final String zoneStr = "Asia/Shanghai";
|
||||||
|
|
||||||
public static final DateTimeFormatter formatterCompatibleISO8601 = DateTimeFormatter.ofPattern(ISO8601_COMPATIBLE_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
public static final DateTimeFormatter formatterCompatibleISO8601 = DateTimeFormatter.ofPattern(ISO8601_COMPATIBLE_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
||||||
public static final DateTimeFormatter formatterISO8601 = DateTimeFormatter.ofPattern(ISO8601_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
public static final DateTimeFormatter formatterISO8601 = DateTimeFormatter.ofPattern(ISO8601_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
||||||
public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
public static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
||||||
|
public static final DateTimeFormatter DateFormatter = DateTimeFormatter.ofPattern(date_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
||||||
public static final DateTimeFormatter urlFormatter = DateTimeFormatter.ofPattern(URL_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
public static final DateTimeFormatter urlFormatter = DateTimeFormatter.ofPattern(URL_PATTERN, Locale.getDefault()).withZone(ZoneId.of(zoneStr));
|
||||||
|
|
||||||
public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
|
public static String yyyy_MM_dd_HH_mm_ssToISO8601(String formatTime) {
|
||||||
@ -71,6 +77,22 @@ public class DateUtil {
|
|||||||
return instant.getEpochSecond();
|
return instant.getEpochSecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳 转 yyyy_MM_dd_HH_mm_ss
|
||||||
|
*/
|
||||||
|
public static String timestampTo_yyyy_MM_dd_HH_mm_ss(long timestamp) {
|
||||||
|
Instant instant = Instant.ofEpochSecond(timestamp);
|
||||||
|
return formatter.format(LocalDateTime.ofInstant(instant, ZoneId.of(zoneStr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳 转 yyyy_MM_dd
|
||||||
|
*/
|
||||||
|
public static String timestampTo_yyyy_MM_dd(long timestamp) {
|
||||||
|
Instant instant = Instant.ofEpochMilli(timestamp);
|
||||||
|
return DateFormatter.format(LocalDateTime.ofInstant(instant, ZoneId.of(zoneStr)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前时间
|
* 获取当前时间
|
||||||
* @return
|
* @return
|
||||||
@ -117,4 +139,13 @@ public class DateUtil {
|
|||||||
Instant beforeInstant = Instant.from(formatter.parse(keepaliveTime));
|
Instant beforeInstant = Instant.from(formatter.parse(keepaliveTime));
|
||||||
return ChronoUnit.MILLIS.between(beforeInstant, Instant.now());
|
return ChronoUnit.MILLIS.between(beforeInstant, Instant.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getDifference(String startTime, String endTime) {
|
||||||
|
if (ObjectUtils.isEmpty(startTime) || ObjectUtils.isEmpty(endTime)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Instant startInstant = Instant.from(formatter.parse(startTime));
|
||||||
|
Instant endInstant = Instant.from(formatter.parse(endTime));
|
||||||
|
return ChronoUnit.MILLIS.between(endInstant, startInstant);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.vmanager.bean;
|
package com.genersoft.iot.vmp.vmanager.bean;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
@Schema(description = "流信息")
|
@Schema(description = "流信息")
|
||||||
@ -93,6 +94,9 @@ public class StreamContent {
|
|||||||
@Schema(description = "结束时间")
|
@Schema(description = "结束时间")
|
||||||
private String endTime;
|
private String endTime;
|
||||||
|
|
||||||
|
@Schema(description = "文件下载地址(录像下载使用)")
|
||||||
|
private DownloadFileInfo downLoadFilePath;
|
||||||
|
|
||||||
private double progress;
|
private double progress;
|
||||||
|
|
||||||
public StreamContent(StreamInfo streamInfo) {
|
public StreamContent(StreamInfo streamInfo) {
|
||||||
@ -170,6 +174,10 @@ public class StreamContent {
|
|||||||
this.startTime = streamInfo.getStartTime();
|
this.startTime = streamInfo.getStartTime();
|
||||||
this.endTime = streamInfo.getEndTime();
|
this.endTime = streamInfo.getEndTime();
|
||||||
this.progress = streamInfo.getProgress();
|
this.progress = streamInfo.getProgress();
|
||||||
|
|
||||||
|
if (streamInfo.getDownLoadFilePath() != null) {
|
||||||
|
this.downLoadFilePath = streamInfo.getDownLoadFilePath();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getApp() {
|
public String getApp() {
|
||||||
@ -411,4 +419,12 @@ public class StreamContent {
|
|||||||
public void setProgress(double progress) {
|
public void setProgress(double progress) {
|
||||||
this.progress = progress;
|
this.progress = progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DownloadFileInfo getDownLoadFilePath() {
|
||||||
|
return downLoadFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) {
|
||||||
|
this.downLoadFilePath = downLoadFilePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
package com.genersoft.iot.vmp.vmanager.cloudRecord;
|
package com.genersoft.iot.vmp.vmanager.cloudRecord;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||||
import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
|
import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
|
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
|
import com.genersoft.iot.vmp.service.ICloudRecordService;
|
||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
import com.genersoft.iot.vmp.service.IMediaServerService;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.CloudRecordItem;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.RecordFile;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
@ -23,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,28 +37,15 @@ import java.util.List;
|
|||||||
@RequestMapping("/api/cloud/record")
|
@RequestMapping("/api/cloud/record")
|
||||||
public class CloudRecordController {
|
public class CloudRecordController {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ZLMServerFactory zlmServerFactory;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SendRtpPortManager sendRtpPortManager;
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(CloudRecordController.class);
|
private final static Logger logger = LoggerFactory.getLogger(CloudRecordController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ZlmHttpHookSubscribe hookSubscribe;
|
private ICloudRecordService cloudRecordService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IMediaServerService mediaServerService;
|
private IMediaServerService mediaServerService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserSetting userSetting;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DynamicTask dynamicTask;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate<Object, Object> redisTemplate;
|
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@GetMapping("/date/list")
|
@GetMapping("/date/list")
|
||||||
@ -66,8 +56,8 @@ public class CloudRecordController {
|
|||||||
@Parameter(name = "month", description = "月,置空则查询当月", required = false)
|
@Parameter(name = "month", description = "月,置空则查询当月", required = false)
|
||||||
@Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部", required = false)
|
@Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部", required = false)
|
||||||
public List<String> openRtpServer(
|
public List<String> openRtpServer(
|
||||||
@RequestParam String app,
|
@RequestParam(required = true) String app,
|
||||||
@RequestParam String stream,
|
@RequestParam(required = true) String stream,
|
||||||
@RequestParam(required = false) int year,
|
@RequestParam(required = false) int year,
|
||||||
@RequestParam(required = false) int month,
|
@RequestParam(required = false) int month,
|
||||||
@RequestParam(required = false) String mediaServerId
|
@RequestParam(required = false) String mediaServerId
|
||||||
@ -97,26 +87,28 @@ public class CloudRecordController {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return mediaServerService.getRecordDates(app, stream, year, month, mediaServerItems);
|
return cloudRecordService.getDateList(app, stream, year, month, mediaServerItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
@Operation(summary = "分页查询云端录像", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
@Operation(summary = "分页查询云端录像", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@Parameter(name = "app", description = "应用名", required = true)
|
@Parameter(name = "query", description = "检索内容", required = false)
|
||||||
@Parameter(name = "stream", description = "流ID", required = true)
|
@Parameter(name = "app", description = "应用名", required = false)
|
||||||
@Parameter(name = "page", description = "当前页", required = false)
|
@Parameter(name = "stream", description = "流ID", required = false)
|
||||||
@Parameter(name = "count", description = "每页查询数量", required = false)
|
@Parameter(name = "page", description = "当前页", required = true)
|
||||||
@Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = true)
|
@Parameter(name = "count", description = "每页查询数量", required = true)
|
||||||
@Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = true)
|
@Parameter(name = "startTime", description = "开始时间(yyyy-MM-dd HH:mm:ss)", required = false)
|
||||||
|
@Parameter(name = "endTime", description = "结束时间(yyyy-MM-dd HH:mm:ss)", required = false)
|
||||||
@Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false)
|
@Parameter(name = "mediaServerId", description = "流媒体ID,置空则查询全部流媒体", required = false)
|
||||||
public PageInfo<RecordFile> openRtpServer(
|
public PageInfo<CloudRecordItem> openRtpServer(
|
||||||
@RequestParam String app,
|
@RequestParam(required = false) String query,
|
||||||
@RequestParam String stream,
|
@RequestParam(required = false) String app,
|
||||||
|
@RequestParam(required = false) String stream,
|
||||||
@RequestParam int page,
|
@RequestParam int page,
|
||||||
@RequestParam int count,
|
@RequestParam int count,
|
||||||
@RequestParam String startTime,
|
@RequestParam(required = false) String startTime,
|
||||||
@RequestParam String endTime,
|
@RequestParam(required = false) String endTime,
|
||||||
@RequestParam(required = false) String mediaServerId
|
@RequestParam(required = false) String mediaServerId
|
||||||
|
|
||||||
) {
|
) {
|
||||||
@ -135,13 +127,147 @@ public class CloudRecordController {
|
|||||||
mediaServerItems = mediaServerService.getAll();
|
mediaServerItems = mediaServerService.getAll();
|
||||||
}
|
}
|
||||||
if (mediaServerItems.isEmpty()) {
|
if (mediaServerItems.isEmpty()) {
|
||||||
return new PageInfo<>();
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "当前无流媒体");
|
||||||
}
|
}
|
||||||
List<RecordFile> records = mediaServerService.getRecords(app, stream, startTime, endTime, mediaServerItems);
|
if (query != null && ObjectUtils.isEmpty(query.trim())) {
|
||||||
PageInfo<RecordFile> pageInfo = new PageInfo<>(records);
|
query = null;
|
||||||
pageInfo.startPage(page, count);
|
}
|
||||||
return pageInfo;
|
if (app != null && ObjectUtils.isEmpty(app.trim())) {
|
||||||
|
app = null;
|
||||||
|
}
|
||||||
|
if (stream != null && ObjectUtils.isEmpty(stream.trim())) {
|
||||||
|
stream = null;
|
||||||
|
}
|
||||||
|
if (startTime != null && ObjectUtils.isEmpty(startTime.trim())) {
|
||||||
|
startTime = null;
|
||||||
|
}
|
||||||
|
if (endTime != null && ObjectUtils.isEmpty(endTime.trim())) {
|
||||||
|
endTime = null;
|
||||||
|
}
|
||||||
|
return cloudRecordService.getList(page, count, query, app, stream, startTime, endTime, mediaServerItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@GetMapping("/task/add")
|
||||||
|
@Operation(summary = "添加合并任务")
|
||||||
|
@Parameter(name = "app", description = "应用名", required = false)
|
||||||
|
@Parameter(name = "stream", description = "流ID", required = false)
|
||||||
|
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||||
|
@Parameter(name = "startTime", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "endTime", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "callId", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "remoteHost", description = "返回地址时的远程地址", required = false)
|
||||||
|
public String addTask(
|
||||||
|
HttpServletRequest request,
|
||||||
|
@RequestParam(required = false) String app,
|
||||||
|
@RequestParam(required = false) String stream,
|
||||||
|
@RequestParam(required = false) String mediaServerId,
|
||||||
|
@RequestParam(required = false) String startTime,
|
||||||
|
@RequestParam(required = false) String endTime,
|
||||||
|
@RequestParam(required = false) String callId,
|
||||||
|
@RequestParam(required = false) String remoteHost
|
||||||
|
){
|
||||||
|
MediaServerItem mediaServerItem;
|
||||||
|
if (mediaServerId == null) {
|
||||||
|
mediaServerItem = mediaServerService.getDefaultMediaServer();
|
||||||
|
}else {
|
||||||
|
mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||||
|
}
|
||||||
|
if (mediaServerItem == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的流媒体");
|
||||||
|
}else {
|
||||||
|
if (remoteHost == null) {
|
||||||
|
remoteHost = request.getScheme() + "://" + mediaServerItem.getIp() + ":" + mediaServerItem.getRecordAssistPort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cloudRecordService.addTask(app, stream, mediaServerItem, startTime, endTime, callId, remoteHost, mediaServerId != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@GetMapping("/task/list")
|
||||||
|
@Operation(summary = "查询合并任务")
|
||||||
|
@Parameter(name = "taskId", description = "任务Id", required = false)
|
||||||
|
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||||
|
@Parameter(name = "isEnd", description = "是否结束", required = false)
|
||||||
|
public JSONArray queryTaskList(
|
||||||
|
HttpServletRequest request,
|
||||||
|
@RequestParam(required = false) String app,
|
||||||
|
@RequestParam(required = false) String stream,
|
||||||
|
@RequestParam(required = false) String callId,
|
||||||
|
@RequestParam(required = false) String taskId,
|
||||||
|
@RequestParam(required = false) String mediaServerId,
|
||||||
|
@RequestParam(required = false) Boolean isEnd
|
||||||
|
){
|
||||||
|
if (ObjectUtils.isEmpty(mediaServerId)) {
|
||||||
|
mediaServerId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cloudRecordService.queryTask(app, stream, callId, taskId, mediaServerId, isEnd, request.getScheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@GetMapping("/collect/add")
|
||||||
|
@Operation(summary = "添加收藏")
|
||||||
|
@Parameter(name = "app", description = "应用名", required = false)
|
||||||
|
@Parameter(name = "stream", description = "流ID", required = false)
|
||||||
|
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||||
|
@Parameter(name = "startTime", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "endTime", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "callId", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "recordId", description = "录像记录的ID,用于精准收藏一个视频文件", required = false)
|
||||||
|
public int addCollect(
|
||||||
|
@RequestParam(required = false) String app,
|
||||||
|
@RequestParam(required = false) String stream,
|
||||||
|
@RequestParam(required = false) String mediaServerId,
|
||||||
|
@RequestParam(required = false) String startTime,
|
||||||
|
@RequestParam(required = false) String endTime,
|
||||||
|
@RequestParam(required = false) String callId,
|
||||||
|
@RequestParam(required = false) Integer recordId
|
||||||
|
){
|
||||||
|
logger.info("[云端录像] 添加收藏,app={},stream={},mediaServerId={},startTime={},endTime={},callId={},recordId={}",
|
||||||
|
app, stream, mediaServerId, startTime, endTime, callId, recordId);
|
||||||
|
if (recordId != null) {
|
||||||
|
return cloudRecordService.changeCollectById(recordId, true);
|
||||||
|
}else {
|
||||||
|
return cloudRecordService.changeCollect(true, app, stream, mediaServerId, startTime, endTime, callId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@GetMapping("/collect/delete")
|
||||||
|
@Operation(summary = "移除收藏")
|
||||||
|
@Parameter(name = "app", description = "应用名", required = false)
|
||||||
|
@Parameter(name = "stream", description = "流ID", required = false)
|
||||||
|
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||||
|
@Parameter(name = "startTime", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "endTime", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "callId", description = "鉴权ID", required = false)
|
||||||
|
@Parameter(name = "recordId", description = "录像记录的ID,用于精准精准移除一个视频文件的收藏", required = false)
|
||||||
|
public int deleteCollect(
|
||||||
|
@RequestParam(required = false) String app,
|
||||||
|
@RequestParam(required = false) String stream,
|
||||||
|
@RequestParam(required = false) String mediaServerId,
|
||||||
|
@RequestParam(required = false) String startTime,
|
||||||
|
@RequestParam(required = false) String endTime,
|
||||||
|
@RequestParam(required = false) String callId,
|
||||||
|
@RequestParam(required = false) Integer recordId
|
||||||
|
){
|
||||||
|
logger.info("[云端录像] 移除收藏,app={},stream={},mediaServerId={},startTime={},endTime={},callId={},recordId={}",
|
||||||
|
app, stream, mediaServerId, startTime, endTime, callId, recordId);
|
||||||
|
if (recordId != null) {
|
||||||
|
return cloudRecordService.changeCollectById(recordId, false);
|
||||||
|
}else {
|
||||||
|
return cloudRecordService.changeCollect(false, app, stream, mediaServerId, startTime, endTime, callId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@GetMapping("/play/path")
|
||||||
|
@Operation(summary = "获取播放地址")
|
||||||
|
@Parameter(name = "recordId", description = "录像记录的ID", required = true)
|
||||||
|
public DownloadFileInfo getPlayUrlPath(
|
||||||
|
@RequestParam(required = true) Integer recordId
|
||||||
|
){
|
||||||
|
return cloudRecordService.getPlayUrlPath(recordId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public class GbStreamController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public void del(@RequestBody GbStreamParam gbStreamParam){
|
public void del(@RequestBody GbStreamParam gbStreamParam){
|
||||||
|
|
||||||
if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().size() == 0) {
|
if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().isEmpty()) {
|
||||||
if (gbStreamParam.isAll()) {
|
if (gbStreamParam.isAll()) {
|
||||||
gbStreamService.delAllPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId());
|
gbStreamService.delAllPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId());
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ public class GbStreamController {
|
|||||||
@PostMapping(value = "/add")
|
@PostMapping(value = "/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public void add(@RequestBody GbStreamParam gbStreamParam){
|
public void add(@RequestBody GbStreamParam gbStreamParam){
|
||||||
if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().size() == 0) {
|
if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().isEmpty()) {
|
||||||
if (gbStreamParam.isAll()) {
|
if (gbStreamParam.isAll()) {
|
||||||
List<GbStream> allGBChannels = gbStreamService.getAllGBChannels(gbStreamParam.getPlatformId());
|
List<GbStream> allGBChannels = gbStreamService.getAllGBChannels(gbStreamParam.getPlatformId());
|
||||||
gbStreamService.addPlatformInfo(allGBChannels, gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId());
|
gbStreamService.addPlatformInfo(allGBChannels, gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId());
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.genersoft.iot.vmp.vmanager.gb28181.record;
|
package com.genersoft.iot.vmp.vmanager.gb28181.record;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
@ -11,7 +13,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
|||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.service.IDeviceService;
|
import com.genersoft.iot.vmp.service.IDeviceService;
|
||||||
|
import com.genersoft.iot.vmp.service.IInviteStreamService;
|
||||||
import com.genersoft.iot.vmp.service.IPlayService;
|
import com.genersoft.iot.vmp.service.IPlayService;
|
||||||
|
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
|
||||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
import com.genersoft.iot.vmp.utils.DateUtil;
|
import com.genersoft.iot.vmp.utils.DateUtil;
|
||||||
@ -26,6 +30,7 @@ import org.apache.commons.lang3.math.NumberUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -58,6 +63,9 @@ public class GBRecordController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IPlayService playService;
|
private IPlayService playService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IInviteStreamService inviteStreamService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IDeviceService deviceService;
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
//package com.genersoft.iot.vmp.vmanager.record;
|
|
||||||
//
|
|
||||||
//import com.alibaba.fastjson2.JSONObject;
|
|
||||||
//import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
|
|
||||||
//import com.genersoft.iot.vmp.service.IRecordInfoServer;
|
|
||||||
//import com.genersoft.iot.vmp.storager.dao.dto.RecordInfo;
|
|
||||||
//import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
|
||||||
//import com.github.pagehelper.PageInfo;
|
|
||||||
//import io.swagger.annotations.Api;
|
|
||||||
//import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
//import io.swagger.annotations.ApiImplicitParams;
|
|
||||||
//import io.swagger.annotations.ApiOperation;
|
|
||||||
//import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
//import org.springframework.web.bind.annotation.*;
|
|
||||||
//
|
|
||||||
//@Tag(name = "云端录像")
|
|
||||||
//
|
|
||||||
//@RestController
|
|
||||||
//@RequestMapping("/api/record")
|
|
||||||
//public class RecordController {
|
|
||||||
//
|
|
||||||
// @Autowired
|
|
||||||
// private IRecordInfoServer recordInfoServer;
|
|
||||||
//
|
|
||||||
// //@ApiOperation("录像列表查询")
|
|
||||||
// @ApiImplicitParams({
|
|
||||||
// @ApiImplicitParam(name="page", value = "当前页", required = true, dataTypeClass = Integer.class),
|
|
||||||
// @ApiImplicitParam(name="count", value = "每页查询数量", required = true, dataTypeClass = Integer.class),
|
|
||||||
// @ApiImplicitParam(name="query", value = "查询内容", dataTypeClass = String.class),
|
|
||||||
// })
|
|
||||||
// @GetMapping(value = "/app/list")
|
|
||||||
// @ResponseBody
|
|
||||||
// public Object list(@RequestParam(required = false)Integer page,
|
|
||||||
// @RequestParam(required = false)Integer count ){
|
|
||||||
//
|
|
||||||
// PageInfo<RecordInfo> recordList = recordInfoServer.getRecordList(page - 1, page - 1 + count);
|
|
||||||
// return recordList;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //@ApiOperation("获取录像详情")
|
|
||||||
// @ApiImplicitParams({
|
|
||||||
// @ApiImplicitParam(name="recordInfo", value = "录像记录", required = true, dataTypeClass = RecordInfo.class)
|
|
||||||
// })
|
|
||||||
// @GetMapping(value = "/detail")
|
|
||||||
// @ResponseBody
|
|
||||||
// public JSONObject list(RecordInfo recordInfo, String time ){
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -68,6 +68,7 @@ public class ApiDeviceController {
|
|||||||
// if (logger.isDebugEnabled()) {
|
// if (logger.isDebugEnabled()) {
|
||||||
// logger.debug("查询所有视频设备API调用");
|
// logger.debug("查询所有视频设备API调用");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
List<Device> devices;
|
List<Device> devices;
|
||||||
if (start == null || limit ==null) {
|
if (start == null || limit ==null) {
|
||||||
@ -80,7 +81,7 @@ public class ApiDeviceController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JSONArray deviceJSONList = new JSONArray();
|
JSONArray deviceJSONList = new JSONArray();
|
||||||
for (Device device : devices) {
|
devices.stream().forEach(device -> {
|
||||||
JSONObject deviceJsonObject = new JSONObject();
|
JSONObject deviceJsonObject = new JSONObject();
|
||||||
deviceJsonObject.put("ID", device.getDeviceId());
|
deviceJsonObject.put("ID", device.getDeviceId());
|
||||||
deviceJsonObject.put("Name", device.getName());
|
deviceJsonObject.put("Name", device.getName());
|
||||||
@ -99,7 +100,7 @@ public class ApiDeviceController {
|
|||||||
deviceJsonObject.put("UpdatedAt", "");
|
deviceJsonObject.put("UpdatedAt", "");
|
||||||
deviceJsonObject.put("CreatedAt", "");
|
deviceJsonObject.put("CreatedAt", "");
|
||||||
deviceJSONList.add(deviceJsonObject);
|
deviceJSONList.add(deviceJsonObject);
|
||||||
}
|
});
|
||||||
result.put("DeviceList",deviceJSONList);
|
result.put("DeviceList",deviceJSONList);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -114,7 +115,6 @@ public class ApiDeviceController {
|
|||||||
@RequestParam(required = false)String q,
|
@RequestParam(required = false)String q,
|
||||||
@RequestParam(required = false)Boolean online ){
|
@RequestParam(required = false)Boolean online ){
|
||||||
|
|
||||||
|
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
List<DeviceChannelExtend> deviceChannels;
|
List<DeviceChannelExtend> deviceChannels;
|
||||||
List<String> channelIds = null;
|
List<String> channelIds = null;
|
||||||
@ -127,13 +127,19 @@ public class ApiDeviceController {
|
|||||||
deviceChannels = allDeviceChannelList;
|
deviceChannels = allDeviceChannelList;
|
||||||
result.put("ChannelCount", deviceChannels.size());
|
result.put("ChannelCount", deviceChannels.size());
|
||||||
}else {
|
}else {
|
||||||
deviceChannels = storager.queryChannelsByDeviceIdWithStartAndLimit(serial,channelIds, null, null, online,start, limit);
|
if (start > allDeviceChannelList.size()) {
|
||||||
int total = allDeviceChannelList.size();
|
deviceChannels = new ArrayList<>();
|
||||||
result.put("ChannelCount", total);
|
}else {
|
||||||
|
if (start + limit < allDeviceChannelList.size()) {
|
||||||
|
deviceChannels = allDeviceChannelList.subList(start, start + limit);
|
||||||
|
}else {
|
||||||
|
deviceChannels = allDeviceChannelList.subList(start, allDeviceChannelList.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("ChannelCount", allDeviceChannelList.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray channleJSONList = new JSONArray();
|
JSONArray channleJSONList = new JSONArray();
|
||||||
for (DeviceChannelExtend deviceChannelExtend : deviceChannels) {
|
deviceChannels.stream().forEach(deviceChannelExtend -> {
|
||||||
JSONObject deviceJOSNChannel = new JSONObject();
|
JSONObject deviceJOSNChannel = new JSONObject();
|
||||||
deviceJOSNChannel.put("ID", deviceChannelExtend.getChannelId());
|
deviceJOSNChannel.put("ID", deviceChannelExtend.getChannelId());
|
||||||
deviceJOSNChannel.put("DeviceID", deviceChannelExtend.getDeviceId());
|
deviceJOSNChannel.put("DeviceID", deviceChannelExtend.getDeviceId());
|
||||||
@ -166,7 +172,7 @@ public class ApiDeviceController {
|
|||||||
deviceJOSNChannel.put("StreamID", deviceChannelExtend.getStreamId()); // StreamID 直播流ID, 有值表示正在直播
|
deviceJOSNChannel.put("StreamID", deviceChannelExtend.getStreamId()); // StreamID 直播流ID, 有值表示正在直播
|
||||||
deviceJOSNChannel.put("NumOutputs ", -1); // 直播在线人数
|
deviceJOSNChannel.put("NumOutputs ", -1); // 直播在线人数
|
||||||
channleJSONList.add(deviceJOSNChannel);
|
channleJSONList.add(deviceJOSNChannel);
|
||||||
}
|
});
|
||||||
result.put("ChannelList", channleJSONList);
|
result.put("ChannelList", channleJSONList);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public class ApiStreamController {
|
|||||||
result.put("error","device[ " + serial + " ]未找到");
|
result.put("error","device[ " + serial + " ]未找到");
|
||||||
resultDeferredResult.setResult(result);
|
resultDeferredResult.setResult(result);
|
||||||
return resultDeferredResult;
|
return resultDeferredResult;
|
||||||
}else if (device.isOnLine()) {
|
}else if (!device.isOnLine()) {
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
result.put("error","device[ " + code + " ]offline");
|
result.put("error","device[ " + code + " ]offline");
|
||||||
resultDeferredResult.setResult(result);
|
resultDeferredResult.setResult(result);
|
||||||
|
@ -34,18 +34,42 @@ spring:
|
|||||||
poolMaxWait: 5
|
poolMaxWait: 5
|
||||||
# [必选] jdbc数据库配置
|
# [必选] jdbc数据库配置
|
||||||
datasource:
|
datasource:
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
# kingbase配置
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
# type: com.zaxxer.hikari.HikariDataSource
|
||||||
url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
|
# driver-class-name: com.kingbase8.Driver
|
||||||
username: root
|
# url: jdbc:kingbase8://192.168.1.55:54321/wvp?useUnicode=true&characterEncoding=utf8
|
||||||
password: root123
|
# username: system
|
||||||
hikari:
|
# password: system
|
||||||
connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
|
# postgresql配置
|
||||||
initialSize: 10 # 连接池初始化连接数
|
# type: com.zaxxer.hikari.HikariDataSource
|
||||||
maximum-pool-size: 200 # 连接池最大连接数
|
# driver-class-name: org.postgresql.Driver
|
||||||
minimum-idle: 5 # 连接池最小空闲连接数
|
# url: jdbc:postgresql://192.168.1.242:3306/242wvp
|
||||||
idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位)
|
# username: root
|
||||||
max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
|
# password: SYceshizu1234
|
||||||
|
# mysql配置
|
||||||
|
dynamic:
|
||||||
|
primary: master
|
||||||
|
datasource:
|
||||||
|
master:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
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: root123
|
||||||
|
hikari:
|
||||||
|
connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
|
||||||
|
initialSize: 50 # 连接池初始化连接数
|
||||||
|
maximum-pool-size: 200 # 连接池最大连接数
|
||||||
|
minimum-idle: 10 # 连接池最小空闲连接数
|
||||||
|
idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位)
|
||||||
|
max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
|
||||||
|
share:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://127.0.0.1:3306/wvp269_1?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
|
||||||
|
username: root
|
||||||
|
password: 12345678
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 修改分页插件为 postgresql, 数据库类型为mysql不需要
|
# 修改分页插件为 postgresql, 数据库类型为mysql不需要
|
||||||
@ -139,6 +163,10 @@ media:
|
|||||||
auto-config: true
|
auto-config: true
|
||||||
# [可选] zlm服务器的hook.admin_params=secret
|
# [可选] zlm服务器的hook.admin_params=secret
|
||||||
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
|
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
|
||||||
|
# 录像路径
|
||||||
|
record-path: ./www/record
|
||||||
|
# 录像保存时长
|
||||||
|
record-day: 7
|
||||||
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
||||||
rtp:
|
rtp:
|
||||||
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
||||||
@ -182,7 +210,7 @@ user-settings:
|
|||||||
# 使用推流状态作为推流通道状态
|
# 使用推流状态作为推流通道状态
|
||||||
use-pushing-as-status: true
|
use-pushing-as-status: true
|
||||||
# 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启
|
# 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启
|
||||||
use-source-ip-as-stream-ip: true
|
use-source-ip-as-stream-ip: false
|
||||||
# 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
|
# 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放
|
||||||
stream-on-demand: true
|
stream-on-demand: true
|
||||||
# 推流鉴权, 默认开启
|
# 推流鉴权, 默认开启
|
||||||
|
@ -24,18 +24,22 @@ spring:
|
|||||||
timeout: 10000
|
timeout: 10000
|
||||||
# mysql数据源
|
# mysql数据源
|
||||||
datasource:
|
datasource:
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
dynamic:
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
primary: master
|
||||||
url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
|
datasource:
|
||||||
username: root
|
master:
|
||||||
password: root
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
hikari:
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
|
url: jdbc:mysql://127.0.0.1:3306/wvp2?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true
|
||||||
initialSize: 10 # 连接池初始化连接数
|
username: root
|
||||||
maximum-pool-size: 200 # 连接池最大连接数
|
password: root123
|
||||||
minimum-idle: 5 # 连接池最小空闲连接数
|
hikari:
|
||||||
idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位)
|
connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
|
||||||
max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
|
initialSize: 50 # 连接池初始化连接数
|
||||||
|
maximum-pool-size: 200 # 连接池最大连接数
|
||||||
|
minimum-idle: 10 # 连接池最小空闲连接数
|
||||||
|
idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位)
|
||||||
|
max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
|
||||||
#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
||||||
server:
|
server:
|
||||||
port: 18978
|
port: 18978
|
||||||
|
@ -18,13 +18,22 @@ spring:
|
|||||||
timeout: 10000
|
timeout: 10000
|
||||||
# [必选] jdbc数据库配置
|
# [必选] jdbc数据库配置
|
||||||
datasource:
|
datasource:
|
||||||
# 使用mysql 打开23-28行注释, 删除29-36行
|
dynamic:
|
||||||
name: wvp
|
primary: master
|
||||||
url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&allowMultiQueries=true&useSSL=false&allowMultiQueries=true
|
datasource:
|
||||||
username: root
|
master:
|
||||||
password: root
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
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: root123
|
||||||
|
hikari:
|
||||||
|
connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数
|
||||||
|
initialSize: 50 # 连接池初始化连接数
|
||||||
|
maximum-pool-size: 200 # 连接池最大连接数
|
||||||
|
minimum-idle: 10 # 连接池最小空闲连接数
|
||||||
|
idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位)
|
||||||
|
max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位)
|
||||||
|
|
||||||
# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
||||||
server:
|
server:
|
||||||
|
@ -10,7 +10,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin')
|
|||||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||||
const portfinder = require('portfinder')
|
const portfinder = require('portfinder')
|
||||||
|
|
||||||
const HOST = process.env.HOST
|
|
||||||
const PORT = process.env.PORT && Number(process.env.PORT)
|
const PORT = process.env.PORT && Number(process.env.PORT)
|
||||||
|
|
||||||
const devWebpackConfig = merge(baseWebpackConfig, {
|
const devWebpackConfig = merge(baseWebpackConfig, {
|
||||||
@ -31,9 +30,8 @@ const devWebpackConfig = merge(baseWebpackConfig, {
|
|||||||
hot: true,
|
hot: true,
|
||||||
contentBase: false, // since we use CopyWebpackPlugin.
|
contentBase: false, // since we use CopyWebpackPlugin.
|
||||||
compress: true,
|
compress: true,
|
||||||
host: HOST || config.dev.host,
|
host: config.dev.host,
|
||||||
// host:'127.0.0.1',
|
port: config.dev.port,
|
||||||
port: PORT || config.dev.port,
|
|
||||||
open: config.dev.autoOpenBrowser,
|
open: config.dev.autoOpenBrowser,
|
||||||
overlay: config.dev.errorOverlay
|
overlay: config.dev.errorOverlay
|
||||||
? { warnings: false, errors: true }
|
? { warnings: false, errors: true }
|
||||||
|
26485
web_src/package-lock.json
generated
26485
web_src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,207 +1,281 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" style="width: 100%">
|
<div id="app" style="width: 100%">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div class="page-title">
|
<div class="page-title">
|
||||||
<el-page-header v-if="recordDetail" @back="backToList" content="云端录像"></el-page-header>
|
<div >云端录像</div>
|
||||||
<div v-if="!recordDetail">云端录像</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page-header-btn">
|
<div class="page-header-btn">
|
||||||
|
搜索:
|
||||||
|
<el-input @input="getMediaServerList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
|
||||||
|
prefix-icon="el-icon-search" v-model="search" clearable></el-input>
|
||||||
|
开始时间:
|
||||||
|
<el-date-picker
|
||||||
|
v-model="startTime"
|
||||||
|
type="datetime"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
@change="getMediaServerList"
|
||||||
|
placeholder="选择日期时间">
|
||||||
|
</el-date-picker>
|
||||||
|
结束时间:
|
||||||
|
<el-date-picker
|
||||||
|
v-model="endTime"
|
||||||
|
type="datetime"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
@change="getMediaServerList"
|
||||||
|
placeholder="选择日期时间">
|
||||||
|
</el-date-picker>
|
||||||
节点选择:
|
节点选择:
|
||||||
<el-select size="mini" @change="chooseMediaChange" style="width: 16rem; margin-right: 1rem;" v-model="mediaServerId" placeholder="请选择" :disabled="recordDetail">
|
<el-select size="mini" @change="getMediaServerList" style="width: 16rem; margin-right: 1rem;"
|
||||||
|
v-model="mediaServerId" placeholder="请选择" >
|
||||||
|
<el-option label="全部" value=""></el-option>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in mediaServerList"
|
v-for="item in mediaServerList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.id"
|
:label="item.id"
|
||||||
:value="item.id">
|
:value="item.id">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-button v-if="!recordDetail" icon="el-icon-refresh-right" circle size="mini" :loading="loading" @click="getRecordList()"></el-button>
|
<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord()">批量删除</el-button>-->
|
||||||
|
<el-button icon="el-icon-refresh-right" circle size="mini" :loading="loading"
|
||||||
|
@click="getRecordList()"></el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!recordDetail">
|
<!--设备列表-->
|
||||||
|
<el-table :data="recordList" style="width: 100%" :height="winHeight">
|
||||||
<!--设备列表-->
|
<el-table-column
|
||||||
<el-table :data="recordList" style="width: 100%" :height="winHeight">
|
type="selection"
|
||||||
<el-table-column prop="app" label="应用名" >
|
width="55">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="stream" label="流ID" >
|
<el-table-column prop="app" label="应用名">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="time" label="时间" >
|
<el-table-column prop="stream" label="流ID" width="380">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="360" fixed="right">
|
<el-table-column label="开始时间">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button size="medium" icon="el-icon-folder-opened" type="text" @click="showRecordDetail(scope.row)">查看</el-button>
|
{{formatTimeStamp(scope.row.startTime)}}
|
||||||
<!-- <el-button size="mini" icon="el-icon-delete" type="danger" @click="deleteRecord(scope.row)">删除</el-button>-->
|
</template>
|
||||||
</template>
|
</el-table-column>
|
||||||
</el-table-column>
|
<el-table-column label="结束时间">
|
||||||
</el-table>
|
<template slot-scope="scope">
|
||||||
<el-pagination
|
{{formatTimeStamp(scope.row.endTime)}}
|
||||||
style="float: right"
|
</template>
|
||||||
@size-change="handleSizeChange"
|
</el-table-column>
|
||||||
@current-change="currentChange"
|
<el-table-column label="时长">
|
||||||
:current-page="currentPage"
|
<template slot-scope="scope">
|
||||||
:page-size="count"
|
<el-tag>{{formatTime(scope.row.timeLen)}}</el-tag>
|
||||||
:page-sizes="[15, 25, 35, 50]"
|
</template>
|
||||||
layout="total, sizes, prev, pager, next"
|
</el-table-column>
|
||||||
:total="total">
|
<el-table-column prop="fileName" label="文件名称">
|
||||||
</el-pagination>
|
</el-table-column>
|
||||||
</div>
|
<el-table-column prop="mediaServerId" label="流媒体">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="200" fixed="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button size="medium" icon="el-icon-video-play" type="text" @click="play(scope.row)">播放
|
||||||
|
</el-button>
|
||||||
|
<!-- <el-button size="medium" icon="el-icon-delete" type="text" style="color: #f56c6c"-->
|
||||||
|
<!-- @click="deleteRecord(scope.row)">删除-->
|
||||||
|
<!-- </el-button>-->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination
|
||||||
|
style="float: right"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="currentChange"
|
||||||
|
:current-page="currentPage"
|
||||||
|
:page-size="count"
|
||||||
|
:page-sizes="[15, 25, 35, 50]"
|
||||||
|
layout="total, sizes, prev, pager, next"
|
||||||
|
:total="total">
|
||||||
|
</el-pagination>
|
||||||
|
<el-dialog
|
||||||
|
:title="playerTitle"
|
||||||
|
:visible.sync="showPlayer"
|
||||||
|
width="50%">
|
||||||
|
<easyPlayer ref="recordVideoPlayer" :videoUrl="videoUrl" :height="false" ></easyPlayer>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uiHeader from '../layout/UiHeader.vue'
|
import uiHeader from '../layout/UiHeader.vue'
|
||||||
import MediaServer from './service/MediaServer'
|
import MediaServer from './service/MediaServer'
|
||||||
export default {
|
import easyPlayer from './common/easyPlayer.vue'
|
||||||
name: 'app',
|
import moment from 'moment'
|
||||||
components: {
|
import axios from "axios";
|
||||||
uiHeader
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
mediaServerList: [], // 滅体节点列表
|
|
||||||
mediaServerId: null, // 媒体服务
|
|
||||||
mediaServerPath: null, // 媒体服务地址
|
|
||||||
recordList: [], // 设备列表
|
|
||||||
chooseRecord: null, // 媒体服务
|
|
||||||
|
|
||||||
updateLooper: 0, //数据刷新轮训标志
|
export default {
|
||||||
winHeight: window.innerHeight - 250,
|
name: 'app',
|
||||||
currentPage:1,
|
components: {
|
||||||
count:15,
|
uiHeader,easyPlayer
|
||||||
total:0,
|
},
|
||||||
loading: false,
|
data() {
|
||||||
mediaServerObj : new MediaServer(),
|
return {
|
||||||
recordDetail: false
|
search: '',
|
||||||
|
startTime: '',
|
||||||
|
endTime: '',
|
||||||
|
showPlayer: false,
|
||||||
|
playerTitle: '',
|
||||||
|
videoUrl: '',
|
||||||
|
playerStyle: {
|
||||||
|
"margin": "auto",
|
||||||
|
"margin-bottom": "20px",
|
||||||
|
"width": window.innerWidth/2 + "px",
|
||||||
|
"height": this.winHeight/2 + "px",
|
||||||
|
},
|
||||||
|
mediaServerList: [], // 滅体节点列表
|
||||||
|
mediaServerId: "", // 媒体服务
|
||||||
|
mediaServerPath: null, // 媒体服务地址
|
||||||
|
recordList: [], // 设备列表
|
||||||
|
chooseRecord: null, // 媒体服务
|
||||||
|
|
||||||
};
|
updateLooper: 0, //数据刷新轮训标志
|
||||||
},
|
winHeight: window.innerHeight - 250,
|
||||||
computed: {
|
currentPage: 1,
|
||||||
|
count: 15,
|
||||||
|
total: 0,
|
||||||
|
loading: false,
|
||||||
|
mediaServerObj: new MediaServer(),
|
||||||
|
|
||||||
},
|
};
|
||||||
mounted() {
|
},
|
||||||
this.initData();
|
computed: {},
|
||||||
},
|
mounted() {
|
||||||
destroyed() {
|
this.initData();
|
||||||
// this.$destroy('videojs');
|
},
|
||||||
},
|
destroyed() {
|
||||||
methods: {
|
this.$destroy('recordVideoPlayer');
|
||||||
initData: function() {
|
},
|
||||||
// 获取媒体节点列表
|
methods: {
|
||||||
this.getMediaServerList();
|
initData: function () {
|
||||||
// this.getRecordList();
|
// 获取媒体节点列表
|
||||||
},
|
this.getMediaServerList();
|
||||||
currentChange: function(val){
|
this.getRecordList();
|
||||||
this.currentPage = val;
|
},
|
||||||
this.getRecordList();
|
currentChange: function (val) {
|
||||||
},
|
this.currentPage = val;
|
||||||
handleSizeChange: function(val){
|
this.getRecordList();
|
||||||
this.count = val;
|
},
|
||||||
this.getRecordList();
|
handleSizeChange: function (val) {
|
||||||
},
|
this.count = val;
|
||||||
getMediaServerList: function (){
|
this.getRecordList();
|
||||||
let that = this;
|
},
|
||||||
that.mediaServerObj.getOnlineMediaServerList((data)=>{
|
getMediaServerList: function () {
|
||||||
that.mediaServerList = data.data;
|
let that = this;
|
||||||
if (that.mediaServerList.length > 0) {
|
that.mediaServerObj.getOnlineMediaServerList((data) => {
|
||||||
that.mediaServerId = that.mediaServerList[0].id
|
that.mediaServerList = data.data;
|
||||||
that.setMediaServerPath(that.mediaServerId);
|
})
|
||||||
that.getRecordList();
|
},
|
||||||
}
|
setMediaServerPath: function (serverId) {
|
||||||
})
|
let that = this;
|
||||||
},
|
let i;
|
||||||
setMediaServerPath: function (serverId) {
|
for (i = 0; i < that.mediaServerList.length; i++) {
|
||||||
let that = this;
|
if (serverId === that.mediaServerList[i].id) {
|
||||||
let i;
|
break;
|
||||||
for (i = 0; i < that.mediaServerList.length; i++) {
|
|
||||||
if (serverId === that.mediaServerList[i].id) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let port = that.mediaServerList[i].httpPort;
|
}
|
||||||
if (location.protocol === "https:" && that.mediaServerList[i].httpSSlPort) {
|
let port = that.mediaServerList[i].httpPort;
|
||||||
port = that.mediaServerList[i].httpSSlPort
|
if (location.protocol === "https:" && that.mediaServerList[i].httpSSlPort) {
|
||||||
|
port = that.mediaServerList[i].httpSSlPort
|
||||||
|
}
|
||||||
|
that.mediaServerPath = location.protocol + "//" + that.mediaServerList[i].streamIp + ":" + port
|
||||||
|
console.log(that.mediaServerPath)
|
||||||
|
},
|
||||||
|
getRecordList: function () {
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/cloud/record/list`,
|
||||||
|
params: {
|
||||||
|
app: '',
|
||||||
|
stream: '',
|
||||||
|
query: this.search,
|
||||||
|
startTime: this.startTime,
|
||||||
|
endTime: this.endTime,
|
||||||
|
mediaServerId: this.mediaServerId,
|
||||||
|
page: this.currentPage,
|
||||||
|
count: this.count
|
||||||
}
|
}
|
||||||
that.mediaServerPath = location.protocol + "//" + that.mediaServerList[i].streamIp + ":" + port
|
}).then((res) => {
|
||||||
console.log(that.mediaServerPath)
|
console.log(res)
|
||||||
},
|
if (res.data.code === 0) {
|
||||||
getRecordList: function (){
|
this.total = res.data.data.total;
|
||||||
let that = this;
|
this.recordList = res.data.data.list;
|
||||||
this.$axios({
|
}
|
||||||
method: 'get',
|
this.loading = false;
|
||||||
url:`/record_proxy/${that.mediaServerId}/api/record/list`,
|
}).catch((error) => {
|
||||||
params: {
|
console.log(error);
|
||||||
page: that.currentPage,
|
this.loading = false;
|
||||||
count: that.count
|
});
|
||||||
|
},
|
||||||
|
play(row) {
|
||||||
|
console.log(row)
|
||||||
|
this.chooseRecord = row;
|
||||||
|
this.showPlayer = true;
|
||||||
|
this.$axios({
|
||||||
|
method: 'get',
|
||||||
|
url: `/api/cloud/record/play/path`,
|
||||||
|
params: {
|
||||||
|
recordId: row.id,
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
if (location.protocol === "https:") {
|
||||||
|
this.videoUrl = res.data.data.httpsPath;
|
||||||
|
}else {
|
||||||
|
this.videoUrl = res.data.data.httpPath;
|
||||||
}
|
}
|
||||||
}).then(function (res) {
|
console.log(222 )
|
||||||
console.log(res)
|
console.log(this.videoUrl )
|
||||||
if (res.data.code === 0) {
|
}
|
||||||
that.total = res.data.data.total;
|
}).catch((error) => {
|
||||||
that.recordList = res.data.data.list;
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getFileBasePath(item) {
|
||||||
|
let basePath = ""
|
||||||
|
if (axios.defaults.baseURL.startsWith("http")) {
|
||||||
|
basePath = `${axios.defaults.baseURL}/record_proxy/${item.mediaServerId}`
|
||||||
|
}else {
|
||||||
|
basePath = `${window.location.origin}${axios.defaults.baseURL}/record_proxy/${item.mediaServerId}`
|
||||||
}
|
}
|
||||||
that.loading = false;
|
return basePath;
|
||||||
}).catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
that.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
backToList(){
|
|
||||||
this.recordDetail= false;
|
|
||||||
},
|
|
||||||
chooseMediaChange(val){
|
|
||||||
console.log(val)
|
|
||||||
this.total = 0;
|
|
||||||
this.recordList = [];
|
|
||||||
this.setMediaServerPath(val);
|
|
||||||
this.getRecordList();
|
|
||||||
},
|
|
||||||
showRecordDetail(row){
|
|
||||||
this.recordDetail = true;
|
|
||||||
this.chooseRecord = row;
|
|
||||||
// 查询是否存在录像
|
|
||||||
// this.$axios({
|
|
||||||
// method: 'delete',
|
|
||||||
// url:`/record_proxy/api/record/delete`,
|
|
||||||
// params: {
|
|
||||||
// page: this.currentPage,
|
|
||||||
// count: this.count
|
|
||||||
// }
|
|
||||||
// }).then((res) => {
|
|
||||||
// console.log(res)
|
|
||||||
// this.total = res.data.data.total;
|
|
||||||
// this.recordList = res.data.data.list;
|
|
||||||
// }).catch(function (error) {
|
|
||||||
// console.log(error);
|
|
||||||
// });
|
|
||||||
this.$router.push(`/cloudRecordDetail/${row.app}/${row.stream}`)
|
|
||||||
},
|
|
||||||
deleteRecord(){
|
|
||||||
// TODO
|
|
||||||
let that = this;
|
|
||||||
this.$axios({
|
|
||||||
method: 'delete',
|
|
||||||
url:`/record_proxy/api/record/delete`,
|
|
||||||
params: {
|
|
||||||
page: that.currentPage,
|
|
||||||
count: that.count
|
|
||||||
}
|
|
||||||
}).then(function (res) {
|
|
||||||
console.log(res)
|
|
||||||
if (res.data.code === 0) {
|
|
||||||
that.total = res.data.data.total;
|
|
||||||
that.recordList = res.data.data.list;
|
|
||||||
}
|
|
||||||
}).catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
deleteRecord() {
|
||||||
|
// TODO
|
||||||
|
let that = this;
|
||||||
|
this.$axios({
|
||||||
|
method: 'delete',
|
||||||
|
url: `/record_proxy/api/record/delete`,
|
||||||
|
params: {
|
||||||
|
page: that.currentPage,
|
||||||
|
count: that.count
|
||||||
|
}
|
||||||
|
}).then(function (res) {
|
||||||
|
console.log(res)
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
that.total = res.data.data.total;
|
||||||
|
that.recordList = res.data.data.list;
|
||||||
|
}
|
||||||
|
}).catch(function (error) {
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formatTime(time) {
|
||||||
|
const h = parseInt(time / 3600)
|
||||||
|
const minute = parseInt(time / 60 % 60)
|
||||||
|
const second = Math.ceil(time % 60)
|
||||||
|
|
||||||
|
return (h > 0 ? h + `小时` : '') + (minute > 0 ? minute + '分' : '') + second + '秒'
|
||||||
|
},
|
||||||
|
formatTimeStamp(time) {
|
||||||
|
return moment.unix(time).format('yyyy-MM-DD HH:mm:ss')
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -37,13 +37,13 @@
|
|||||||
<div class="record-list-box" :style="recordListStyle">
|
<div class="record-list-box" :style="recordListStyle">
|
||||||
<ul v-if="detailFiles.length >0" class="infinite-list record-list" v-infinite-scroll="infiniteScroll" >
|
<ul v-if="detailFiles.length >0" class="infinite-list record-list" v-infinite-scroll="infiniteScroll" >
|
||||||
<li v-for="(item,index) in detailFiles" :key="index" 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.filename" @click="chooseFile(item)">
|
<el-tag v-if="choosedFile !== item.fileName" @click="chooseFile(item)">
|
||||||
<i class="el-icon-video-camera" ></i>
|
<i class="el-icon-video-camera" ></i>
|
||||||
{{ getFileShowName(item.fileName) }}
|
{{ getFileShowName(item) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag type="danger" v-if="choosedFile === item.filename">
|
<el-tag type="danger" v-if="choosedFile === item.fileName">
|
||||||
<i class="el-icon-video-camera" ></i>
|
<i class="el-icon-video-camera" ></i>
|
||||||
{{ getFileShowName(item.fileName) }}
|
{{ getFileShowName(item) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<a class="el-icon-download" style="color: #409EFF;font-weight: 600;margin-left: 10px;"
|
<a class="el-icon-download" style="color: #409EFF;font-weight: 600;margin-left: 10px;"
|
||||||
:href="`${getFileBasePath(item)}/download.html?url=download/${app}/${stream}/${chooseDate}/${item.fileName}`"
|
:href="`${getFileBasePath(item)}/download.html?url=download/${app}/${stream}/${chooseDate}/${item.fileName}`"
|
||||||
@ -135,7 +135,7 @@
|
|||||||
<script>
|
<script>
|
||||||
// TODO 根据查询的时间列表设置滑轨的最大值与最小值,
|
// TODO 根据查询的时间列表设置滑轨的最大值与最小值,
|
||||||
import uiHeader from '../layout/UiHeader.vue'
|
import uiHeader from '../layout/UiHeader.vue'
|
||||||
import player from './dialog/easyPlayer.vue'
|
import player from './common/easyPlayer.vue'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
export default {
|
export default {
|
||||||
@ -319,7 +319,7 @@
|
|||||||
this.choosedFile = "";
|
this.choosedFile = "";
|
||||||
}else {
|
}else {
|
||||||
this.choosedFile = file.fileName;
|
this.choosedFile = file.fileName;
|
||||||
this.videoUrl = `${this.getFileBasePath(file)}/download/${this.app}/${this.stream}/${this.chooseDate}/${this.choosedFile}`
|
this.videoUrl = `${this.getFileBasePath(file)}/download/${this.app}/${this.stream}/${this.chooseDate}/${file.fileName}`
|
||||||
console.log(this.videoUrl)
|
console.log(this.videoUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,9 +327,8 @@
|
|||||||
backToList() {
|
backToList() {
|
||||||
this.$router.back()
|
this.$router.back()
|
||||||
},
|
},
|
||||||
getFileShowName(name) {
|
getFileShowName(item) {
|
||||||
return name.substring(0, 2) + ":" + name.substring(2, 4) + ":" + name.substring(4, 6) + "-" +
|
return moment.unix(item.startTime).format('HH:mm:ss') + "-" + moment.unix(item.endTime).format('HH:mm:ss')
|
||||||
name.substring(7, 9) + ":" + name.substring(9, 11) + ":" + name.substring(11, 13)
|
|
||||||
},
|
},
|
||||||
chooseMediaChange() {
|
chooseMediaChange() {
|
||||||
|
|
||||||
@ -376,13 +375,8 @@
|
|||||||
},
|
},
|
||||||
getTimeForFile(file){
|
getTimeForFile(file){
|
||||||
console.log(file)
|
console.log(file)
|
||||||
let timeStr = file.fileName.substring(0, 17);
|
let starTime = new Date(file.startTime * 1000);
|
||||||
if(timeStr.indexOf("~") > 0){
|
let endTime = new Date(file.endTime * 1000);
|
||||||
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)){
|
if(this.checkIsOver24h(starTime,endTime)){
|
||||||
endTime = new Date(this.chooseDate + " " + "23:59:59");
|
endTime = new Date(this.chooseDate + " " + "23:59:59");
|
||||||
}
|
}
|
||||||
@ -486,12 +480,13 @@
|
|||||||
let that = this;
|
let that = this;
|
||||||
this.$axios({
|
this.$axios({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url:`/record_proxy/${that.mediaServerId}/api/record/file/download/task/add`,
|
url:`/api/cloud/record/task/add`,
|
||||||
params: {
|
params: {
|
||||||
app: that.app,
|
app: this.app,
|
||||||
stream: that.stream,
|
stream: this.stream,
|
||||||
startTime: moment(this.taskTimeRange[0]).format('YYYY-MM-DD HH:mm:ss'),
|
mediaServerId: this.mediaServerId,
|
||||||
endTime: moment(this.taskTimeRange[1]).format('YYYY-MM-DD HH:mm:ss'),
|
startTime: moment(this.taskTimeRange[0]).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
endTime: moment(this.taskTimeRange[1]).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
}
|
}
|
||||||
}).then(function (res) {
|
}).then(function (res) {
|
||||||
if (res.data.code === 0 ) {
|
if (res.data.code === 0 ) {
|
||||||
@ -511,8 +506,9 @@
|
|||||||
let that = this;
|
let that = this;
|
||||||
this.$axios({
|
this.$axios({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url:`/record_proxy/${that.mediaServerId}/api/record/file/download/task/list`,
|
url:`/api/cloud/record/task/list`,
|
||||||
params: {
|
params: {
|
||||||
|
mediaServerId: this.mediaServerId,
|
||||||
isEnd: isEnd,
|
isEnd: isEnd,
|
||||||
}
|
}
|
||||||
}).then(function (res) {
|
}).then(function (res) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="easyplayer"></div>
|
<div id="easyplayer" ></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="container" @dblclick="fullscreenSwich"
|
<div ref="container" @dblclick="fullscreenSwich"
|
||||||
style="width:100%;height:100%;background-color: #000000;margin:0 auto;position: relative;">
|
style="width:100%;height:100%;min-height: 200px;background-color: #000000;margin:0 auto;position: relative;">
|
||||||
<div class="buttons-box" id="buttonsBox">
|
<div class="buttons-box" id="buttonsBox">
|
||||||
<div class="buttons-box-left">
|
<div class="buttons-box-left">
|
||||||
<i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
|
<i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
|
||||||
@ -80,9 +80,10 @@ export default {
|
|||||||
height = clientHeight
|
height = clientHeight
|
||||||
width = (16 / 9) * height
|
width = (16 / 9) * height
|
||||||
}
|
}
|
||||||
|
if (width > 0 && height > 0) {
|
||||||
dom.style.width = width + 'px';
|
dom.style.width = width + 'px';
|
||||||
dom.style.height = height + "px";
|
dom.style.height = height + "px";
|
||||||
|
}
|
||||||
},
|
},
|
||||||
create() {
|
create() {
|
||||||
let options = {
|
let options = {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<el-input v-model="form.name" clearable></el-input>
|
<el-input v-model="form.name" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="密码" prop="password">
|
<el-form-item label="密码" prop="password">
|
||||||
<el-input type="password" v-model="form.password" clearable></el-input>
|
<el-input v-model="form.password" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="收流IP" prop="sdpIp">
|
<el-form-item label="收流IP" prop="sdpIp">
|
||||||
<el-input type="sdpIp" v-model="form.sdpIp" clearable></el-input>
|
<el-input type="sdpIp" v-model="form.sdpIp" clearable></el-input>
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
<el-progress :percentage="percentage"></el-progress>
|
<el-progress :percentage="percentage"></el-progress>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6" >
|
<el-col :span="6" >
|
||||||
<el-button icon="el-icon-download" v-if="percentage < 100" size="mini" title="点击下载可将以缓存部分下载到本地" @click="download()">停止缓存并下载</el-button>
|
<el-button icon="el-icon-download" v-if="downloadFile" size="mini" title="点击下载" @click="downloadFileClientEvent()">下载</el-button>
|
||||||
<el-button icon="el-icon-download" v-if="downloadFile" size="mini" title="点击下载" @click="downloadFileClientEvent()">点击下载</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -27,7 +26,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: "四倍速下载中...",
|
title: "下载中...",
|
||||||
deviceId: "",
|
deviceId: "",
|
||||||
channelId: "",
|
channelId: "",
|
||||||
app: "",
|
app: "",
|
||||||
@ -39,7 +38,6 @@ export default {
|
|||||||
streamInfo: null,
|
streamInfo: null,
|
||||||
taskId: null,
|
taskId: null,
|
||||||
getProgressRun: false,
|
getProgressRun: false,
|
||||||
getProgressForFileRun: false,
|
|
||||||
timer: null,
|
timer: null,
|
||||||
downloadFile: null,
|
downloadFile: null,
|
||||||
|
|
||||||
@ -62,7 +60,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.percentage == 100 ) {
|
if (this.percentage == 100 ) {
|
||||||
this.getFileDownload();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTimeout( ()=>{
|
setTimeout( ()=>{
|
||||||
@ -75,7 +73,6 @@ export default {
|
|||||||
method: 'get',
|
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)=> {
|
}).then((res)=> {
|
||||||
console.log(res)
|
|
||||||
if (res.data.code === 0) {
|
if (res.data.code === 0) {
|
||||||
this.streamInfo = res.data.data;
|
this.streamInfo = res.data.data;
|
||||||
if (parseFloat(res.data.progress) == 1) {
|
if (parseFloat(res.data.progress) == 1) {
|
||||||
@ -83,6 +80,15 @@ export default {
|
|||||||
}else {
|
}else {
|
||||||
this.percentage = (parseFloat(res.data.data.progress)*100).toFixed(1);
|
this.percentage = (parseFloat(res.data.data.progress)*100).toFixed(1);
|
||||||
}
|
}
|
||||||
|
if (this.streamInfo.downLoadFilePath) {
|
||||||
|
if (location.protocol === "https:") {
|
||||||
|
this.downloadFile = this.streamInfo.downLoadFilePath.httpsPath;
|
||||||
|
}else {
|
||||||
|
this.downloadFile = this.streamInfo.downLoadFilePath.httpPath;
|
||||||
|
}
|
||||||
|
this.getProgressRun = false;
|
||||||
|
this.downloadFileClientEvent()
|
||||||
|
}
|
||||||
if (callback)callback();
|
if (callback)callback();
|
||||||
}else {
|
}else {
|
||||||
this.$message({
|
this.$message({
|
||||||
@ -108,24 +114,11 @@ export default {
|
|||||||
}
|
}
|
||||||
this.showDialog=false;
|
this.showDialog=false;
|
||||||
this.getProgressRun = false;
|
this.getProgressRun = false;
|
||||||
this.getProgressForFileRun = false;
|
|
||||||
},
|
},
|
||||||
gbScale: function (scale){
|
gbScale: function (scale){
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
},
|
},
|
||||||
download: function (){
|
|
||||||
this.getProgressRun = false;
|
|
||||||
if (this.streamInfo != null ) {
|
|
||||||
if (this.streamInfo.progress < 1) {
|
|
||||||
// 发送停止缓存
|
|
||||||
this.stopDownloadRecord((res)=>{
|
|
||||||
this.getFileDownload()
|
|
||||||
})
|
|
||||||
}else {
|
|
||||||
this.getFileDownload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stopDownloadRecord: function (callback) {
|
stopDownloadRecord: function (callback) {
|
||||||
this.$axios({
|
this.$axios({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
@ -134,74 +127,20 @@ export default {
|
|||||||
if (callback) callback(res)
|
if (callback) callback(res)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getFileDownload: function (){
|
|
||||||
this.$axios({
|
|
||||||
method: 'get',
|
|
||||||
url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/add`,
|
|
||||||
params: {
|
|
||||||
app: this.app,
|
|
||||||
stream: this.stream,
|
|
||||||
startTime: null,
|
|
||||||
endTime: null,
|
|
||||||
}
|
|
||||||
}).then((res) =>{
|
|
||||||
if (res.data.code === 0 ) {
|
|
||||||
// 查询进度
|
|
||||||
this.title = "录像文件处理中..."
|
|
||||||
this.taskId = res.data.data;
|
|
||||||
this.percentage = 0.0;
|
|
||||||
this.getProgressForFileRun = true;
|
|
||||||
this.getProgressForFileTimer();
|
|
||||||
}
|
|
||||||
}).catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getProgressForFileTimer: function (){
|
|
||||||
if (!this.getProgressForFileRun || this.percentage == 100) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setTimeout( ()=>{
|
|
||||||
if (!this.showDialog) return;
|
|
||||||
this.getProgressForFile(this.getProgressForFileTimer)
|
|
||||||
}, 1000)
|
|
||||||
},
|
|
||||||
getProgressForFile: function (callback){
|
|
||||||
this.$axios({
|
|
||||||
method: 'get',
|
|
||||||
url:`/record_proxy/${this.mediaServerId}/api/record/file/download/task/list`,
|
|
||||||
params: {
|
|
||||||
app: this.app,
|
|
||||||
stream: this.stream,
|
|
||||||
taskId: this.taskId,
|
|
||||||
isEnd: true,
|
|
||||||
}
|
|
||||||
}).then((res) => {
|
|
||||||
console.log(res)
|
|
||||||
if (res.data.code === 0) {
|
|
||||||
if (res.data.data.length === 0){
|
|
||||||
this.percentage = 0
|
|
||||||
// 往往在多次请求后(实验五分钟的视频是三次请求),才会返回数据,第一次请求通常是返回空数组
|
|
||||||
if (callback)callback()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// res.data.data应是数组类型
|
|
||||||
this.percentage = parseFloat(res.data.data[0].percentage)*100
|
|
||||||
if (res.data.data[0].percentage === '1') {
|
|
||||||
this.getProgressForFileRun = false;
|
|
||||||
this.downloadFile = res.data.data[0].downloadFile
|
|
||||||
this.title = "文件处理完成,点击按扭下载"
|
|
||||||
// window.open(res.data.data[0].downloadFile)
|
|
||||||
}else {
|
|
||||||
if (callback)callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch(function (error) {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
downloadFileClientEvent: function (){
|
downloadFileClientEvent: function (){
|
||||||
window.open(this.downloadFile )
|
// window.open(this.downloadFile )
|
||||||
|
|
||||||
|
let x = new XMLHttpRequest();
|
||||||
|
x.open("GET", this.downloadFile, true);
|
||||||
|
x.responseType = 'blob';
|
||||||
|
x.onload=(e)=> {
|
||||||
|
let url = window.URL.createObjectURL(x.response)
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url
|
||||||
|
a.download = this.deviceId + "-" + this.channelId + ".mp4";
|
||||||
|
a.click()
|
||||||
|
}
|
||||||
|
x.send();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
|
0
web_src/static/js/jessibuca/decoder.wasm
Normal file → Executable file
0
web_src/static/js/jessibuca/decoder.wasm
Normal file → Executable file
File diff suppressed because one or more lines are too long
63
打包/config/assist-application.yml
Executable file
63
打包/config/assist-application.yml
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
spring:
|
||||||
|
# REDIS数据库配置
|
||||||
|
redis:
|
||||||
|
# [可选] 超时时间
|
||||||
|
timeout: 10000
|
||||||
|
# 以下为单机配置
|
||||||
|
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
|
||||||
|
host: 127.0.0.1
|
||||||
|
# [必须修改] 端口号
|
||||||
|
port: 6379
|
||||||
|
# [可选] 数据库 DB
|
||||||
|
database: 1
|
||||||
|
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
|
||||||
|
password: adminadmin123.
|
||||||
|
# 以下为集群配置
|
||||||
|
# cluster:
|
||||||
|
# nodes: 192.168.1.242:7001
|
||||||
|
# password: 4767cb971b40a1300fa09b7f87b09d1c
|
||||||
|
|
||||||
|
# [可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
||||||
|
server:
|
||||||
|
port: 18081
|
||||||
|
# [可选] HTTPS配置, 默认不开启
|
||||||
|
ssl:
|
||||||
|
# [可选] 是否开启HTTPS访问
|
||||||
|
enabled: false
|
||||||
|
# [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名
|
||||||
|
key-store: classpath:xxx.jks
|
||||||
|
# [可选] 证书密码
|
||||||
|
key-password: password
|
||||||
|
# [可选] 证书类型, 默认为jks,根据实际修改
|
||||||
|
key-store-type: JKS
|
||||||
|
|
||||||
|
# [根据业务需求配置]
|
||||||
|
userSettings:
|
||||||
|
# [必选 ] 服务ID
|
||||||
|
id: 334533
|
||||||
|
# [可选 ] 录像下载合成临时文件保存时长, 不配置默认取值recordDay(单位: 天)每天晚12点自动对过期文件执行清理
|
||||||
|
# recordTempDay: 7
|
||||||
|
# [必选 ] ffmpeg路径
|
||||||
|
ffmpeg: lib/ffmpeg
|
||||||
|
# [必选 ] ffprobe路径, 一般安装ffmpeg就会自带, 一般跟ffmpeg在同一目录,用于查询文件的信息
|
||||||
|
ffprobe: lib/ffprobe
|
||||||
|
# [可选 ] 限制 ffmpeg 合并文件使用的线程数,间接限制cpu使用率, 默认2 限制到50%
|
||||||
|
threads: 2
|
||||||
|
|
||||||
|
swagger-ui:
|
||||||
|
enabled: true
|
||||||
|
# [可选] 日志配置, 一般不需要改
|
||||||
|
logging:
|
||||||
|
file:
|
||||||
|
name: logs/wvp.log
|
||||||
|
max-history: 30
|
||||||
|
max-size: 10MB
|
||||||
|
total-size-cap: 300MB
|
||||||
|
level:
|
||||||
|
root: WARN
|
||||||
|
top:
|
||||||
|
panll:
|
||||||
|
assist: info
|
||||||
|
net:
|
||||||
|
bramp:
|
||||||
|
ffmpeg: error
|
166
打包/config/config.ini
Executable file
166
打包/config/config.ini
Executable file
@ -0,0 +1,166 @@
|
|||||||
|
; auto-generated by mINI class {
|
||||||
|
|
||||||
|
[api]
|
||||||
|
apiDebug=1
|
||||||
|
defaultSnap=./www/logo.png
|
||||||
|
secret=034523TF8yT83wh5Wvz73f7
|
||||||
|
snapRoot=./www/snap/
|
||||||
|
|
||||||
|
[cluster]
|
||||||
|
origin_url=
|
||||||
|
retry_count=3
|
||||||
|
timeout_sec=15
|
||||||
|
|
||||||
|
[ffmpeg]
|
||||||
|
bin=/usr/bin/ffmpeg
|
||||||
|
cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
|
||||||
|
log=./ffmpeg/ffmpeg.log
|
||||||
|
restart_sec=0
|
||||||
|
snap=%s -i %s -y -f mjpeg -t 0.001 %s
|
||||||
|
|
||||||
|
[general]
|
||||||
|
check_nvidia_dev=1
|
||||||
|
enableVhost=0
|
||||||
|
enable_ffmpeg_log=0
|
||||||
|
flowThreshold=1024
|
||||||
|
maxStreamWaitMS=15000
|
||||||
|
mediaServerId=GQ3TF8yT83wh5Wvz
|
||||||
|
mergeWriteMS=0
|
||||||
|
resetWhenRePlay=1
|
||||||
|
streamNoneReaderDelayMS=15000
|
||||||
|
unready_frame_cache=100
|
||||||
|
wait_add_track_ms=3000
|
||||||
|
wait_track_ready_ms=10000
|
||||||
|
|
||||||
|
[hls]
|
||||||
|
broadcastRecordTs=0
|
||||||
|
deleteDelaySec=10
|
||||||
|
fileBufSize=65536
|
||||||
|
segDur=2
|
||||||
|
segKeep=0
|
||||||
|
segNum=3
|
||||||
|
segRetain=5
|
||||||
|
|
||||||
|
[hook]
|
||||||
|
admin_params=secret=034523TF8yT83wh5Wvz73f7
|
||||||
|
alive_interval=30.000000
|
||||||
|
enable=1
|
||||||
|
on_flow_report=
|
||||||
|
on_http_access=
|
||||||
|
on_play=http://192.168.1.3:18082/index/hook/on_play
|
||||||
|
on_publish=http://192.168.1.3:18082/index/hook/on_publish
|
||||||
|
on_record_mp4=
|
||||||
|
on_record_ts=
|
||||||
|
on_rtp_server_timeout=http://192.168.1.3:18082/index/hook/on_rtp_server_timeout
|
||||||
|
on_rtsp_auth=
|
||||||
|
on_rtsp_realm=
|
||||||
|
on_send_rtp_stopped=http://192.168.1.3:18082/index/hook/on_send_rtp_stopped
|
||||||
|
on_server_keepalive=http://192.168.1.3:18082/index/hook/on_server_keepalive
|
||||||
|
on_server_started=http://192.168.1.3:18082/index/hook/on_server_started
|
||||||
|
on_shell_login=
|
||||||
|
on_stream_changed=http://192.168.1.3:18082/index/hook/on_stream_changed
|
||||||
|
on_stream_none_reader=http://192.168.1.3:18082/index/hook/on_stream_none_reader
|
||||||
|
on_stream_not_found=http://192.168.1.3:18082/index/hook/on_stream_not_found
|
||||||
|
retry=1
|
||||||
|
retry_delay=3.000000
|
||||||
|
timeoutSec=20
|
||||||
|
|
||||||
|
[http]
|
||||||
|
charSet=utf-8
|
||||||
|
dirMenu=1
|
||||||
|
forbidCacheSuffix=
|
||||||
|
forwarded_ip_header=
|
||||||
|
keepAliveSecond=15
|
||||||
|
maxReqSize=40960
|
||||||
|
notFound=<html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>您访问的资源不存在!</h1></center><hr><center>ZLMediaKit(git hash:f6cba98/2023-02-06T14:18:21+08:00,branch:master,build time:2023-02-07T10:51:47)</center></body></html>
|
||||||
|
port=6080
|
||||||
|
rootPath=./www
|
||||||
|
sendBufSize=65536
|
||||||
|
sslport=16080
|
||||||
|
virtualPath=
|
||||||
|
|
||||||
|
[multicast]
|
||||||
|
addrMax=239.255.255.255
|
||||||
|
addrMin=239.0.0.0
|
||||||
|
udpTTL=64
|
||||||
|
|
||||||
|
[protocol]
|
||||||
|
add_mute_audio=1
|
||||||
|
continue_push_ms=3000
|
||||||
|
enable_audio=1
|
||||||
|
enable_fmp4=1
|
||||||
|
enable_hls=1
|
||||||
|
enable_mp4=0
|
||||||
|
enable_rtmp=1
|
||||||
|
enable_rtsp=1
|
||||||
|
enable_ts=1
|
||||||
|
fmp4_demand=0
|
||||||
|
hls_demand=0
|
||||||
|
hls_save_path=./www
|
||||||
|
modify_stamp=0
|
||||||
|
mp4_as_player=0
|
||||||
|
mp4_max_second=3600
|
||||||
|
mp4_save_path=./www
|
||||||
|
rtmp_demand=0
|
||||||
|
rtsp_demand=0
|
||||||
|
ts_demand=0
|
||||||
|
|
||||||
|
[record]
|
||||||
|
appName=record
|
||||||
|
fastStart=0
|
||||||
|
fileBufSize=65536
|
||||||
|
fileRepeat=0
|
||||||
|
sampleMS=500
|
||||||
|
|
||||||
|
[rtc]
|
||||||
|
externIP=192.168.1.3
|
||||||
|
port=8000
|
||||||
|
preferredCodecA=PCMA,PCMU,opus,mpeg4-generic
|
||||||
|
preferredCodecV=H264,H265,AV1,VP9,VP8
|
||||||
|
rembBitRate=0
|
||||||
|
tcpPort=8000
|
||||||
|
timeoutSec=15
|
||||||
|
|
||||||
|
[rtmp]
|
||||||
|
handshakeSecond=15
|
||||||
|
keepAliveSecond=15
|
||||||
|
modifyStamp=0
|
||||||
|
port=1935
|
||||||
|
sslport=19350
|
||||||
|
|
||||||
|
[rtp]
|
||||||
|
audioMtuSize=600
|
||||||
|
lowLatency=0
|
||||||
|
rtpMaxSize=10
|
||||||
|
videoMtuSize=1400
|
||||||
|
|
||||||
|
[rtp_proxy]
|
||||||
|
dumpDir=
|
||||||
|
h264_pt=98
|
||||||
|
h265_pt=99
|
||||||
|
opus_pt=100
|
||||||
|
port=10000
|
||||||
|
port_range=40000-40500
|
||||||
|
ps_pt=96
|
||||||
|
timeoutSec=15
|
||||||
|
|
||||||
|
[rtsp]
|
||||||
|
authBasic=0
|
||||||
|
directProxy=1
|
||||||
|
handshakeSecond=15
|
||||||
|
keepAliveSecond=15
|
||||||
|
lowLatency=0
|
||||||
|
port=10554
|
||||||
|
sslport=
|
||||||
|
|
||||||
|
[shell]
|
||||||
|
maxReqSize=1024
|
||||||
|
port=9000
|
||||||
|
|
||||||
|
[srt]
|
||||||
|
latencyMul=4
|
||||||
|
pktBufSize=8192
|
||||||
|
port=9000
|
||||||
|
timeoutSec=5
|
||||||
|
|
||||||
|
; } ---
|
120
打包/config/wvp-application.yml
Executable file
120
打包/config/wvp-application.yml
Executable file
@ -0,0 +1,120 @@
|
|||||||
|
spring:
|
||||||
|
# [可选]上传文件大小限制
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 10MB
|
||||||
|
max-request-size: 100MB
|
||||||
|
# REDIS数据库配置
|
||||||
|
redis:
|
||||||
|
# [可选] 超时时间
|
||||||
|
timeout: 10000
|
||||||
|
# 以下为单机配置
|
||||||
|
# [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
|
||||||
|
host: 127.0.0.1
|
||||||
|
# # [必须修改] 端口号
|
||||||
|
port: 6379
|
||||||
|
# [可选] 数据库 DB
|
||||||
|
database: 1
|
||||||
|
# [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
|
||||||
|
password: adminadmin123.
|
||||||
|
# 以下为集群配置
|
||||||
|
# cluster:
|
||||||
|
# nodes: 192.168.1.66:9001,192.168.1.66:9002,192.168.1.66:9003,192.168.1.66:9004,192.168.1.66:9005,192.168.1.66:9006
|
||||||
|
# password: adminadmin123.
|
||||||
|
# [可选] jdbc数据库配置, 项目使用sqlite作为数据库,一般不需要配置
|
||||||
|
# mysql数据源
|
||||||
|
datasource:
|
||||||
|
# kingbase配置
|
||||||
|
# type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
# driver-class-name: com.kingbase8.Driver
|
||||||
|
# url: jdbc:kingbase8://192.168.1.55:54321/wvp?useUnicode=true&characterEncoding=utf8
|
||||||
|
# username: system
|
||||||
|
# password: system
|
||||||
|
# postgresql配置
|
||||||
|
# type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
# driver-class-name: org.postgresql.Driver
|
||||||
|
# url: jdbc:postgresql://192.168.1.242:3306/242wvp
|
||||||
|
# username: root
|
||||||
|
# password: SYceshizu1234
|
||||||
|
# mysql配置
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://192.168.1.242:3306/242wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
|
||||||
|
username: root
|
||||||
|
password: SYceshizu1234
|
||||||
|
|
||||||
|
|
||||||
|
# kingbase 和 postgresql需要开启这个配置
|
||||||
|
#pagehelper:
|
||||||
|
# helper-dialect: postgresql
|
||||||
|
|
||||||
|
#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口
|
||||||
|
server:
|
||||||
|
port: 18080
|
||||||
|
|
||||||
|
# 作为28181服务器的配置
|
||||||
|
sip:
|
||||||
|
# [必须修改] 本机的IP
|
||||||
|
ip: 192.168.1.3
|
||||||
|
# [可选] 28181服务监听的端口
|
||||||
|
port: 15060
|
||||||
|
# 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
|
||||||
|
# 后两位为行业编码,定义参照附录D.3
|
||||||
|
# 3701020049标识山东济南历下区 信息行业接入
|
||||||
|
# [可选]
|
||||||
|
domain: 3402000001
|
||||||
|
# [可选]
|
||||||
|
id: 34020000013000000001
|
||||||
|
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
|
||||||
|
password: 12345678
|
||||||
|
|
||||||
|
#zlm 默认服务器配置
|
||||||
|
media:
|
||||||
|
# [必须修改] zlm服务器唯一id,用于触发hook时区别是哪台服务器,general.mediaServerId
|
||||||
|
id: GQ3TF8yT83wh5Wvz
|
||||||
|
# [必须修改] zlm服务器的内网IP
|
||||||
|
ip: 192.168.1.3
|
||||||
|
# [必须修改] zlm服务器的http.port
|
||||||
|
http-port: 6080
|
||||||
|
# [可选] zlm服务器的hook.admin_params=secret
|
||||||
|
secret: 034523TF8yT83wh5Wvz73f7
|
||||||
|
# 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试
|
||||||
|
rtp:
|
||||||
|
# [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输
|
||||||
|
enable: true
|
||||||
|
# [可选] 在此范围内选择端口用于媒体流传输,
|
||||||
|
port-range: 30000,30500 # 端口范围
|
||||||
|
# [可选] 国标级联在此范围内选择端口发送媒体流,请不要与收流端口范围重合
|
||||||
|
send-port-range: 50502,50506 # 端口范围
|
||||||
|
# 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用
|
||||||
|
record-assist-port: 18089
|
||||||
|
# 录像路径
|
||||||
|
record-path: ./www/record
|
||||||
|
# 录像保存时长
|
||||||
|
record-day: 7
|
||||||
|
# [可选] 日志配置, 一般不需要改
|
||||||
|
logging:
|
||||||
|
config: classpath:logback-spring-local.xml
|
||||||
|
|
||||||
|
# [根据业务需求配置]
|
||||||
|
user-settings:
|
||||||
|
server-id: 741266
|
||||||
|
auto-apply-play: true
|
||||||
|
interface-authentication: true
|
||||||
|
interface-authentication-excludes:
|
||||||
|
- /api/v1/**
|
||||||
|
- /api/media/stream_info_by_app_and_stream
|
||||||
|
- /api/v1/control/ptz
|
||||||
|
- /api/cloud/record/*/**
|
||||||
|
# 推流直播是否录制
|
||||||
|
record-push-live: true
|
||||||
|
# 国标是否录制
|
||||||
|
record-sip: false
|
||||||
|
# 使用推流状态作为推流通道状态
|
||||||
|
use-pushing-as-status: false
|
||||||
|
# 设备上线时是否自动同步通道
|
||||||
|
sync-channel-on-device-online: false
|
||||||
|
# 消息通道功能-缺少国标ID是否给所有上级发送消息
|
||||||
|
send-to-platforms-when-id-lost: false
|
||||||
|
|
||||||
|
|
323
数据库/2.6.9/初始化-mysql-2.6.9.sql
Normal file
323
数据库/2.6.9/初始化-mysql-2.6.9.sql
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*建表*/
|
||||||
|
create table wvp_device (
|
||||||
|
id serial primary key ,
|
||||||
|
device_id character varying(50) not null ,
|
||||||
|
name character varying(255),
|
||||||
|
manufacturer character varying(255),
|
||||||
|
model character varying(255),
|
||||||
|
firmware character varying(255),
|
||||||
|
transport character varying(50),
|
||||||
|
stream_mode character varying(50),
|
||||||
|
on_line bool default false,
|
||||||
|
register_time character varying(50),
|
||||||
|
keepalive_time character varying(50),
|
||||||
|
ip character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
port integer,
|
||||||
|
expires integer,
|
||||||
|
subscribe_cycle_for_catalog integer DEFAULT 0,
|
||||||
|
subscribe_cycle_for_mobile_position integer DEFAULT 0,
|
||||||
|
mobile_position_submission_interval integer DEFAULT 5,
|
||||||
|
subscribe_cycle_for_alarm integer DEFAULT 0,
|
||||||
|
host_address character varying(50),
|
||||||
|
charset character varying(50),
|
||||||
|
ssrc_check bool default false,
|
||||||
|
geo_coord_sys character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
custom_name character varying(255),
|
||||||
|
sdp_ip character varying(50),
|
||||||
|
local_ip character varying(50),
|
||||||
|
password character varying(255),
|
||||||
|
as_message_channel bool default false,
|
||||||
|
keepalive_interval_time integer,
|
||||||
|
switch_primary_sub_stream bool default false,
|
||||||
|
broadcast_push_after_ack bool default false,
|
||||||
|
constraint uk_device_device unique (device_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_device_alarm (
|
||||||
|
id serial primary key ,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
alarm_priority character varying(50),
|
||||||
|
alarm_method character varying(50),
|
||||||
|
alarm_time character varying(50),
|
||||||
|
alarm_description character varying(255),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
alarm_type character varying(50),
|
||||||
|
create_time character varying(50) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_device_channel (
|
||||||
|
id serial primary key ,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
name character varying(255),
|
||||||
|
custom_name character varying(255),
|
||||||
|
manufacture character varying(50),
|
||||||
|
model character varying(50),
|
||||||
|
owner character varying(50),
|
||||||
|
civil_code character varying(50),
|
||||||
|
block character varying(50),
|
||||||
|
address character varying(50),
|
||||||
|
parent_id character varying(50),
|
||||||
|
safety_way integer,
|
||||||
|
register_way integer,
|
||||||
|
cert_num character varying(50),
|
||||||
|
certifiable integer,
|
||||||
|
err_code integer,
|
||||||
|
end_time character varying(50),
|
||||||
|
secrecy character varying(50),
|
||||||
|
ip_address character varying(50),
|
||||||
|
port integer,
|
||||||
|
password character varying(255),
|
||||||
|
ptz_type integer,
|
||||||
|
custom_ptz_type integer,
|
||||||
|
status bool default false,
|
||||||
|
longitude double precision,
|
||||||
|
custom_longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
custom_latitude double precision,
|
||||||
|
stream_id character varying(255),
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
parental character varying(50),
|
||||||
|
has_audio bool default false,
|
||||||
|
create_time character varying(50) not null,
|
||||||
|
update_time character varying(50) not null,
|
||||||
|
sub_count integer,
|
||||||
|
longitude_gcj02 double precision,
|
||||||
|
latitude_gcj02 double precision,
|
||||||
|
longitude_wgs84 double precision,
|
||||||
|
latitude_wgs84 double precision,
|
||||||
|
business_group_id character varying(50),
|
||||||
|
gps_time character varying(50),
|
||||||
|
constraint uk_wvp_device_channel_unique_device_channel unique (device_id, channel_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_device_mobile_position (
|
||||||
|
id serial primary key,
|
||||||
|
device_id character varying(50) not null,
|
||||||
|
channel_id character varying(50) not null,
|
||||||
|
device_name character varying(255),
|
||||||
|
time character varying(50),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
altitude double precision,
|
||||||
|
speed double precision,
|
||||||
|
direction double precision,
|
||||||
|
report_source character varying(50),
|
||||||
|
longitude_gcj02 double precision,
|
||||||
|
latitude_gcj02 double precision,
|
||||||
|
longitude_wgs84 double precision,
|
||||||
|
latitude_wgs84 double precision,
|
||||||
|
create_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_gb_stream (
|
||||||
|
gb_stream_id serial primary key,
|
||||||
|
app character varying(255) not null,
|
||||||
|
stream character varying(255) not null,
|
||||||
|
gb_id character varying(50) not null,
|
||||||
|
name character varying(255),
|
||||||
|
longitude double precision,
|
||||||
|
latitude double precision,
|
||||||
|
stream_type character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
constraint uk_gb_stream_unique_gb_id unique (gb_id),
|
||||||
|
constraint uk_gb_stream_unique_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_log (
|
||||||
|
id serial primary key ,
|
||||||
|
name character varying(50),
|
||||||
|
type character varying(50),
|
||||||
|
uri character varying(200),
|
||||||
|
address character varying(50),
|
||||||
|
result character varying(50),
|
||||||
|
timing bigint,
|
||||||
|
username character varying(50),
|
||||||
|
create_time character varying(50)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_media_server (
|
||||||
|
id character varying(255) primary key ,
|
||||||
|
ip character varying(50),
|
||||||
|
hook_ip character varying(50),
|
||||||
|
sdp_ip character varying(50),
|
||||||
|
stream_ip character varying(50),
|
||||||
|
http_port integer,
|
||||||
|
http_ssl_port integer,
|
||||||
|
rtmp_port integer,
|
||||||
|
rtmp_ssl_port integer,
|
||||||
|
rtp_proxy_port integer,
|
||||||
|
rtsp_port integer,
|
||||||
|
rtsp_ssl_port integer,
|
||||||
|
auto_config bool default false,
|
||||||
|
secret character varying(50),
|
||||||
|
rtp_enable bool default false,
|
||||||
|
rtp_port_range character varying(50),
|
||||||
|
send_rtp_port_range character varying(50),
|
||||||
|
record_assist_port integer,
|
||||||
|
default_server bool default false,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
hook_alive_interval integer,
|
||||||
|
record_path character varying(255),
|
||||||
|
record_day integer default 7,
|
||||||
|
constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_platform (
|
||||||
|
id serial primary key ,
|
||||||
|
enable bool default false,
|
||||||
|
name character varying(255),
|
||||||
|
server_gb_id character varying(50),
|
||||||
|
server_gb_domain character varying(50),
|
||||||
|
server_ip character varying(50),
|
||||||
|
server_port integer,
|
||||||
|
device_gb_id character varying(50),
|
||||||
|
device_ip character varying(50),
|
||||||
|
device_port character varying(50),
|
||||||
|
username character varying(255),
|
||||||
|
password character varying(50),
|
||||||
|
expires character varying(50),
|
||||||
|
keep_timeout character varying(50),
|
||||||
|
transport character varying(50),
|
||||||
|
character_set character varying(50),
|
||||||
|
catalog_id character varying(50),
|
||||||
|
ptz bool default false,
|
||||||
|
rtcp bool default false,
|
||||||
|
status bool default false,
|
||||||
|
start_offline_push bool default false,
|
||||||
|
administrative_division character varying(50),
|
||||||
|
catalog_group integer,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
as_message_channel bool default false,
|
||||||
|
auto_push_channel bool default false,
|
||||||
|
constraint uk_platform_unique_server_gb_id unique (server_gb_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_platform_catalog (
|
||||||
|
id character varying(50),
|
||||||
|
platform_id character varying(50),
|
||||||
|
name character varying(255),
|
||||||
|
parent_id character varying(50),
|
||||||
|
civil_code character varying(50),
|
||||||
|
business_group_id character varying(50),
|
||||||
|
constraint uk_platform_catalog_id_platform_id unique (id, platform_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_platform_gb_channel (
|
||||||
|
id serial primary key ,
|
||||||
|
platform_id character varying(50),
|
||||||
|
catalog_id character varying(50),
|
||||||
|
device_channel_id integer,
|
||||||
|
constraint uk_platform_gb_channel_platform_id_catalog_id_device_channel_id unique (platform_id, catalog_id, device_channel_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_platform_gb_stream (
|
||||||
|
id serial primary key,
|
||||||
|
platform_id character varying(50),
|
||||||
|
catalog_id character varying(50),
|
||||||
|
gb_stream_id integer,
|
||||||
|
constraint uk_platform_gb_stream_platform_id_catalog_id_gb_stream_id unique (platform_id, catalog_id, gb_stream_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_stream_proxy (
|
||||||
|
id serial primary key,
|
||||||
|
type character varying(50),
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
url character varying(255),
|
||||||
|
src_url character varying(255),
|
||||||
|
dst_url character varying(255),
|
||||||
|
timeout_ms integer,
|
||||||
|
ffmpeg_cmd_key character varying(255),
|
||||||
|
rtp_type character varying(50),
|
||||||
|
media_server_id character varying(50),
|
||||||
|
enable_audio bool default false,
|
||||||
|
enable_mp4 bool default false,
|
||||||
|
enable bool default false,
|
||||||
|
status boolean,
|
||||||
|
enable_remove_none_reader bool default false,
|
||||||
|
create_time character varying(50),
|
||||||
|
name character varying(255),
|
||||||
|
update_time character varying(50),
|
||||||
|
stream_key character varying(255),
|
||||||
|
enable_disable_none_reader bool default false,
|
||||||
|
constraint uk_stream_proxy_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_stream_push (
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
total_reader_count character varying(50),
|
||||||
|
origin_type integer,
|
||||||
|
origin_type_str character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
alive_second integer,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
|
push_time character varying(50),
|
||||||
|
status bool default false,
|
||||||
|
update_time character varying(50),
|
||||||
|
push_ing bool default false,
|
||||||
|
self bool default false,
|
||||||
|
constraint uk_stream_push_app_stream unique (app, stream)
|
||||||
|
);
|
||||||
|
create table wvp_cloud_record (
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
call_id character varying(255),
|
||||||
|
start_time bigint,
|
||||||
|
end_time bigint,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
file_name character varying(255),
|
||||||
|
folder character varying(255),
|
||||||
|
file_path character varying(255),
|
||||||
|
collect bool default false,
|
||||||
|
file_size bigint,
|
||||||
|
time_len bigint,
|
||||||
|
constraint uk_stream_push_app_stream_path unique (app, stream, file_path)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_user (
|
||||||
|
id serial primary key,
|
||||||
|
username character varying(255),
|
||||||
|
password character varying(255),
|
||||||
|
role_id integer,
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50),
|
||||||
|
push_key character varying(50),
|
||||||
|
constraint uk_user_username unique (username)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wvp_user_role (
|
||||||
|
id serial primary key,
|
||||||
|
name character varying(50),
|
||||||
|
authority character varying(50),
|
||||||
|
create_time character varying(50),
|
||||||
|
update_time character varying(50)
|
||||||
|
);
|
||||||
|
create table wvp_resources_tree (
|
||||||
|
id serial primary key ,
|
||||||
|
is_catalog bool default true,
|
||||||
|
device_channel_id integer ,
|
||||||
|
gb_stream_id integer,
|
||||||
|
name character varying(255),
|
||||||
|
parentId integer,
|
||||||
|
path character varying(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*初始数据*/
|
||||||
|
INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3');
|
||||||
|
INSERT INTO wvp_user_role VALUES (1, 'admin','0','2021-04-13 14:14:57','2021-04-13 14:14:57');
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -164,6 +164,8 @@ create table wvp_media_server (
|
|||||||
create_time character varying(50),
|
create_time character varying(50),
|
||||||
update_time character varying(50),
|
update_time character varying(50),
|
||||||
hook_alive_interval integer,
|
hook_alive_interval integer,
|
||||||
|
record_path character varying(255),
|
||||||
|
record_day integer default 7,
|
||||||
constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
|
constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -259,6 +261,7 @@ create table wvp_stream_push (
|
|||||||
create_time character varying(50),
|
create_time character varying(50),
|
||||||
alive_second integer,
|
alive_second integer,
|
||||||
media_server_id character varying(50),
|
media_server_id character varying(50),
|
||||||
|
server_id character varying(50),
|
||||||
push_time character varying(50),
|
push_time character varying(50),
|
||||||
status bool default false,
|
status bool default false,
|
||||||
update_time character varying(50),
|
update_time character varying(50),
|
||||||
@ -266,6 +269,22 @@ create table wvp_stream_push (
|
|||||||
self bool default false,
|
self bool default false,
|
||||||
constraint uk_stream_push_app_stream unique (app, stream)
|
constraint uk_stream_push_app_stream unique (app, stream)
|
||||||
);
|
);
|
||||||
|
create table wvp_cloud_record (
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
call_id character varying(255),
|
||||||
|
start_time int8,
|
||||||
|
end_time int8,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
file_name character varying(255),
|
||||||
|
folder character varying(255),
|
||||||
|
file_path character varying(255),
|
||||||
|
collect bool default false,
|
||||||
|
file_size int8,
|
||||||
|
time_len int8,
|
||||||
|
constraint uk_stream_push_app_stream_path unique (app, stream, file_path)
|
||||||
|
);
|
||||||
|
|
||||||
create table wvp_user (
|
create table wvp_user (
|
||||||
id serial primary key,
|
id serial primary key,
|
503
数据库/2.6.9/更新-mysql-2.6.9.sql
Normal file
503
数据库/2.6.9/更新-mysql-2.6.9.sql
Normal file
@ -0,0 +1,503 @@
|
|||||||
|
|
||||||
|
alter table device
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change streamMode stream_mode varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change registerTime register_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change keepaliveTime keepalive_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change subscribeCycleForCatalog subscribe_cycle_for_catalog bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change subscribeCycleForMobilePosition subscribe_cycle_for_mobile_position bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change mobilePositionSubmissionInterval mobile_position_submission_interval int default 5 not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change subscribeCycleForAlarm subscribe_cycle_for_alarm bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change hostAddress host_address varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change ssrcCheck ssrc_check bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change geoCoordSys geo_coord_sys varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
drop column treeType;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change mediaServerId media_server_id varchar(50) default 'auto' null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change sdpIp sdp_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change localIp local_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change asMessageChannel as_message_channel bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change keepaliveIntervalTime keepalive_interval_time int null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change online on_line varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
add COLUMN switch_primary_sub_stream bool default false comment '开启主子码流切换的开关(0-不开启,1-开启)现在已知支持设备为 大华、TP——LINK全系设备';
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change channelId channel_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmPriority alarm_priority varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmMethod alarm_method varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmTime alarm_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmDescription alarm_description varchar(255) null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmType alarm_type varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change channelId channel_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change civilCode civil_code varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change parentId parent_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change safetyWay safety_way int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change registerWay register_way int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change certNum cert_num varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change errCode err_code int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change endTime end_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change ipAddress ip_address varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change PTZType ptz_type int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change streamId stream_id varchar(255) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change hasAudio has_audio bool default false;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change subCount sub_count int default 0 null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change longitudeGcj02 longitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change latitudeGcj02 latitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change longitudeWgs84 longitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change latitudeWgs84 latitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change businessGroupId business_group_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change gpsTime gps_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change channelId channel_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change deviceName device_name varchar(255) null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change reportSource report_source varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change longitudeGcj02 longitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change latitudeGcj02 latitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change longitudeWgs84 longitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change latitudeWgs84 latitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change gbStreamId gb_stream_id int auto_increment;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change gbId gb_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change streamType stream_type varchar(50) null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change mediaServerId media_server_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table log
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change hookIp hook_ip varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
add column send_rtp_port_range varchar(50) default null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change sdpIp sdp_ip varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change streamIp stream_ip varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change httpPort http_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change httpSSlPort http_ssl_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtmpPort rtmp_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtmpSSlPort rtmp_ssl_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtpProxyPort rtp_proxy_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtspPort rtsp_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtspSSLPort rtsp_ssl_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change autoConfig auto_config bool default true;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtpEnable rtp_enable bool default false;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtpPortRange rtp_port_range varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change recordAssistPort record_assist_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change defaultServer default_server bool default false;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change hookAliveInterval hook_alive_interval int not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverGBId server_gb_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverGBDomain server_gb_domain varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverIP server_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverPort server_port int null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change deviceGBId device_gb_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change deviceIp device_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change devicePort device_port varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change keepTimeout keep_timeout varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change characterSet character_set varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change catalogId catalog_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change startOfflinePush start_offline_push bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change administrativeDivision administrative_division varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change catalogGroup catalog_group int default 1 null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change updateTime update_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
drop column treeType;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change asMessageChannel as_message_channel bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change enable enable bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change ptz ptz bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change rtcp rtcp bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change platformId platform_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change parentId parent_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change civilCode civil_code varchar(50) null;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change businessGroupId business_group_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table platform_gb_channel
|
||||||
|
change platformId platform_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_channel
|
||||||
|
change catalogId catalog_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_channel
|
||||||
|
change deviceChannelId device_channel_id int not null;
|
||||||
|
|
||||||
|
alter table platform_gb_stream
|
||||||
|
change platformId platform_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_stream
|
||||||
|
change catalogId catalog_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_stream
|
||||||
|
change gbStreamId gb_stream_id int not null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change mediaServerId media_server_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change updateTime update_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_remove_none_reader enable_remove_none_reader bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_disable_none_reader enable_disable_none_reader bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_audio enable_audio bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_mp4 enable_mp4 bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable enable bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change totalReaderCount total_reader_count varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change originType origin_type int null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change originTypeStr origin_type_str varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change aliveSecond alive_second int null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change mediaServerId media_server_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change pushTime push_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change updateTime update_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change pushIng push_ing bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change self self bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
drop column serverId;
|
||||||
|
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change roleId role_id int not null;
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change pushKey push_key varchar(50) null;
|
||||||
|
|
||||||
|
alter table user_role
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table user_role
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
rename table device to wvp_device;
|
||||||
|
rename table device_alarm to wvp_device_alarm;
|
||||||
|
rename table device_channel to wvp_device_channel;
|
||||||
|
rename table device_mobile_position to wvp_device_mobile_position;
|
||||||
|
rename table gb_stream to wvp_gb_stream;
|
||||||
|
rename table log to wvp_log;
|
||||||
|
rename table media_server to wvp_media_server;
|
||||||
|
rename table parent_platform to wvp_platform;
|
||||||
|
rename table platform_catalog to wvp_platform_catalog;
|
||||||
|
rename table platform_gb_channel to wvp_platform_gb_channel;
|
||||||
|
rename table platform_gb_stream to wvp_platform_gb_stream;
|
||||||
|
rename table stream_proxy to wvp_stream_proxy;
|
||||||
|
rename table stream_push to wvp_stream_push;
|
||||||
|
rename table user to wvp_user;
|
||||||
|
rename table user_role to wvp_user_role;
|
||||||
|
|
||||||
|
alter table wvp_device add column broadcast_push_after_ack bool default false;
|
||||||
|
alter table wvp_device_channel add column custom_name varchar(255) null ;
|
||||||
|
alter table wvp_device_channel add column custom_longitude double null ;
|
||||||
|
alter table wvp_device_channel add column custom_latitude double null ;
|
||||||
|
alter table wvp_device_channel add column custom_ptz_type int null ;
|
||||||
|
|
||||||
|
create table wvp_resources_tree (
|
||||||
|
id serial primary key ,
|
||||||
|
is_catalog bool default true,
|
||||||
|
device_channel_id integer ,
|
||||||
|
gb_stream_id integer,
|
||||||
|
name character varying(255),
|
||||||
|
parentId integer,
|
||||||
|
path character varying(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table wvp_platform
|
||||||
|
add auto_push_channel bool default false;
|
||||||
|
|
||||||
|
alter table wvp_stream_proxy
|
||||||
|
add stream_key character varying(255);
|
||||||
|
|
||||||
|
create table wvp_cloud_record (
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
call_id character varying(255),
|
||||||
|
start_time bigint,
|
||||||
|
end_time bigint,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
file_name character varying(255),
|
||||||
|
folder character varying(255),
|
||||||
|
file_path character varying(255),
|
||||||
|
collect bool default false,
|
||||||
|
file_size bigint,
|
||||||
|
time_len bigint,
|
||||||
|
constraint uk_stream_push_app_stream_path unique (app, stream, file_path)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table wvp_media_server
|
||||||
|
add record_path character varying(255);
|
||||||
|
|
||||||
|
alter table wvp_media_server
|
||||||
|
add record_day integer default 7;
|
||||||
|
|
||||||
|
alter table wvp_stream_push
|
||||||
|
add server_id character varying(50);
|
||||||
|
|
||||||
|
|
505
数据库/2.6.9/更新-postgresql-kingbase-2.6.9.sql
Normal file
505
数据库/2.6.9/更新-postgresql-kingbase-2.6.9.sql
Normal file
@ -0,0 +1,505 @@
|
|||||||
|
|
||||||
|
alter table device
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change streamMode stream_mode varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change registerTime register_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change keepaliveTime keepalive_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change subscribeCycleForCatalog subscribe_cycle_for_catalog bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change subscribeCycleForMobilePosition subscribe_cycle_for_mobile_position bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change mobilePositionSubmissionInterval mobile_position_submission_interval int default 5 not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change subscribeCycleForAlarm subscribe_cycle_for_alarm bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change hostAddress host_address varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change ssrcCheck ssrc_check bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change geoCoordSys geo_coord_sys varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
drop column treeType;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change mediaServerId media_server_id varchar(50) default 'auto' null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change sdpIp sdp_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change localIp local_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change asMessageChannel as_message_channel bool default false;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change keepaliveIntervalTime keepalive_interval_time int null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
change online on_line varchar(50) null;
|
||||||
|
|
||||||
|
alter table device
|
||||||
|
add COLUMN switch_primary_sub_stream bool default false comment '开启主子码流切换的开关(0-不开启,1-开启)现在已知支持设备为 大华、TP——LINK全系设备'
|
||||||
|
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change channelId channel_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmPriority alarm_priority varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmMethod alarm_method varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmTime alarm_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmDescription alarm_description varchar(255) null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change alarmType alarm_type varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_alarm
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change channelId channel_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change civilCode civil_code varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change parentId parent_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change safetyWay safety_way int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change registerWay register_way int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change certNum cert_num varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change errCode err_code int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change endTime end_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change ipAddress ip_address varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change PTZType ptz_type int null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change streamId stream_id varchar(255) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change hasAudio has_audio bool default false;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change subCount sub_count int default 0 null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change longitudeGcj02 longitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change latitudeGcj02 latitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change longitudeWgs84 longitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change latitudeWgs84 latitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change businessGroupId business_group_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_channel
|
||||||
|
change gpsTime gps_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change deviceId device_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change channelId channel_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change deviceName device_name varchar(255) null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change reportSource report_source varchar(50) null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change longitudeGcj02 longitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change latitudeGcj02 latitude_gcj02 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change longitudeWgs84 longitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change latitudeWgs84 latitude_wgs84 double null;
|
||||||
|
|
||||||
|
alter table device_mobile_position
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change gbStreamId gb_stream_id int auto_increment;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change gbId gb_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change streamType stream_type varchar(50) null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change mediaServerId media_server_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table gb_stream
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table log
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change hookIp hook_ip varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
add column send_rtp_port_range varchar(50) default null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change sdpIp sdp_ip varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change streamIp stream_ip varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change httpPort http_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change httpSSlPort http_ssl_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtmpPort rtmp_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtmpSSlPort rtmp_ssl_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtpProxyPort rtp_proxy_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtspPort rtsp_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtspSSLPort rtsp_ssl_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change autoConfig auto_config bool default true;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtpEnable rtp_enable bool default false;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change rtpPortRange rtp_port_range varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change recordAssistPort record_assist_port int not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change defaultServer default_server bool default false;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table media_server
|
||||||
|
change hookAliveInterval hook_alive_interval int not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverGBId server_gb_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverGBDomain server_gb_domain varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverIP server_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change serverPort server_port int null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change deviceGBId device_gb_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change deviceIp device_ip varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change devicePort device_port varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change keepTimeout keep_timeout varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change characterSet character_set varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change catalogId catalog_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change startOfflinePush start_offline_push bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change administrativeDivision administrative_division varchar(50) not null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change catalogGroup catalog_group int default 1 null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change updateTime update_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
drop column treeType;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change asMessageChannel as_message_channel bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change enable enable bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change ptz ptz bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change rtcp rtcp bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table parent_platform
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change platformId platform_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change parentId parent_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change civilCode civil_code varchar(50) null;
|
||||||
|
|
||||||
|
alter table platform_catalog
|
||||||
|
change businessGroupId business_group_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table platform_gb_channel
|
||||||
|
change platformId platform_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_channel
|
||||||
|
change catalogId catalog_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_channel
|
||||||
|
change deviceChannelId device_channel_id int not null;
|
||||||
|
|
||||||
|
alter table platform_gb_stream
|
||||||
|
change platformId platform_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_stream
|
||||||
|
change catalogId catalog_id varchar(50) not null;
|
||||||
|
|
||||||
|
alter table platform_gb_stream
|
||||||
|
change gbStreamId gb_stream_id int not null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change mediaServerId media_server_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change updateTime update_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_remove_none_reader enable_remove_none_reader bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_disable_none_reader enable_disable_none_reader bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_audio enable_audio bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable_mp4 enable_mp4 bool default false;
|
||||||
|
|
||||||
|
alter table stream_proxy
|
||||||
|
change enable enable bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change totalReaderCount total_reader_count varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change originType origin_type int null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change originTypeStr origin_type_str varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change createTime create_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change aliveSecond alive_second int null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change mediaServerId media_server_id varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change pushTime push_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change updateTime update_time varchar(50) null;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change pushIng push_ing bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change status status bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
change self self bool default false;
|
||||||
|
|
||||||
|
alter table stream_push
|
||||||
|
drop column serverId;
|
||||||
|
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change roleId role_id int not null;
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table user
|
||||||
|
change pushKey push_key varchar(50) null;
|
||||||
|
|
||||||
|
alter table user_role
|
||||||
|
change createTime create_time varchar(50) not null;
|
||||||
|
|
||||||
|
alter table user_role
|
||||||
|
change updateTime update_time varchar(50) not null;
|
||||||
|
|
||||||
|
rename table device to wvp_device;
|
||||||
|
rename table device_alarm to wvp_device_alarm;
|
||||||
|
rename table device_channel to wvp_device_channel;
|
||||||
|
rename table device_mobile_position to wvp_device_mobile_position;
|
||||||
|
rename table gb_stream to wvp_gb_stream;
|
||||||
|
rename table log to wvp_log;
|
||||||
|
rename table media_server to wvp_media_server;
|
||||||
|
rename table parent_platform to wvp_platform;
|
||||||
|
rename table platform_catalog to wvp_platform_catalog;
|
||||||
|
rename table platform_gb_channel to wvp_platform_gb_channel;
|
||||||
|
rename table platform_gb_stream to wvp_platform_gb_stream;
|
||||||
|
rename table stream_proxy to wvp_stream_proxy;
|
||||||
|
rename table stream_push to wvp_stream_push;
|
||||||
|
rename table user to wvp_user;
|
||||||
|
rename table user_role to wvp_user_role;
|
||||||
|
|
||||||
|
alter table wvp_device add column broadcast_push_after_ack bool default false;
|
||||||
|
alter table wvp_device_channel add column custom_name varchar(255) null ;
|
||||||
|
alter table wvp_device_channel add column custom_longitude double null ;
|
||||||
|
alter table wvp_device_channel add column custom_latitude double null ;
|
||||||
|
alter table wvp_device_channel add column custom_ptz_type int null ;
|
||||||
|
|
||||||
|
create table wvp_resources_tree (
|
||||||
|
id serial primary key ,
|
||||||
|
is_catalog bool default true,
|
||||||
|
device_channel_id integer ,
|
||||||
|
gb_stream_id integer,
|
||||||
|
name character varying(255),
|
||||||
|
parentId integer,
|
||||||
|
path character varying(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table wvp_platform
|
||||||
|
add auto_push_channel bool default false;
|
||||||
|
|
||||||
|
alter table wvp_stream_proxy
|
||||||
|
add stream_key character varying(255);
|
||||||
|
|
||||||
|
create table wvp_cloud_record (
|
||||||
|
id serial primary key,
|
||||||
|
app character varying(255),
|
||||||
|
stream character varying(255),
|
||||||
|
call_id character varying(255),
|
||||||
|
start_time int8,
|
||||||
|
end_time int8,
|
||||||
|
media_server_id character varying(50),
|
||||||
|
file_name character varying(255),
|
||||||
|
folder character varying(255),
|
||||||
|
file_path character varying(255),
|
||||||
|
collect bool default false,
|
||||||
|
file_size int8,
|
||||||
|
time_len int8,
|
||||||
|
constraint uk_stream_push_app_stream_path unique (app, stream, file_path)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table wvp_media_server
|
||||||
|
add record_path character varying(255);
|
||||||
|
|
||||||
|
alter table wvp_media_server
|
||||||
|
add record_day integer default 7;
|
||||||
|
|
||||||
|
alter table wvp_stream_push
|
||||||
|
add server_id character varying(50);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ alter table device_channel
|
|||||||
change status status bool default false;
|
change status status bool default false;
|
||||||
|
|
||||||
alter table device_channel
|
alter table device_channel
|
||||||
change streamId stream_id varchar(50) null;
|
change streamId stream_id varchar(255) null;
|
||||||
|
|
||||||
alter table device_channel
|
alter table device_channel
|
||||||
change deviceId device_id varchar(50) not null;
|
change deviceId device_id varchar(50) not null;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user