From 1983b8b0a705995665dffadf709afd03239c5950 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 22 Nov 2022 12:55:29 +0800 Subject: [PATCH 01/20] =?UTF-8?q?=E5=9B=BD=E6=A0=87=E7=BA=A7=E8=81=94->?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E9=80=9A=E9=81=93=E6=94=AF=E6=8C=81=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E7=9B=AE=E5=89=8D=E4=B8=8B=E6=89=80=E6=9C=89=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=85=A8=E9=83=A8=E6=B7=BB=E5=8A=A0=E5=88=B0=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/service/IDeviceChannelService.java | 8 +++ .../iot/vmp/service/IGbStreamService.java | 14 ++++++ .../vmp/service/IPlatformChannelService.java | 7 +++ .../impl/DeviceChannelServiceImpl.java | 9 ++++ .../vmp/service/impl/GbStreamServiceImpl.java | 34 ++++++++++++- .../impl/PlatformChannelServiceImpl.java | 23 +++++++++ .../vmp/storager/dao/DeviceChannelMapper.java | 1 - .../iot/vmp/storager/dao/GbStreamMapper.java | 2 +- .../storager/dao/PlatformChannelMapper.java | 8 +++ .../storager/dao/PlatformGbStreamMapper.java | 3 ++ .../impl/VideoManagerStorageImpl.java | 15 ------ .../gb28181/gbStream/GbStreamController.java | 27 ++++++---- .../gb28181/gbStream/bean/GbStreamParam.java | 11 +++++ .../gb28181/platform/PlatformController.java | 31 ++++++++++-- .../platform/bean/UpdateChannelParam.java | 11 +++++ .../vmanager/gb28181/play/PlayController.java | 2 - .../components/dialog/chooseChannelForGb.vue | 49 +++++++++++++------ .../dialog/chooseChannelForStream.vue | 45 +++++++++++------ 18 files changed, 234 insertions(+), 66 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java b/src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java index 3f5873583..31e568a36 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IDeviceChannelService.java @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.service; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; +import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; import java.util.List; @@ -38,4 +39,11 @@ public interface IDeviceChannelService { * @return */ ResourceBaceInfo getOverview(); + + /** + * 查询所有未分配的通道 + * @param platformId + * @return + */ + List queryAllChannelList(String platformId); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java b/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java index ffbba0072..314a38907 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IGbStreamService.java @@ -55,4 +55,18 @@ public interface IGbStreamService { int updateGbIdOrName(List streamPushItemForUpdate); DeviceChannel getDeviceChannelListByStreamWithStatus(GbStream gbStream, String catalogId, ParentPlatform platform); + + /** + * 查询所有未分配的通道 + * @param platformId + * @return + */ + List getAllGBChannels(String platformId); + + /** + * 移除所有关联的通道 + * @param platformId + * @param catalogId + */ + void delAllPlatformInfo(String platformId, String catalogId); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlatformChannelService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlatformChannelService.java index 739e6b864..49d74282c 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IPlatformChannelService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IPlatformChannelService.java @@ -19,4 +19,11 @@ public interface IPlatformChannelService { */ int updateChannelForGB(String platformId, List channelReduces, String catalogId); + /** + * 移除目录下的所有通道 + * @param platformId + * @param catalogId + * @return + */ + int delAllChannelForGB(String platformId, String catalogId); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java index 41b55ddc8..9db2d6830 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceChannelServiceImpl.java @@ -10,6 +10,7 @@ import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; +import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -168,4 +169,12 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService { public ResourceBaceInfo getOverview() { return channelMapper.getOverview(); } + + + @Override + public List queryAllChannelList(String platformId) { + return channelMapper.queryChannelListInAll(null, null, null, platformId, null); + } + + } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java index da11b164a..dc9d927c7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/GbStreamServiceImpl.java @@ -4,11 +4,11 @@ import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; +import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; import com.genersoft.iot.vmp.storager.dao.PlatformCatalogMapper; import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; -import com.genersoft.iot.vmp.service.IGbStreamService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.slf4j.Logger; @@ -19,7 +19,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.List; @@ -230,4 +229,35 @@ public class GbStreamServiceImpl implements IGbStreamService { deviceChannel.setSecrecy("0"); return deviceChannel; } + + @Override + public List getAllGBChannels(String platformId) { + + return gbStreamMapper.selectAll(platformId, null, null, null); + + } + + @Override + public void delAllPlatformInfo(String platformId, String catalogId) { + if (platformId == null) { + return ; + } + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId); + if (platform == null) { + return ; + } + if (ObjectUtils.isEmpty(catalogId)) { + catalogId = platform.getDeviceGBId(); + } + if (platformGbStreamMapper.delByPlatformAndCatalogId(platformId, catalogId) > 0) { + List gbStreams = platformGbStreamMapper.queryChannelInParentPlatformAndCatalog(platformId, catalogId); + List deviceChannelList = new ArrayList<>(); + for (GbStream gbStream : gbStreams) { + DeviceChannel deviceChannel = new DeviceChannel(); + deviceChannel.setChannelId(gbStream.getGbId()); + deviceChannelList.add(deviceChannel); + } + eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.DEL); + } + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java index 22d195efd..601ff5de4 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformChannelServiceImpl.java @@ -16,6 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.ObjectUtils; import java.util.ArrayList; import java.util.HashMap; @@ -105,4 +106,26 @@ public class PlatformChannelServiceImpl implements IPlatformChannelService { } return deviceChannelList; } + + @Override + public int delAllChannelForGB(String platformId, String catalogId) { + + int result; + if (platformId == null) { + return 0; + } + ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId); + if (platform == null) { + return 0; + } + if (ObjectUtils.isEmpty(catalogId)) { + catalogId = platform.getDeviceGBId(); + } + + if ((result = platformChannelMapper.delChannelForGBByCatalogId(platformId, catalogId)) > 0) { + List deviceChannels = platformChannelMapper.queryAllChannelInCatalog(platformId, catalogId); + eventPublisher.catalogEventPublish(platformId, deviceChannels, CatalogEvent.DEL); + } + return result; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java index ff20cef3b..53072b2db 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.storager.dao; -import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java index 8a5d4550c..6ea852e42 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/GbStreamMapper.java @@ -5,7 +5,6 @@ import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; -import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto; import org.apache.ibatis.annotations.*; import org.springframework.stereotype.Repository; @@ -169,4 +168,5 @@ public interface GbStreamMapper { @Select("SELECT status FROM stream_push WHERE app=#{app} AND stream=#{stream}") Boolean selectStatusForPush(String app, String stream); + } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java index e048f31e0..120ecb3e4 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformChannelMapper.java @@ -57,6 +57,9 @@ public interface PlatformChannelMapper { @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'") List queryChannelInParentPlatform(String platformId, String channelId); + @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE pgc.platformId='${platformId}' and pgc.catalogId=#{catalogId}") + List queryAllChannelInCatalog(String platformId, String catalogId); + @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " + " from device_channel dc left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId " + " where pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}") @@ -99,4 +102,9 @@ public interface PlatformChannelMapper { "DELETE FROM platform_gb_channel WHERE platformId=#{serverGBId}" + "") void delByPlatformId(String serverGBId); + + @Delete("") + int delChannelForGBByCatalogId(String platformId, String catalogId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java index 98afd6b77..13094b98d 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/PlatformGbStreamMapper.java @@ -105,4 +105,7 @@ public interface PlatformGbStreamMapper { "" + "") void delByAppAndStreamsByPlatformId(List gbStreams, String platformId); + + @Delete("DELETE FROM platform_gb_stream WHERE platformId=#{platformId} and catalogId=#{catalogId}") + int delByPlatformAndCatalogId(String platformId, String catalogId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java index 79edcf857..377b20f21 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStorageImpl.java @@ -1,13 +1,11 @@ package com.genersoft.iot.vmp.storager.impl; -import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.SipConfig; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; -import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; @@ -28,7 +26,6 @@ import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -761,18 +758,6 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage { return gbStreamMapper.updateStreamGPS(gpsMsgInfos); } - private List getDeviceChannelListByChannelReduceList(List channelReduces, String catalogId) { - List deviceChannelList = new ArrayList<>(); - if (channelReduces.size() > 0){ - for (ChannelReduce channelReduce : channelReduces) { - DeviceChannel deviceChannel = queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); - deviceChannel.setParental(1); - deviceChannel.setParentId(catalogId); - deviceChannelList.add(deviceChannel); - } - } - return deviceChannelList; - } private DeviceChannel getDeviceChannelByCatalog(PlatformCatalog catalog) { ParentPlatform platform = platformMapper.getParentPlatByServerGBId(catalog.getPlatformId()); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java index 3ba032a99..447944a7f 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/GbStreamController.java @@ -1,9 +1,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.gbStream; import com.genersoft.iot.vmp.gb28181.bean.GbStream; +import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.vmanager.gb28181.gbStream.bean.GbStreamParam; -import com.genersoft.iot.vmp.service.IGbStreamService; import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -12,9 +12,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import java.util.List; + @Tag(name = "视频流关联到级联平台") @CrossOrigin @RestController @@ -76,11 +77,14 @@ public class GbStreamController { @Operation(summary = "移除国标关联") @DeleteMapping(value = "/del") @ResponseBody - public Object del(@RequestBody GbStreamParam gbStreamParam){ - if (gbStreamService.delPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getGbStreams())) { - return "success"; + public void del(@RequestBody GbStreamParam gbStreamParam){ + + if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().size() == 0) { + if (gbStreamParam.isAll()) { + gbStreamService.delAllPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId()); + } }else { - return "fail"; + gbStreamService.delPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getGbStreams()); } } @@ -93,11 +97,14 @@ public class GbStreamController { @Operation(summary = "保存国标关联") @PostMapping(value = "/add") @ResponseBody - public Object add(@RequestBody GbStreamParam gbStreamParam){ - if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId())) { - return "success"; + public void add(@RequestBody GbStreamParam gbStreamParam){ + if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().size() == 0) { + if (gbStreamParam.isAll()) { + List allGBChannels = gbStreamService.getAllGBChannels(gbStreamParam.getPlatformId()); + gbStreamService.addPlatformInfo(allGBChannels, gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId()); + } }else { - return "fail"; + gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId()); } } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java index 161f2e7f4..3705c7090 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/gbStream/bean/GbStreamParam.java @@ -14,6 +14,9 @@ public class GbStreamParam { @Schema(description = "目录ID") private String catalogId; + @Schema(description = "关联所有通道") + private boolean all; + @Schema(description = "流国标信息列表") private List gbStreams; @@ -40,4 +43,12 @@ public class GbStreamParam { public void setGbStreams(List gbStreams) { this.gbStreams = gbStreams; } + + public boolean isAll() { + return all; + } + + public void setAll(boolean all) { + this.all = all; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java index 3bd8aec95..40b65c33b 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/PlatformController.java @@ -10,8 +10,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; -import com.genersoft.iot.vmp.service.IPlatformChannelService; -import com.genersoft.iot.vmp.service.IPlatformService; +import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; @@ -72,6 +71,12 @@ public class PlatformController { @Autowired private IPlatformService platformService; + @Autowired + private IDeviceChannelService deviceChannelService; + + @Autowired + private IGbStreamService gbStreamService; + /** * 获取国标服务的配置 * @@ -379,7 +384,16 @@ public class PlatformController { if (logger.isDebugEnabled()) { logger.debug("给上级平台添加国标通道API调用"); } - int result = platformChannelService.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId()); + int result = 0; + if (param.getChannelReduces() == null || param.getChannelReduces().size() == 0) { + if (param.isAll()) { + logger.info("[国标级联]添加所有通道到上级平台, {}", param.getPlatformId()); + List allChannelForDevice = deviceChannelService.queryAllChannelList(param.getPlatformId()); + result = platformChannelService.updateChannelForGB(param.getPlatformId(), allChannelForDevice, param.getCatalogId()); + } + }else { + result = platformChannelService.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId()); + } if (result <= 0) { throw new ControllerException(ErrorCode.ERROR100); } @@ -399,8 +413,15 @@ public class PlatformController { if (logger.isDebugEnabled()) { logger.debug("给上级平台删除国标通道API调用"); } - int result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces()); - + int result = 0; + if (param.getChannelReduces() == null || param.getChannelReduces().size() == 0) { + if (param.isAll()) { + logger.info("[国标级联]移除所有通道,上级平台, {}", param.getPlatformId()); + result = platformChannelService.delAllChannelForGB(param.getPlatformId(), param.getCatalogId()); + } + }else { + result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces()); + } if (result <= 0) { throw new ControllerException(ErrorCode.ERROR100); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java index 01762d9c8..2d598e44d 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/platform/bean/UpdateChannelParam.java @@ -17,6 +17,9 @@ public class UpdateChannelParam { @Schema(description = "目录的国标编号") private String catalogId; + @Schema(description = "处理所有通道") + private boolean all; + @Schema(description = "") private List channelReduces; @@ -43,4 +46,12 @@ public class UpdateChannelParam { public void setCatalogId(String catalogId) { this.catalogId = catalogId; } + + public boolean isAll() { + return all; + } + + public void setAll(boolean all) { + this.all = all; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index 885f121a0..9fed0c59d 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -134,7 +134,6 @@ public class PlayController { return result; } - @Operation(summary = "停止点播") @Parameter(name = "deviceId", description = "设备国标编号", required = true) @Parameter(name = "channelId", description = "通道国标编号", required = true) @@ -171,7 +170,6 @@ public class PlayController { json.put("deviceId", deviceId); json.put("channelId", channelId); return json; - } /** diff --git a/web_src/src/components/dialog/chooseChannelForGb.vue b/web_src/src/components/dialog/chooseChannelForGb.vue index a4dc5e08d..fc97b4ce9 100644 --- a/web_src/src/components/dialog/chooseChannelForGb.vue +++ b/web_src/src/components/dialog/chooseChannelForGb.vue @@ -18,8 +18,10 @@ - 批量移除 - 批量添加 + 批量移除 + 批量添加 + 全部添加 + 全部移除 @@ -115,13 +117,15 @@ export default { this.initData(); }, add: function (row) { + let all = typeof(row) === "undefined" this.getCatalogFromUser((catalogId)=> { this.$axios({ method:"post", url:"/api/platform/update_channel_for_gb", data:{ platformId: this.platformId, - channelReduces: [row], + all: all, + channelReduces: all?[]:[row], catalogId: catalogId } }).then((res)=>{ @@ -134,21 +138,34 @@ export default { }, remove: function (row) { - console.log(row) + let all = typeof(row) === "undefined" + this.$confirm(`确定移除${all?"所有通道":""}吗?`, '提示', { + dangerouslyUseHTMLString: true, + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + console.log(row) + + this.$axios({ + method:"delete", + url:"/api/platform/del_channel_for_gb", + data:{ + platformId: this.platformId, + all: all, + channelReduces: all?[]:[row], + } + }).then((res)=>{ + console.log("移除成功") + this.getChannelList(); + }).catch(function (error) { + console.log(error); + }); + }).catch(() => { - this.$axios({ - method:"delete", - url:"/api/platform/del_channel_for_gb", - data:{ - platformId: this.platformId, - channelReduces: [row] - } - }).then((res)=>{ - console.log("移除成功") - this.getChannelList(); - }).catch(function (error) { - console.log(error); }); + + }, // checkedChange: function (val) { // let that = this; diff --git a/web_src/src/components/dialog/chooseChannelForStream.vue b/web_src/src/components/dialog/chooseChannelForStream.vue index 8d63dbf7d..6c4653b59 100644 --- a/web_src/src/components/dialog/chooseChannelForStream.vue +++ b/web_src/src/components/dialog/chooseChannelForStream.vue @@ -24,6 +24,8 @@ 批量移除 批量添加 + 全部添加 + 全部移除 @@ -128,6 +130,7 @@ export default { }, add: function (row, scope) { + let all = typeof(row) === "undefined" this.getCatalogFromUser((catalogId)=>{ this.$axios({ method:"post", @@ -135,7 +138,8 @@ export default { data:{ platformId: this.platformId, catalogId: catalogId, - gbStreams: [row], + all: all, + gbStreams: all?[]:[row], } }).then((res)=>{ console.log("保存成功") @@ -149,20 +153,33 @@ export default { }, remove: function (row, scope) { - this.$axios({ - method:"delete", - url:"/api/gbStream/del", - data:{ - platformId: this.platformId, - gbStreams: [row], - } - }).then((res)=>{ - console.log("移除成功") - // this.gbStreams.splice(scope.$index,1) - this.getChannelList(); - }).catch(function (error) { - console.log(error); + let all = typeof(row) === "undefined" + this.$confirm(`确定移除${all?"所有通道":""}吗?`, '提示', { + dangerouslyUseHTMLString: true, + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + + this.$axios({ + method:"delete", + url:"/api/gbStream/del", + data:{ + platformId: this.platformId, + all: all, + gbStreams: all?[]:[row], + } + }).then((res)=>{ + console.log("移除成功") + // this.gbStreams.splice(scope.$index,1) + this.getChannelList(); + }).catch(function (error) { + console.log(error); + }); + }).catch(() => { + }); + }, getChannelList: function () { let that = this; From 14699711028f0d157eddfb0432e26ab91f1b4493 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 22 Nov 2022 15:02:25 +0800 Subject: [PATCH 02/20] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E4=B8=8A=E7=BA=BF=E6=97=B6=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9F=A5=E8=AF=A2=E9=80=9A=E9=81=93=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=80=9A=E9=81=93=E5=88=B7=E6=96=B0=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/conf/UserSetting.java | 10 ++++ .../vmp/service/impl/DeviceServiceImpl.java | 20 ++++---- src/main/resources/all-application.yml | 2 + .../components/dialog/SyncChannelProgress.vue | 48 ++++++++----------- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index ca204d93e..eeee438fd 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -41,6 +41,8 @@ public class UserSetting { private Boolean gbSendStreamStrict = Boolean.FALSE; + private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; + private String serverId = "000000"; private String thirdPartyGBIdReg = "[\\s\\S]*"; @@ -186,4 +188,12 @@ public class UserSetting { public void setGbSendStreamStrict(Boolean gbSendStreamStrict) { this.gbSendStreamStrict = gbSendStreamStrict; } + + public Boolean getSyncChannelOnDeviceOnline() { + return syncChannelOnDeviceOnline; + } + + public void setSyncChannelOnDeviceOnline(Boolean syncChannelOnDeviceOnline) { + this.syncChannelOnDeviceOnline = syncChannelOnDeviceOnline; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index ac48e4df3..d25e537e6 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -1,6 +1,7 @@ package com.genersoft.iot.vmp.service.impl; import com.genersoft.iot.vmp.conf.DynamicTask; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; @@ -12,7 +13,6 @@ import com.genersoft.iot.vmp.service.IDeviceChannelService; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.storager.dao.PlatformChannelMapper; @@ -78,7 +78,7 @@ public class DeviceServiceImpl implements IDeviceService { TransactionDefinition transactionDefinition; @Autowired - private IVideoManagerStorage storage; + private UserSetting userSetting; @Autowired private ISIPCommander commander; @@ -120,16 +120,18 @@ public class DeviceServiceImpl implements IDeviceService { if(device.getOnline() == 0){ device.setOnline(1); device.setCreateTime(now); - logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId()); deviceMapper.update(device); redisCatchStorage.updateDevice(device); - try { - commander.deviceInfoQuery(device); - } catch (InvalidArgumentException | SipException | ParseException e) { - logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage()); + if (userSetting.getSyncChannelOnDeviceOnline()) { + logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId()); + try { + commander.deviceInfoQuery(device); + } catch (InvalidArgumentException | SipException | ParseException e) { + logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage()); + } + sync(device); + // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台 } - sync(device); - // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台 }else { if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).size() == 0) { logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId()); diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 330391537..e8b28d0d7 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -195,6 +195,8 @@ user-settings: # 国标级联发流严格模式,严格模式会使用与sdp信息中一致的端口发流,端口共享media.rtp.port-range,这会损失一些性能, # 非严格模式使用随机端口发流,性能更好, 默认关闭 gb-send-stream-strict: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: false # 关闭在线文档(生产环境建议关闭) springdoc: diff --git a/web_src/src/components/dialog/SyncChannelProgress.vue b/web_src/src/components/dialog/SyncChannelProgress.vue index c972a46cc..e1c9fe01b 100644 --- a/web_src/src/components/dialog/SyncChannelProgress.vue +++ b/web_src/src/components/dialog/SyncChannelProgress.vue @@ -63,37 +63,29 @@ export default { } if (res.data.data != null) { - if (res.data.syncIng) { + if (res.data.data.syncIng) { if (res.data.data.total == 0) { - if (res.data.data.errorMsg !== null ){ - this.msg = res.data.data.errorMsg; - this.syncStatus = "exception" - }else { - this.msg = `等待同步中`; - this.timmer = setTimeout(this.getProgress, 300) - } - }else { - if (res.data.data.total == res.data.data.current) { - this.syncStatus = "success" - this.percentage = 100; - this.msg = '同步成功'; - }else { - if (res.data.data.errorMsg !== null ){ - this.msg = res.data.data.errorMsg; - this.syncStatus = "exception" - }else { - this.total = res.data.data.total; - this.current = res.data.data.current; - this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100; - this.msg = `同步中...[${res.data.data.current}/${res.data.data.total}]`; - this.timmer = setTimeout(this.getProgress, 300) - } - } + this.msg = `等待同步中`; + this.timmer = setTimeout(this.getProgress, 300) + }else { + this.total = res.data.data.total; + this.current = res.data.data.current; + this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100; + this.msg = `同步中...[${res.data.data.current}/${res.data.data.total}]`; + this.timmer = setTimeout(this.getProgress, 300) } }else { - this.syncStatus = "success" - this.percentage = 100; - this.msg = '同步成功'; + if (res.data.data.errorMsg){ + this.msg = res.data.data.errorMsg; + this.syncStatus = "exception" + }else { + this.syncStatus = "success" + this.percentage = 100; + this.msg = '同步成功'; + setTimeout(()=>{ + this.showDialog = false; + }, 3000) + } } } }else { From 8ea6e192d9f986045adbaeab54ea062938e9693e Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 22 Nov 2022 17:17:35 +0800 Subject: [PATCH 03/20] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8B=89=E6=B5=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E8=A1=A8=E5=8D=95=E4=BB=A5=E5=8F=8A=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql.sql | 2 +- sql/update.sql | 5 ++ .../iot/vmp/conf/GlobalExceptionHandler.java | 10 +-- .../vmp/media/zlm/ZLMHttpHookListener.java | 1 + .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 12 +-- .../vmp/media/zlm/dto/StreamProxyItem.java | 33 +++----- .../service/impl/StreamProxyServiceImpl.java | 31 ++----- .../vmp/storager/dao/StreamProxyMapper.java | 6 +- web_src/src/components/StreamProxyList.vue | 69 +++++++--------- .../src/components/dialog/StreamProxyEdit.vue | 80 +++++++++---------- 10 files changed, 108 insertions(+), 141 deletions(-) diff --git a/sql/mysql.sql b/sql/mysql.sql index b5ca0161e..869482cc5 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -446,7 +446,7 @@ CREATE TABLE `stream_proxy` ( `ffmpeg_cmd_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `rtp_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, - `enable_hls` bit(1) DEFAULT NULL, + `enable_audio` bit(1) DEFAULT NULL, `enable_mp4` bit(1) DEFAULT NULL, `enable` bit(1) NOT NULL, `status` bit(1) NOT NULL, diff --git a/sql/update.sql b/sql/update.sql index 405cb3a75..877e24779 100644 --- a/sql/update.sql +++ b/sql/update.sql @@ -36,3 +36,8 @@ alter table device alter table device modify hostAddress varchar(50) null; + +alter table stream_proxy + change enable_hls enable_audio bit null; + + diff --git a/src/main/java/com/genersoft/iot/vmp/conf/GlobalExceptionHandler.java b/src/main/java/com/genersoft/iot/vmp/conf/GlobalExceptionHandler.java index 0c7c3d2f7..728afb96b 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/GlobalExceptionHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/GlobalExceptionHandler.java @@ -1,12 +1,12 @@ package com.genersoft.iot.vmp.conf; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @@ -40,8 +40,8 @@ public class GlobalExceptionHandler { */ @ExceptionHandler(ControllerException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public WVPResult exceptionHandler(ControllerException e) { - return WVPResult.fail(e.getCode(), e.getMsg()); + public ResponseEntity> exceptionHandler(ControllerException e) { + return new ResponseEntity<>(WVPResult.fail(e.getCode(), e.getMsg()), HttpStatus.OK); } /** @@ -51,7 +51,7 @@ public class GlobalExceptionHandler { */ @ExceptionHandler(BadCredentialsException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) - public WVPResult exceptionHandler(BadCredentialsException e) { - return WVPResult.fail(ErrorCode.ERROR100.getCode(), e.getMessage()); + public ResponseEntity> exceptionHandler(BadCredentialsException e) { + return new ResponseEntity<>(WVPResult.fail(ErrorCode.ERROR100.getCode(), e.getMessage()), HttpStatus.OK); } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index a3145540f..54a28905e 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -505,6 +505,7 @@ public class ZLMHttpHookListener { // 修改数据 streamProxyService.stop(param.getApp(), param.getStream()); }else { + // 无人观看不做处理 ret.put("close", false); } return ret; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 7d3510ff4..bf9551d4e 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -236,14 +236,13 @@ public class ZLMRESTfulUtils { } public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms, - boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ + boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ logger.info(src_url); logger.info(dst_url); Map param = new HashMap<>(); param.put("src_url", src_url); param.put("dst_url", dst_url); param.put("timeout_ms", timeout_ms); - param.put("enable_hls", enable_hls); param.put("enable_mp4", enable_mp4); param.put("ffmpeg_cmd_key", ffmpeg_cmd_key); return sendPost(mediaServerItem, "addFFmpegSource",param, null); @@ -287,19 +286,14 @@ public class ZLMRESTfulUtils { return sendPost(mediaServerItem, "restartServer",null, null); } - public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { + public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type) { Map param = new HashMap<>(); param.put("vhost", "__defaultVhost__"); param.put("app", app); param.put("stream", stream); param.put("url", url); - param.put("enable_hls", enable_hls?1:0); param.put("enable_mp4", enable_mp4?1:0); - param.put("enable_rtmp", 1); - param.put("enable_fmp4", 1); - param.put("enable_audio", 1); - param.put("enable_rtsp", 1); - param.put("add_mute_audio", 1); + param.put("enable_audio", enable_audio?1:0); param.put("rtp_type", rtp_type); return sendPost(mediaServerItem, "addStreamProxy",param, null); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java index ea0bdcaac..b0e74e8f1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java @@ -31,8 +31,8 @@ public class StreamProxyItem extends GbStream { private String rtp_type; @Schema(description = "是否启用") private boolean enable; - @Schema(description = "是否启用HLS") - private boolean enable_hls; + @Schema(description = "是否启用音频") + private boolean enable_audio; @Schema(description = "是否启用MP4") private boolean enable_mp4; @Schema(description = "是否 无人观看时删除") @@ -40,8 +40,6 @@ public class StreamProxyItem extends GbStream { @Schema(description = "是否 无人观看时自动停用") private boolean enable_disable_none_reader; - @Schema(description = "上级平台国标ID") - private String platformGbId; @Schema(description = "创建时间") private String createTime; @@ -139,14 +137,6 @@ public class StreamProxyItem extends GbStream { this.enable = enable; } - public boolean isEnable_hls() { - return enable_hls; - } - - public void setEnable_hls(boolean enable_hls) { - this.enable_hls = enable_hls; - } - public boolean isEnable_mp4() { return enable_mp4; } @@ -155,19 +145,12 @@ public class StreamProxyItem extends GbStream { this.enable_mp4 = enable_mp4; } - - public String getPlatformGbId() { - return platformGbId; - } - - public void setPlatformGbId(String platformGbId) { - this.platformGbId = platformGbId; - } - + @Override public String getCreateTime() { return createTime; } + @Override public void setCreateTime(String createTime) { this.createTime = createTime; } @@ -187,4 +170,12 @@ public class StreamProxyItem extends GbStream { public void setEnable_disable_none_reader(boolean enable_disable_none_reader) { this.enable_disable_none_reader = enable_disable_none_reader; } + + public boolean isEnable_audio() { + return enable_audio; + } + + public void setEnable_audio(boolean enable_audio) { + this.enable_audio = enable_audio; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 3183e3de9..7dcd7f2cf 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -5,23 +5,22 @@ import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.exception.ControllerException; -import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; +import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; +import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper; -import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; @@ -35,7 +34,9 @@ import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.util.ObjectUtils; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 视频代理业务 @@ -107,7 +108,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { param.getStream() ); param.setDst_url(dstUrl); StringBuffer resultMsg = new StringBuffer(); - boolean streamLive = false; param.setMediaServerId(mediaInfo.getId()); boolean saveResult; // 更新 @@ -124,7 +124,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (param.isEnable()) { JSONObject jsonObject = addStreamProxyToZlm(param); if (jsonObject == null || jsonObject.getInteger("code") != 0) { - streamLive = false; resultMsg.append(", 但是启用失败,请检查流地址是否可用"); param.setEnable(false); // 直接移除 @@ -134,28 +133,12 @@ public class StreamProxyServiceImpl implements IStreamProxyService { updateStreamProxy(param); } - }else { - streamLive = true; resultForStreamInfo = mediaService.getStreamInfoByAppAndStream( mediaInfo, param.getApp(), param.getStream(), null, null); } } - if ( !ObjectUtils.isEmpty(param.getPlatformGbId()) && streamLive) { - List gbStreams = new ArrayList<>(); - gbStreams.add(param); - if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId(), param.getCatalogId())){ - return resultForStreamInfo; - }else { - resultMsg.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败"); - throw new ControllerException(ErrorCode.ERROR100.getCode(), resultMsg.toString()); - } - }else { - if (!streamLive) { - throw new ControllerException(ErrorCode.ERROR100.getCode(), resultMsg.toString()); - } - } return resultForStreamInfo; } @@ -245,10 +228,10 @@ public class StreamProxyServiceImpl implements IStreamProxyService { } if ("default".equals(param.getType())){ result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(), - param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type()); + param.isEnable_audio(), param.isEnable_mp4(), param.getRtp_type()); }else if ("ffmpeg".equals(param.getType())) { result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrc_url(), param.getDst_url(), - param.getTimeout_ms() + "", param.isEnable_hls(), param.isEnable_mp4(), + param.getTimeout_ms() + "", param.isEnable_audio(), param.isEnable_mp4(), param.getFfmpeg_cmd_key()); } return result; diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java index 448a358f4..4ed214dac 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java @@ -12,9 +12,9 @@ import java.util.List; public interface StreamProxyMapper { @Insert("INSERT INTO stream_proxy (type, name, app, stream,mediaServerId, url, src_url, dst_url, " + - "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" + + "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_audio, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" + "('${type}','${name}', '${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " + - "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable}, ${status}, " + + "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_audio}, ${enable_mp4}, ${enable}, ${status}, " + "${enable_remove_none_reader}, ${enable_disable_none_reader}, '${createTime}' )") int add(StreamProxyItem streamProxyDto); @@ -30,7 +30,7 @@ public interface StreamProxyMapper { "timeout_ms=#{timeout_ms}, " + "ffmpeg_cmd_key=#{ffmpeg_cmd_key}, " + "rtp_type=#{rtp_type}, " + - "enable_hls=#{enable_hls}, " + + "enable_audio=#{enable_audio}, " + "enable=#{enable}, " + "status=#{status}, " + "enable_remove_none_reader=#{enable_remove_none_reader}, " + diff --git a/web_src/src/components/StreamProxyList.vue b/web_src/src/components/StreamProxyList.vue index 5eff9d50c..47ccde8b6 100644 --- a/web_src/src/components/StreamProxyList.vue +++ b/web_src/src/components/StreamProxyList.vue @@ -32,7 +32,7 @@ @@ -55,15 +55,15 @@ - + - + - + @@ -131,7 +132,6 @@ currentPage:1, count:15, total:0, - getListLoading: false, startBtnLoading: false }; }, @@ -139,7 +139,7 @@ }, mounted() { this.initData(); - this.updateLooper = setInterval(this.initData, 1000); + this.startUpdateList() }, destroyed() { this.$destroy('videojs'); @@ -149,6 +149,12 @@ initData: function() { this.getStreamProxyList(); }, + stopUpdateList: function (){ + window.clearInterval(this.updateLooper) + }, + startUpdateList: function (){ + this.updateLooper = setInterval(this.initData, 1000); + }, currentChange: function(val){ this.currentPage = val; this.getStreamProxyList(); @@ -159,7 +165,6 @@ }, getStreamProxyList: function() { let that = this; - this.getListLoading = true; this.$axios({ method: 'get', url:`/api/proxy/list`, @@ -175,23 +180,18 @@ } that.streamProxyList = res.data.data.list; } - that.getListLoading = false; }).catch(function (error) { console.log(error); - that.getListLoading = false; }); }, addStreamProxy: function(){ this.$refs.streamProxyEdit.openDialog(null, this.initData) }, addOnvif: function(){ - this.getListLoading = true; - this.getListLoading = true; this.$axios({ method: 'get', url:`/api/onvif/search?timeout=3000`, }).then((res) =>{ - this.getListLoading = false; if (res.data.code === 0 ){ if (res.data.data.length > 0) { this.$refs.onvifEdit.openDialog(res.data.data, (url)=>{ @@ -208,7 +208,6 @@ } }).catch((error)=> { - this.getListLoading = false; this.$message.error(error.response.data.msg); }); @@ -217,7 +216,6 @@ }, play: function(row){ let that = this; - this.getListLoading = true; this.$axios({ method: 'get', url:`/api/push/getPlayUrl`, @@ -227,7 +225,6 @@ mediaServerId: row.mediaServerId } }).then(function (res) { - that.getListLoading = false; if (res.data.code === 0) { that.$refs.devicePlayer.openDialog("streamPlay", null, null, { streamInfo: res.data.data, @@ -243,13 +240,11 @@ }).catch(function (error) { console.log(error); - that.getListLoading = false; }); }, deleteStreamProxy: function(row){ let that = this; - this.getListLoading = true; that.$axios({ method:"delete", url:"/api/proxy/del", @@ -258,16 +253,13 @@ stream: row.stream } }).then((res)=>{ - that.getListLoading = false; that.initData() }).catch(function (error) { console.log(error); - that.getListLoading = false; }); }, start: function(row){ - let that = this; - this.getListLoading = true; + this.stopUpdateList() this.$set(row, 'startBtnLoading', true) this.$axios({ method: 'get', @@ -276,28 +268,31 @@ app: row.app, stream: row.stream } - }).then(function (res) { - that.getListLoading = false; - that.$set(row, 'startBtnLoading', false) + }).then((res)=> { if (res.data.code === 0){ - that.initData() + this.initData() }else { - that.$message({ + this.$message({ showClose: true, - message: "保存失败,请检查地址是否可用!", + message: "启动失败,请检查地址是否可用!", type: "error", }); } - - }).catch(function (error) { + this.$set(row, 'startBtnLoading', false) + this.startUpdateList() + }).catch((error)=> { console.log(error); - that.getListLoading = false; - that.$set(row, 'startBtnLoading', false) + this.$message({ + showClose: true, + message: "启动失败,请检查地址是否可用!", + type: "error", + }); + this.$set(row, 'startBtnLoading', false) + this.startUpdateList() }); }, stop: function(row){ let that = this; - this.getListLoading = true; this.$axios({ method: 'get', url:`/api/proxy/stop`, @@ -306,11 +301,9 @@ stream: row.stream } }).then(function (res) { - that.getListLoading = false; that.initData() }).catch(function (error) { console.log(error); - that.getListLoading = false; }); }, refresh: function (){ diff --git a/web_src/src/components/dialog/StreamProxyEdit.vue b/web_src/src/components/dialog/StreamProxyEdit.vue index 1270999fd..76011fac3 100644 --- a/web_src/src/components/dialog/StreamProxyEdit.vue +++ b/web_src/src/components/dialog/StreamProxyEdit.vue @@ -83,31 +83,23 @@ - - - - - {{ item.name }} - {{ item.serverGBId }} - - - + + + + + + +
- - - - - + +
@@ -169,10 +161,11 @@ export default { gbId: null, rtp_type: null, enable: true, - enable_hls: true, + enable_audio: true, enable_mp4: false, + none_reader: null, enable_remove_none_reader: false, - enable_disable_none_reader: true, + enable_disable_none_reader: false, platformGbId: null, mediaServerId: null, }, @@ -196,6 +189,7 @@ export default { this.listChangeCallback = callback; if (proxyParam != null) { this.proxyParam = proxyParam; + this.proxyParam.none_reader = null; } let that = this; @@ -233,26 +227,26 @@ export default { }, onSubmit: function () { this.dialogLoading = true; - var that = this; - that.$axios({ + this.noneReaderHandler(); + this.$axios({ method: 'post', url:`/api/proxy/save`, - data: that.proxyParam - }).then(function (res) { - that.dialogLoading = false; + data: this.proxyParam + }).then((res)=> { + this.dialogLoading = false; if (typeof (res.data.code) != "undefined" && res.data.code === 0) { - that.$message({ + this.$message({ showClose: true, message: res.data.msg, type: "success", }); - that.showDialog = false; - if (that.listChangeCallback != null) { - that.listChangeCallback(); - that.dialogLoading = false; + this.showDialog = false; + if (this.listChangeCallback != null) { + this.listChangeCallback(); + this.dialogLoading = false; } } - }).catch(function (error) { + }).catch((error) =>{ console.log(error); this.dialogLoading = false; }); @@ -280,12 +274,18 @@ export default { this.platform.expires = "300"; } }, - removeNoneReader: function(checked) { - this.proxyParam.enable_disable_none_reader = !checked; + noneReaderHandler: function() { + if (this.proxyParam.none_reader === null || this.proxyParam.none_reader === "0") { + this.proxyParam.enable_disable_none_reader = false; + this.proxyParam.enable_remove_none_reader = false; + }else if (this.proxyParam.none_reader === "1"){ + this.proxyParam.enable_disable_none_reader = true; + this.proxyParam.enable_remove_none_reader = false; + }else if (this.proxyParam.none_reader ==="2"){ + this.proxyParam.enable_disable_none_reader = false; + this.proxyParam.enable_remove_none_reader = true; + } }, - disableNoneReaderHandType: function(checked) { - this.proxyParam.enable_remove_none_reader = !checked; - } }, }; From 278264a2c6492d94ffb668cb75c3494f426074ea Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 22 Nov 2022 17:30:49 +0800 Subject: [PATCH 04/20] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8B=89=E6=B5=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java | 3 +++ .../iot/vmp/vmanager/streamProxy/StreamProxyController.java | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java index 7dcd7f2cf..a2fd08840 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java @@ -284,6 +284,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { result = true; streamProxy.setEnable(true); updateStreamProxy(streamProxy); + }else { + logger.info("启用代理失败: {}/{}->{}({})", app, stream, jsonObject.getString("msg"), + streamProxy.getSrc_url() == null? streamProxy.getUrl():streamProxy.getSrc_url()); } } return result; diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index 95b6cf39b..d1368d818 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -109,7 +109,6 @@ public class StreamProxyController { logger.info("启用代理: " + app + "/" + stream); boolean result = streamProxyService.start(app, stream); if (!result) { - logger.info("启用代理失败: " + app + "/" + stream); throw new ControllerException(ErrorCode.ERROR100); } } From fa2ccb4ec8737df8718f1507bdd290fc7b5dd144 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 25 Nov 2022 10:50:16 +0800 Subject: [PATCH 05/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E7=AB=AF=E5=8F=A3=E9=85=8D=E7=BD=AE=E4=B8=8D=E5=85=A8=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E5=89=8D=E7=AB=AF=E6=92=AD=E6=94=BE=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=BC=B9=E5=87=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 108 +++++++++++++----- .../iot/vmp/gb28181/bean/SendRtpItem.java | 15 ++- .../request/impl/AckRequestProcessor.java | 4 +- .../request/impl/InviteRequestProcessor.java | 13 +-- .../vmp/media/zlm/ZLMRTPServerFactory.java | 6 +- .../vmp/service/bean/RequestSendItemMsg.java | 17 ++- .../redisMsg/RedisGbPlayMsgListener.java | 6 +- .../src/components/dialog/devicePlayer.vue | 44 +++---- 8 files changed, 144 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 460f418cd..8311745c2 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -169,25 +169,31 @@ public class StreamInfo implements Serializable, Cloneable{ public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s/%s", app, stream, callIdParam); - this.rtmp = new StreamURL("rtmp", host, port, file); - if (sslPort != 0) { + if (port > 0) { + this.rtmp = new StreamURL("rtmp", host, port, file); + } + if (sslPort > 0) { this.rtmps = new StreamURL("rtmps", host, sslPort, file); } } public void setRtsp(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s/%s", app, stream, callIdParam); - this.rtsp = new StreamURL("rtsp", host, port, file); - if (sslPort != 0) { + if (port > 0) { + this.rtsp = new StreamURL("rtsp", host, port, file); + } + if (sslPort > 0) { this.rtsps = new StreamURL("rtsps", host, sslPort, file); } } public void setFlv(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s.live.flv%s", app, stream, callIdParam); - this.flv = new StreamURL("http", host, port, file); + if (port > 0) { + this.flv = new StreamURL("http", host, port, file); + } this.ws_flv = new StreamURL("ws", host, port, file); - if (sslPort != 0) { + if (sslPort > 0) { this.https_flv = new StreamURL("https", host, sslPort, file); this.wss_flv = new StreamURL("wss", host, sslPort, file); } @@ -195,9 +201,11 @@ public class StreamInfo implements Serializable, Cloneable{ public void setFmp4(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s.live.mp4%s", app, stream, callIdParam); - this.fmp4 = new StreamURL("http", host, port, file); - this.ws_fmp4 = new StreamURL("ws", host, port, file); - if (sslPort != 0) { + if (port > 0) { + this.fmp4 = new StreamURL("http", host, port, file); + this.ws_fmp4 = new StreamURL("ws", host, port, file); + } + if (sslPort > 0) { this.https_fmp4 = new StreamURL("https", host, sslPort, file); this.wss_fmp4 = new StreamURL("wss", host, sslPort, file); } @@ -205,9 +213,11 @@ public class StreamInfo implements Serializable, Cloneable{ public void setHls(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s/hls.m3u8%s", app, stream, callIdParam); - this.hls = new StreamURL("http", host, port, file); - this.ws_hls = new StreamURL("ws", host, port, file); - if (sslPort != 0) { + if (port > 0) { + this.hls = new StreamURL("http", host, port, file); + this.ws_hls = new StreamURL("ws", host, port, file); + } + if (sslPort > 0) { this.https_hls = new StreamURL("https", host, sslPort, file); this.wss_hls = new StreamURL("wss", host, sslPort, file); } @@ -215,9 +225,12 @@ public class StreamInfo implements Serializable, Cloneable{ public void setTs(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s.live.ts%s", app, stream, callIdParam); - this.ts = new StreamURL("http", host, port, file); - this.ws_ts = new StreamURL("ws", host, port, file); - if (sslPort != 0) { + + if (port > 0) { + this.ts = new StreamURL("http", host, port, file); + this.ws_ts = new StreamURL("ws", host, port, file); + } + if (sslPort > 0) { this.https_ts = new StreamURL("https", host, sslPort, file); this.wss_ts = new StreamURL("wss", host, sslPort, file); } @@ -225,41 +238,78 @@ public class StreamInfo implements Serializable, Cloneable{ public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam) { String file = String.format("index/api/webrtc?app=%s&stream=%s&type=play%s", app, stream, callIdParam); - this.rtc = new StreamURL("http", host, port, file); - if (sslPort != 0) { + if (port > 0) { + this.rtc = new StreamURL("http", host, port, file); + } + if (sslPort > 0) { this.rtcs = new StreamURL("https", host, sslPort, file); } } public void channgeStreamIp(String localAddr) { - this.flv.setHost(localAddr); - this.ws_flv.setHost(localAddr); - this.hls.setHost(localAddr); - this.ws_hls.setHost(localAddr); - this.ts.setHost(localAddr); - this.ws_ts.setHost(localAddr); - this.fmp4.setHost(localAddr); - this.ws_fmp4.setHost(localAddr); - this.rtc.setHost(localAddr); + if (this.flv != null) { + this.flv.setHost(localAddr); + } + if (this.ws_flv != null ){ + this.ws_flv.setHost(localAddr); + } + if (this.hls != null ) { + this.hls.setHost(localAddr); + } + if (this.ws_hls != null ) { + this.ws_hls.setHost(localAddr); + } + if (this.ts != null ) { + this.ts.setHost(localAddr); + } + if (this.ws_ts != null ) { + this.ws_ts.setHost(localAddr); + } + if (this.fmp4 != null ) { + this.fmp4.setHost(localAddr); + } + if (this.ws_fmp4 != null ) { + this.ws_fmp4.setHost(localAddr); + } + if (this.rtc != null ) { + this.rtc.setHost(localAddr); + } if (this.https_flv != null) { this.https_flv.setHost(localAddr); + } + if (this.wss_flv != null) { this.wss_flv.setHost(localAddr); + } + if (this.https_hls != null) { this.https_hls.setHost(localAddr); + } + if (this.wss_hls != null) { this.wss_hls.setHost(localAddr); + } + if (this.wss_ts != null) { this.wss_ts.setHost(localAddr); + } + if (this.https_fmp4 != null) { this.https_fmp4.setHost(localAddr); + } + if (this.wss_fmp4 != null) { this.wss_fmp4.setHost(localAddr); + } + if (this.rtcs != null) { this.rtcs.setHost(localAddr); } - this.rtsp.setHost(localAddr); + if (this.rtsp != null) { + this.rtsp.setHost(localAddr); + } if (this.rtsps != null) { this.rtsps.setHost(localAddr); } - this.rtmp.setHost(localAddr); + if (this.rtmp != null) { + this.rtmp.setHost(localAddr); + } if (this.rtmps != null) { this.rtmps.setHost(localAddr); } - } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java index 8f61bc969..c1fe2c1fe 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/SendRtpItem.java @@ -1,7 +1,5 @@ package com.genersoft.iot.vmp.gb28181.bean; -import gov.nist.javax.sip.message.SIPRequest; - public class SendRtpItem { /** @@ -108,6 +106,11 @@ public class SendRtpItem { */ private boolean onlyAudio = false; + /** + * 是否开启rtcp保活 + */ + private boolean rtcp = false; + /** * 播放类型 @@ -281,4 +284,12 @@ public class SendRtpItem { public void setToTag(String toTag) { this.toTag = toTag; } + + public boolean isRtcp() { + return rtcp; + } + + public void setRtcp(boolean rtcp) { + this.rtcp = rtcp; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java index 45e42b2d9..7a26e7836 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java @@ -120,9 +120,9 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In param.put("pt", sendRtpItem.getPt()); param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); - if (!sendRtpItem.isTcp() && parentPlatform.isRtcp()) { + if (!sendRtpItem.isTcp()) { // 开启rtcp保活 - param.put("udp_rtcp_timeout", "1"); + param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0"); } if (mediaInfo == null) { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java index 3d3c772f4..4bdbbdfb8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java @@ -341,8 +341,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements return; } SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, - device.getDeviceId(), channelId, - mediaTransmissionTCP); + device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp()); if (tcpActive != null) { sendRtpItem.setTcpActive(tcpActive); @@ -537,8 +536,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements if (streamReady) { // 自平台内容 SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, - gbStream.getApp(), gbStream.getStream(), channelId, - mediaTransmissionTCP); + gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); if (sendRtpItem == null) { logger.warn("服务器端口资源不足"); @@ -577,8 +575,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements if (streamReady) { // 自平台内容 SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, - gbStream.getApp(), gbStream.getStream(), channelId, - mediaTransmissionTCP); + gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp()); if (sendRtpItem == null) { logger.warn("服务器端口资源不足"); @@ -695,7 +692,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements dynamicTask.stop(callIdHeader.getCallId()); if (serverId.equals(userSetting.getServerId())) { SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId, - app, stream, channelId, mediaTransmissionTCP); + app, stream, channelId, mediaTransmissionTCP, platform.isRtcp()); if (sendRtpItem == null) { logger.warn("上级点时创建sendRTPItem失败,可能是服务器端口资源不足"); @@ -757,7 +754,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements // 发送redis消息 redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(), streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId, - channelId, mediaTransmissionTCP, null, responseSendItemMsg -> { + channelId, mediaTransmissionTCP, platform.isRtcp(),null, responseSendItemMsg -> { SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem(); if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) { logger.warn("服务器端口资源不足"); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java index dd054f853..c7105698f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java @@ -175,7 +175,7 @@ public class ZLMRTPServerFactory { * @param tcp 是否为tcp * @return SendRtpItem */ - public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp, boolean rtcp){ // 默认为随机端口 int localPort = 0; @@ -195,6 +195,7 @@ public class ZLMRTPServerFactory { sendRtpItem.setDeviceId(deviceId); sendRtpItem.setChannelId(channelId); sendRtpItem.setTcp(tcp); + sendRtpItem.setRtcp(rtcp); sendRtpItem.setApp("rtp"); sendRtpItem.setLocalPort(localPort); sendRtpItem.setServerId(userSetting.getServerId()); @@ -212,7 +213,7 @@ public class ZLMRTPServerFactory { * @param tcp 是否为tcp * @return SendRtpItem */ - public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ + public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp, boolean rtcp){ // 默认为随机端口 int localPort = 0; if (userSetting.getGbSendStreamStrict()) { @@ -233,6 +234,7 @@ public class ZLMRTPServerFactory { sendRtpItem.setLocalPort(localPort); sendRtpItem.setServerId(userSetting.getServerId()); sendRtpItem.setMediaServerId(serverItem.getId()); + sendRtpItem.setRtcp(rtcp); return sendRtpItem; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/RequestSendItemMsg.java b/src/main/java/com/genersoft/iot/vmp/service/bean/RequestSendItemMsg.java index 66689fa6a..0c6502d19 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/bean/RequestSendItemMsg.java +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/RequestSendItemMsg.java @@ -63,10 +63,16 @@ public class RequestSendItemMsg { private Boolean isTcp; + /** + * 是否使用TCP + */ + private Boolean rtcp; + + public static RequestSendItemMsg getInstance(String serverId, String mediaServerId, String app, String stream, String ip, int port, - String ssrc, String platformId, String channelId, Boolean isTcp, String platformName) { + String ssrc, String platformId, String channelId, Boolean isTcp, Boolean rtcp, String platformName) { RequestSendItemMsg requestSendItemMsg = new RequestSendItemMsg(); requestSendItemMsg.setServerId(serverId); requestSendItemMsg.setMediaServerId(mediaServerId); @@ -79,6 +85,7 @@ public class RequestSendItemMsg { requestSendItemMsg.setPlatformName(platformName); requestSendItemMsg.setChannelId(channelId); requestSendItemMsg.setTcp(isTcp); + requestSendItemMsg.setRtcp(rtcp); return requestSendItemMsg; } @@ -170,4 +177,12 @@ public class RequestSendItemMsg { public void setTcp(Boolean tcp) { isTcp = tcp; } + + public Boolean getRtcp() { + return rtcp; + } + + public void setRtcp(Boolean rtcp) { + this.rtcp = rtcp; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index 1628398a3..1330262cc 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -318,7 +318,7 @@ public class RedisGbPlayMsgListener implements MessageListener { SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, content.getIp(), content.getPort(), content.getSsrc(), content.getPlatformId(), content.getApp(), content.getStream(), content.getChannelId(), - content.getTcp()); + content.getTcp(), content.getRtcp()); WVPResult result = new WVPResult<>(); result.setCode(0); @@ -348,9 +348,9 @@ public class RedisGbPlayMsgListener implements MessageListener { * @param callback 得到信息的回调 */ public void sendMsg(String serverId, String mediaServerId, String app, String stream, String ip, int port, String ssrc, - String platformId, String channelId, boolean isTcp, String platformName, PlayMsgCallback callback, PlayMsgErrorCallback errorCallback) { + String platformId, String channelId, boolean isTcp, boolean rtcp, String platformName, PlayMsgCallback callback, PlayMsgErrorCallback errorCallback) { RequestSendItemMsg requestSendItemMsg = RequestSendItemMsg.getInstance( - serverId, mediaServerId, app, stream, ip, port, ssrc, platformId, channelId, isTcp, platformName); + serverId, mediaServerId, app, stream, ip, port, ssrc, platformId, channelId, isTcp, rtcp, platformName); requestSendItemMsg.setServerId(serverId); String key = UUID.randomUUID().toString(); WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId, WvpRedisMsgCmd.GET_SEND_ITEM, diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index e640d6f80..7c16c7cde 100644 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -53,91 +53,91 @@ 更多地址 - + FLV: {{ streamInfo.flv.url }} - + FLV(https): {{ streamInfo.https_flv.url }} - + FLV(ws): {{ streamInfo.ws_flv.url }} - + FLV(wss): {{ streamInfo.wss_flv.url }} - + FMP4: {{ streamInfo.fmp4.url }} - + FMP4(https): {{ streamInfo.https_fmp4.url }} - + FMP4(ws): {{ streamInfo.ws_fmp4.url }} - + FMP4(wss): {{ streamInfo.wss_fmp4.url }} - + HLS: {{ streamInfo.hls.url }} - + HLS(https): {{ streamInfo.https_hls.url }} - + HLS(ws): {{ streamInfo.ws_hls.url }} - + HLS(wss): {{ streamInfo.wss_hls.url }} - + TS: {{ streamInfo.ts.url }} - + TS(https): {{ streamInfo.https_ts.url }} - + TS(ws): {{ streamInfo.ws_ts.url }} - + TS(wss): {{ streamInfo.wss_ts.url }} - + RTC: {{ streamInfo.rtc.url }} - + RTCS: {{ streamInfo.rtcs }} - + RTMP: {{ streamInfo.rtmp.url }} - + RTMPS: {{ streamInfo.rtmps.url }} - + RTSP: {{ streamInfo.rtsp.url }} - + RTSPS: {{ streamInfo.rtsps.url }} From 0629d4cf0df70724958c7765c81e7a51912457a9 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 25 Nov 2022 11:17:48 +0800 Subject: [PATCH 06/20] =?UTF-8?q?=E6=B8=85=E7=A9=BA=E7=BA=A7=E8=81=94?= =?UTF-8?q?=E5=BD=95=E5=83=8F=E8=AE=B0=E5=BD=95=20#672?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/gb28181/event/record/RecordEndEventListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/record/RecordEndEventListener.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/record/RecordEndEventListener.java index 5c2abb28c..92a435170 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/record/RecordEndEventListener.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/record/RecordEndEventListener.java @@ -35,6 +35,7 @@ public class RecordEndEventListener implements ApplicationListener Date: Fri, 25 Nov 2022 11:57:46 +0800 Subject: [PATCH 07/20] =?UTF-8?q?=E4=BC=98=E5=8C=96okhttp=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/media/zlm/ZLMRESTfulUtils.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index bf9551d4e..2815e643d 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -23,27 +23,34 @@ public class ZLMRESTfulUtils { private final static Logger logger = LoggerFactory.getLogger(ZLMRESTfulUtils.class); - - + private OkHttpClient client; public interface RequestCallback{ void run(JSONObject response); } private OkHttpClient getClient(){ - OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); - //todo 暂时写死超时时间 均为5s - httpClientBuilder.connectTimeout(5,TimeUnit.SECONDS); //设置连接超时时间 - httpClientBuilder.readTimeout(5,TimeUnit.SECONDS); //设置读取超时时间 - if (logger.isDebugEnabled()) { - HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> { - logger.debug("http请求参数:" + message); - }); - logging.setLevel(HttpLoggingInterceptor.Level.BASIC); - // OkHttp進行添加攔截器loggingInterceptor - httpClientBuilder.addInterceptor(logging); + if (client == null) { + OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); + //todo 暂时写死超时时间 均为5s + // 设置连接超时时间 + httpClientBuilder.connectTimeout(5,TimeUnit.SECONDS); + // 设置读取超时时间 + httpClientBuilder.readTimeout(5,TimeUnit.SECONDS); + // 设置连接池 + httpClientBuilder.connectionPool(new ConnectionPool(16, 10, TimeUnit.SECONDS)); + 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; + } @@ -164,9 +171,7 @@ public class ZLMRESTfulUtils { .build(); logger.info(request.toString()); try { - OkHttpClient client = new OkHttpClient.Builder() - .readTimeout(10, TimeUnit.SECONDS) - .build(); + OkHttpClient client = getClient(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { if (targetPath != null) { From fb957b0dba3a5b12f949370fdc2e22fb61661c68 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 25 Nov 2022 12:12:35 +0800 Subject: [PATCH 08/20] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/all-application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index e8b28d0d7..6240e4467 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -186,7 +186,7 @@ user-settings: logInDatebase: true # 使用推流状态作为推流通道状态 use-pushing-as-status: true - # 使用来源请求ip作为streamIp + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 use-source-ip-as-stream-ip: true # 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 stream-on-demand: true From f89491ada315b78648f266a86c026f7cb9bf3519 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 25 Nov 2022 14:38:46 +0800 Subject: [PATCH 09/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E6=A8=A1=E5=BC=8F=E4=B8=8Bssrc=E7=9A=84=E9=87=8A?= =?UTF-8?q?=E6=94=BE=20#667?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 2 +- .../iot/vmp/service/impl/MediaServerServiceImpl.java | 1 - .../iot/vmp/vmanager/gb28181/device/DeviceQuery.java | 10 ++++------ web_src/src/components/DeviceList.vue | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 2815e643d..99a695eb3 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -38,7 +38,7 @@ public class ZLMRESTfulUtils { // 设置读取超时时间 httpClientBuilder.readTimeout(5,TimeUnit.SECONDS); // 设置连接池 - httpClientBuilder.connectionPool(new ConnectionPool(16, 10, TimeUnit.SECONDS)); + httpClientBuilder.connectionPool(new ConnectionPool(16, 5, TimeUnit.MINUTES)); if (logger.isDebugEnabled()) { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> { logger.debug("http请求参数:" + message); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java index d9f922aeb..db4d7b334 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java @@ -169,7 +169,6 @@ public class MediaServerServiceImpl implements IMediaServerService { return; } zlmrtpServerFactory.closeRtpServer(mediaServerItem, streamId); - releaseSsrc(mediaServerItem.getId(), streamId); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java index 23d4d7269..d4694c524 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java @@ -5,7 +5,6 @@ import com.genersoft.iot.vmp.conf.DynamicTask; import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; -import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; import com.genersoft.iot.vmp.gb28181.bean.SyncStatus; import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; @@ -25,7 +24,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.commons.compress.utils.IOUtils; -import org.apache.http.HttpResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -33,15 +31,15 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; import javax.servlet.http.HttpServletResponse; -import javax.sip.DialogState; import javax.sip.InvalidArgumentException; import javax.sip.SipException; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.text.ParseException; import java.util.*; @@ -145,7 +143,7 @@ public class DeviceQuery { */ @Operation(summary = "同步设备通道") @Parameter(name = "deviceId", description = "设备国标编号", required = true) - @PostMapping("/devices/{deviceId}/sync") + @GetMapping("/devices/{deviceId}/sync") public WVPResult devicesSync(@PathVariable String deviceId){ if (logger.isDebugEnabled()) { diff --git a/web_src/src/components/DeviceList.vue b/web_src/src/components/DeviceList.vue index e15f340db..29e049daf 100644 --- a/web_src/src/components/DeviceList.vue +++ b/web_src/src/components/DeviceList.vue @@ -207,7 +207,7 @@ export default { console.log("刷新对应设备:" + itemData.deviceId); let that = this; this.$axios({ - method: 'post', + method: 'get', url: '/api/device/query/devices/' + itemData.deviceId + '/sync' }).then((res) => { console.log("刷新设备结果:" + JSON.stringify(res)); From d60452560e37305e62f8cdd6cc08c6b3d3430a10 Mon Sep 17 00:00:00 2001 From: WuPeng Date: Sun, 27 Nov 2022 10:28:42 +0800 Subject: [PATCH 10/20] =?UTF-8?q?=E5=BC=83=E7=94=A8=E5=BA=9F=E5=BC=83?= =?UTF-8?q?=E6=96=B9=E6=B3=95toJavaObject=EF=BC=8C=E6=94=B9=E7=94=A8to?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E6=B6=88=E9=99=A4=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E8=AD=A6=E5=91=8A=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vmp/service/redisMsg/RedisGbPlayMsgListener.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index 1330262cc..61dea12bb 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -119,7 +119,7 @@ public class RedisGbPlayMsgListener implements MessageListener { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class); - WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class); + WvpRedisMsg wvpRedisMsg = JSON.to(WvpRedisMsg.class, msgJSON); if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) { continue; } @@ -128,11 +128,11 @@ public class RedisGbPlayMsgListener implements MessageListener { switch (wvpRedisMsg.getCmd()){ case WvpRedisMsgCmd.GET_SEND_ITEM: - RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class); + RequestSendItemMsg content = JSON.to(RequestSendItemMsg.class, wvpRedisMsg.getContent()); requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); break; case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: - RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);; + RequestPushStreamMsg param = JSON.to(RequestPushStreamMsg.class, wvpRedisMsg.getContent());; requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); break; default: @@ -144,12 +144,12 @@ public class RedisGbPlayMsgListener implements MessageListener { switch (wvpRedisMsg.getCmd()){ case WvpRedisMsgCmd.GET_SEND_ITEM: - WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); + WVPResult content = JSON.to(WVPResult.class, wvpRedisMsg.getContent()); String key = wvpRedisMsg.getSerial(); switch (content.getCode()) { case 0: - ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class); + ResponseSendItemMsg responseSendItemMsg =JSON.to(ResponseSendItemMsg.class, content.getData()); PlayMsgCallback playMsgCallback = callbacks.get(key); if (playMsgCallback != null) { callbacksForError.remove(key); @@ -174,7 +174,7 @@ public class RedisGbPlayMsgListener implements MessageListener { } break; case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: - WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); + WVPResult wvpResult = JSON.to(WVPResult.class, wvpRedisMsg.getContent()); String serial = wvpRedisMsg.getSerial(); switch (wvpResult.getCode()) { case 0: From 14151c07e3d04509d1c8c9ebecde5d9997046efd Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 29 Nov 2022 11:42:09 +0800 Subject: [PATCH 11/20] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=98=9F=E5=88=97?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/gb28181/SipLayer.java | 2 - .../DigestServerAuthenticationHelper.java | 72 +----- .../cmd/impl/SIPCommanderFroPlatform.java | 11 +- .../request/impl/NotifyRequestProcessor.java | 9 +- .../notify/cmd/AlarmNotifyMessageHandler.java | 209 +++++++++--------- .../MobilePositionNotifyMessageHandler.java | 32 +-- .../cmd/CatalogResponseMessageHandler.java | 125 +++++------ .../cmd/RecordInfoResponseMessageHandler.java | 17 +- .../redisMsg/RedisAlarmMsgListener.java | 99 ++++----- .../redisMsg/RedisGbPlayMsgListener.java | 172 +++++++------- .../service/redisMsg/RedisGpsMsgListener.java | 17 +- .../RedisPushStreamResponseListener.java | 30 +-- .../RedisPushStreamStatusListMsgListener.java | 83 +++---- .../RedisPushStreamStatusMsgListener.java | 51 ++--- .../redisMsg/RedisStreamMsgListener.java | 74 +++---- 15 files changed, 458 insertions(+), 545 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java index 13fa01d32..24b88e55a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java @@ -29,8 +29,6 @@ public class SipLayer implements CommandLineRunner { @Autowired private ISIPProcessorObserver sipProcessorObserver; - - private final Map tcpSipProviderMap = new ConcurrentHashMap<>(); private final Map udpSipProviderMap = new ConcurrentHashMap<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java index 7c319efc3..fdb05e56a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/auth/DigestServerAuthenticationHelper.java @@ -25,10 +25,9 @@ */ package com.genersoft.iot.vmp.gb28181.auth; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.Random; +import gov.nist.core.InternalErrorHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.sip.address.URI; import javax.sip.header.AuthorizationHeader; @@ -36,10 +35,10 @@ import javax.sip.header.HeaderFactory; import javax.sip.header.WWWAuthenticateHeader; import javax.sip.message.Request; import javax.sip.message.Response; - -import gov.nist.core.InternalErrorHandler; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.Random; /** * Implements the HTTP digest authentication method server side functionality. @@ -201,12 +200,13 @@ public class DigestServerAuthenticationHelper { // String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16)); String A1 = username + ":" + realm + ":" + pass; + String A2 = request.getMethod().toUpperCase() + ":" + uri.toString(); + byte mdbytes[] = messageDigest.digest(A1.getBytes()); String HA1 = toHexString(mdbytes); logger.debug("A1: " + A1); logger.debug("A2: " + A2); - mdbytes = messageDigest.digest(A2.getBytes()); String HA2 = toHexString(mdbytes); logger.debug("HA1: " + HA1); @@ -238,58 +238,4 @@ public class DigestServerAuthenticationHelper { } -// public static void main(String[] args) throws NoSuchAlgorithmException { -// String realm = "3402000000"; -// String username = "44010000001180008012"; - - -// String nonce = "07cab60999fbf643264ace27d3b7de8b"; -// String uri = "sip:34020000002000000001@3402000000"; -// // qop 保护质量 包含auth(默认的)和auth-int(增加了报文完整性检测)两种策略 -// String qop = "auth"; - -// // 客户端随机数,这是一个不透明的字符串值,由客户端提供,并且客户端和服务器都会使用,以避免用明文文本。 -// // 这使得双方都可以查验对方的身份,并对消息的完整性提供一些保护 -// //String cNonce = authHeader.getCNonce(); - -// // nonce计数器,是一个16进制的数值,表示同一nonce下客户端发送出请求的数量 -// int nc = 1; -// String ncStr = new DecimalFormat("00000000").format(nc); -// // String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16)); -// MessageDigest messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM); -// String A1 = username + ":" + realm + ":" + "12345678"; -// String A2 = "REGISTER" + ":" + uri; -// byte mdbytes[] = messageDigest.digest(A1.getBytes()); -// String HA1 = toHexString(mdbytes); -// System.out.println("A1: " + A1); -// System.out.println("A2: " + A2); - -// mdbytes = messageDigest.digest(A2.getBytes()); -// String HA2 = toHexString(mdbytes); -// System.out.println("HA1: " + HA1); -// System.out.println("HA2: " + HA2); -// String cnonce = "0a4f113b"; -// System.out.println("nonce: " + nonce); -// System.out.println("nc: " + ncStr); -// System.out.println("cnonce: " + cnonce); -// System.out.println("qop: " + qop); -// String KD = HA1 + ":" + nonce; - -// if (qop != null && qop.equals("auth") ) { -// if (nc != -1) { -// KD += ":" + ncStr; -// } -// if (cnonce != null) { -// KD += ":" + cnonce; -// } -// KD += ":" + qop; -// } -// KD += ":" + HA2; -// System.out.println("KD: " + KD); -// mdbytes = messageDigest.digest(KD.getBytes()); -// String mdString = toHexString(mdbytes); -// System.out.println("mdString: " + mdString); -// String response = "4f0507d4b87cdecff04bdaf4c96348f0"; -// System.out.println("response: " + response); -// } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java index 0f234f54d..a641d9bef 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; import com.alibaba.fastjson2.JSON; -import com.alibaba.fastjson2.JSONObject; import com.genersoft.iot.vmp.gb28181.SipLayer; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; @@ -9,13 +8,13 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; -import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; -import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo; +import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.MessageFactoryImpl; import gov.nist.javax.sip.message.SIPRequest; import org.slf4j.Logger; @@ -26,8 +25,10 @@ import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import javax.sip.*; -import javax.sip.header.*; +import javax.sip.InvalidArgumentException; +import javax.sip.SipException; +import javax.sip.header.CallIdHeader; +import javax.sip.header.WWWAuthenticateHeader; import javax.sip.message.Request; import java.text.ParseException; import java.util.ArrayList; diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java index 4df7d631f..db922f98c 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/NotifyRequestProcessor.java @@ -11,7 +11,6 @@ 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.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; @@ -31,7 +30,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; @@ -77,8 +75,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements @Autowired private IDeviceChannelService deviceChannelService; - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -98,9 +94,9 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements }catch (SipException | InvalidArgumentException | ParseException e) { e.printStackTrace(); } + boolean runed = !taskQueue.isEmpty(); taskQueue.offer(new HandlerCatchData(evt, null, null)); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (!runed) { taskExecutor.execute(()-> { while (!taskQueue.isEmpty()) { try { @@ -128,7 +124,6 @@ public class NotifyRequestProcessor extends SIPRequestProcessorParent implements logger.error("处理NOTIFY消息时错误", e); } } - taskQueueHandlerRun = false; }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java index bb1497861..09a5ffc2c 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/AlarmNotifyMessageHandler.java @@ -9,7 +9,6 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; import com.genersoft.iot.vmp.service.IDeviceAlarmService; @@ -27,17 +26,15 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; import javax.sip.SipException; import javax.sip.message.Response; - import java.text.ParseException; import java.util.concurrent.ConcurrentLinkedQueue; -import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.*; +import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; /** * 报警事件的处理,参考:9.4 @@ -72,8 +69,6 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @Autowired private IDeviceChannelService deviceChannelService; - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -89,128 +84,128 @@ public class AlarmNotifyMessageHandler extends SIPRequestProcessorParent impleme @Override public void handForDevice(RequestEvent evt, Device device, Element rootElement) { logger.info("[收到报警通知]设备:{}", device.getDeviceId()); - + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(new SipMsgInfo(evt, device, rootElement)); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + // 回复200 OK + try { + responseAck((SIPRequest) evt.getRequest(), Response.OK); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 报警通知回复: {}", e.getMessage()); + } + if (isEmpty) { taskExecutor.execute(() -> { logger.info("[处理报警通知]待处理数量:{}", taskQueue.size() ); while (!taskQueue.isEmpty()) { - SipMsgInfo sipMsgInfo = taskQueue.poll(); - // 回复200 OK try { - responseAck((SIPRequest) sipMsgInfo.getEvt().getRequest(), Response.OK); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[处理报警通知], 回复200OK失败", e); - } + SipMsgInfo sipMsgInfo = taskQueue.poll(); - Element deviceIdElement = sipMsgInfo.getRootElement().element("DeviceID"); - String channelId = deviceIdElement.getText().toString(); + Element deviceIdElement = sipMsgInfo.getRootElement().element("DeviceID"); + String channelId = deviceIdElement.getText().toString(); - DeviceAlarm deviceAlarm = new DeviceAlarm(); - deviceAlarm.setCreateTime(DateUtil.getNow()); - deviceAlarm.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); - deviceAlarm.setChannelId(channelId); - deviceAlarm.setAlarmPriority(getText(sipMsgInfo.getRootElement(), "AlarmPriority")); - deviceAlarm.setAlarmMethod(getText(sipMsgInfo.getRootElement(), "AlarmMethod")); - String alarmTime = XmlUtil.getText(sipMsgInfo.getRootElement(), "AlarmTime"); - if (alarmTime == null) { - continue; - } - deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime)); - String alarmDescription = getText(sipMsgInfo.getRootElement(), "AlarmDescription"); - if (alarmDescription == null) { - deviceAlarm.setAlarmDescription(""); - } else { - deviceAlarm.setAlarmDescription(alarmDescription); - } - String longitude = getText(sipMsgInfo.getRootElement(), "Longitude"); - if (longitude != null && NumericUtil.isDouble(longitude)) { - deviceAlarm.setLongitude(Double.parseDouble(longitude)); - } else { - deviceAlarm.setLongitude(0.00); - } - String latitude = getText(sipMsgInfo.getRootElement(), "Latitude"); - if (latitude != null && NumericUtil.isDouble(latitude)) { - deviceAlarm.setLatitude(Double.parseDouble(latitude)); - } else { - deviceAlarm.setLatitude(0.00); - } + DeviceAlarm deviceAlarm = new DeviceAlarm(); + deviceAlarm.setCreateTime(DateUtil.getNow()); + deviceAlarm.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); + deviceAlarm.setChannelId(channelId); + deviceAlarm.setAlarmPriority(getText(sipMsgInfo.getRootElement(), "AlarmPriority")); + deviceAlarm.setAlarmMethod(getText(sipMsgInfo.getRootElement(), "AlarmMethod")); + String alarmTime = XmlUtil.getText(sipMsgInfo.getRootElement(), "AlarmTime"); + if (alarmTime == null) { + continue; + } + deviceAlarm.setAlarmTime(DateUtil.ISO8601Toyyyy_MM_dd_HH_mm_ss(alarmTime)); + String alarmDescription = getText(sipMsgInfo.getRootElement(), "AlarmDescription"); + if (alarmDescription == null) { + deviceAlarm.setAlarmDescription(""); + } else { + deviceAlarm.setAlarmDescription(alarmDescription); + } + String longitude = getText(sipMsgInfo.getRootElement(), "Longitude"); + if (longitude != null && NumericUtil.isDouble(longitude)) { + deviceAlarm.setLongitude(Double.parseDouble(longitude)); + } else { + deviceAlarm.setLongitude(0.00); + } + String latitude = getText(sipMsgInfo.getRootElement(), "Latitude"); + if (latitude != null && NumericUtil.isDouble(latitude)) { + deviceAlarm.setLatitude(Double.parseDouble(latitude)); + } else { + deviceAlarm.setLatitude(0.00); + } - if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) { - if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) { - MobilePosition mobilePosition = new MobilePosition(); - mobilePosition.setCreateTime(DateUtil.getNow()); - mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); - mobilePosition.setTime(deviceAlarm.getAlarmTime()); - mobilePosition.setLongitude(deviceAlarm.getLongitude()); - mobilePosition.setLatitude(deviceAlarm.getLatitude()); - mobilePosition.setReportSource("GPS Alarm"); + if (!ObjectUtils.isEmpty(deviceAlarm.getAlarmMethod())) { + if ( deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.GPS.getVal() + "")) { + MobilePosition mobilePosition = new MobilePosition(); + mobilePosition.setCreateTime(DateUtil.getNow()); + mobilePosition.setDeviceId(deviceAlarm.getDeviceId()); + mobilePosition.setTime(deviceAlarm.getAlarmTime()); + mobilePosition.setLongitude(deviceAlarm.getLongitude()); + mobilePosition.setLatitude(deviceAlarm.getLatitude()); + mobilePosition.setReportSource("GPS Alarm"); - // 更新device channel 的经纬度 - DeviceChannel deviceChannel = new DeviceChannel(); - deviceChannel.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); - deviceChannel.setChannelId(channelId); - deviceChannel.setLongitude(mobilePosition.getLongitude()); - deviceChannel.setLatitude(mobilePosition.getLatitude()); - deviceChannel.setGpsTime(mobilePosition.getTime()); + // 更新device channel 的经纬度 + DeviceChannel deviceChannel = new DeviceChannel(); + deviceChannel.setDeviceId(sipMsgInfo.getDevice().getDeviceId()); + deviceChannel.setChannelId(channelId); + deviceChannel.setLongitude(mobilePosition.getLongitude()); + deviceChannel.setLatitude(mobilePosition.getLatitude()); + deviceChannel.setGpsTime(mobilePosition.getTime()); - deviceChannel = deviceChannelService.updateGps(deviceChannel, sipMsgInfo.getDevice()); + deviceChannel = deviceChannelService.updateGps(deviceChannel, sipMsgInfo.getDevice()); - mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84()); - mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84()); - mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02()); - mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02()); + mobilePosition.setLongitudeWgs84(deviceChannel.getLongitudeWgs84()); + mobilePosition.setLatitudeWgs84(deviceChannel.getLatitudeWgs84()); + mobilePosition.setLongitudeGcj02(deviceChannel.getLongitudeGcj02()); + mobilePosition.setLatitudeGcj02(deviceChannel.getLatitudeGcj02()); - if (userSetting.getSavePositionHistory()) { - storager.insertMobilePosition(mobilePosition); + if (userSetting.getSavePositionHistory()) { + storager.insertMobilePosition(mobilePosition); + } + storager.updateChannelPosition(deviceChannel); + + // 发送redis消息。 通知位置信息的变化 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("time", mobilePosition.getTime()); + jsonObject.put("serial", deviceChannel.getDeviceId()); + jsonObject.put("code", deviceChannel.getChannelId()); + jsonObject.put("longitude", mobilePosition.getLongitude()); + jsonObject.put("latitude", mobilePosition.getLatitude()); + jsonObject.put("altitude", mobilePosition.getAltitude()); + jsonObject.put("direction", mobilePosition.getDirection()); + jsonObject.put("speed", mobilePosition.getSpeed()); + redisCatchStorage.sendMobilePositionMsg(jsonObject); } - storager.updateChannelPosition(deviceChannel); - - // 发送redis消息。 通知位置信息的变化 - JSONObject jsonObject = new JSONObject(); - jsonObject.put("time", mobilePosition.getTime()); - jsonObject.put("serial", deviceChannel.getDeviceId()); - jsonObject.put("code", deviceChannel.getChannelId()); - jsonObject.put("longitude", mobilePosition.getLongitude()); - jsonObject.put("latitude", mobilePosition.getLatitude()); - jsonObject.put("altitude", mobilePosition.getAltitude()); - jsonObject.put("direction", mobilePosition.getDirection()); - jsonObject.put("speed", mobilePosition.getSpeed()); - redisCatchStorage.sendMobilePositionMsg(jsonObject); } - } - if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) { - if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) { - deviceAlarm.setAlarmType(getText(sipMsgInfo.getRootElement().element("Info"), "AlarmType")); + if (!ObjectUtils.isEmpty(deviceAlarm.getDeviceId())) { + if (deviceAlarm.getAlarmMethod().contains(DeviceAlarmMethod.Video.getVal() + "")) { + deviceAlarm.setAlarmType(getText(sipMsgInfo.getRootElement().element("Info"), "AlarmType")); + } + } + logger.info("[收到报警通知]内容:{}", JSON.toJSONString(deviceAlarm)); + if ("7".equals(deviceAlarm.getAlarmMethod()) ) { + // 发送给平台的报警信息。 发送redis通知 + AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); + alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); + alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); + alarmChannelMessage.setGbId(channelId); + redisCatchStorage.sendAlarmMsg(alarmChannelMessage); + continue; } - } - logger.info("[收到报警通知]内容:{}", JSON.toJSONString(deviceAlarm)); - if ("7".equals(deviceAlarm.getAlarmMethod()) ) { - // 发送给平台的报警信息。 发送redis通知 - AlarmChannelMessage alarmChannelMessage = new AlarmChannelMessage(); - alarmChannelMessage.setAlarmSn(Integer.parseInt(deviceAlarm.getAlarmMethod())); - alarmChannelMessage.setAlarmDescription(deviceAlarm.getAlarmDescription()); - alarmChannelMessage.setGbId(channelId); - redisCatchStorage.sendAlarmMsg(alarmChannelMessage); - continue; - } - logger.debug("存储报警信息、报警分类"); - // 存储报警信息、报警分类 - if (sipConfig.isAlarm()) { - deviceAlarmService.add(deviceAlarm); - } + logger.debug("存储报警信息、报警分类"); + // 存储报警信息、报警分类 + if (sipConfig.isAlarm()) { + deviceAlarmService.add(deviceAlarm); + } - if (redisCatchStorage.deviceIsOnline(sipMsgInfo.getDevice().getDeviceId())) { - publisher.deviceAlarmEventPublish(deviceAlarm); + if (redisCatchStorage.deviceIsOnline(sipMsgInfo.getDevice().getDeviceId())) { + publisher.deviceAlarmEventPublish(deviceAlarm); + } + }catch (Exception e) { + logger.warn("[收到报警通知] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); } } - taskQueueHandlerRun = false; }); } - - } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java index 7a0ea1c26..40d1dcc90 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MobilePositionNotifyMessageHandler.java @@ -22,7 +22,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; @@ -57,8 +56,6 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @Autowired private IDeviceChannelService deviceChannelService; - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -73,21 +70,22 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen @Override public void handForDevice(RequestEvent evt, Device device, Element rootElement) { + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(new SipMsgInfo(evt, device, rootElement)); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + // 回复200 OK + try { + responseAck((SIPRequest) evt.getRequest(), Response.OK); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 移动位置通知回复: {}", e.getMessage()); + } + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { SipMsgInfo sipMsgInfo = taskQueue.poll(); try { Element rootElementAfterCharset = getRootElement(sipMsgInfo.getEvt(), sipMsgInfo.getDevice().getCharset()); if (rootElementAfterCharset == null) { - try { - logger.warn("[ 移动设备位置数据通知 ] content cannot be null, {}", sipMsgInfo.getEvt().getRequest()); - responseAck((SIPRequest) sipMsgInfo.getEvt().getRequest(), Response.BAD_REQUEST); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 移动设备位置数据通知 内容为空: {}", e.getMessage()); - } + logger.warn("[移动位置通知] {}处理失败,未识别到信息体", device.getDeviceId()); continue; } MobilePosition mobilePosition = new MobilePosition(); @@ -137,12 +135,6 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen storager.insertMobilePosition(mobilePosition); } storager.updateChannelPosition(deviceChannel); - //回复 200 OK - try { - responseAck((SIPRequest) sipMsgInfo.getEvt().getRequest(), Response.OK); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 移动设备位置数据回复200: {}", e.getMessage()); - } // 发送redis消息。 通知位置信息的变化 JSONObject jsonObject = new JSONObject(); @@ -158,14 +150,12 @@ public class MobilePositionNotifyMessageHandler extends SIPRequestProcessorParen } catch (DocumentException e) { e.printStackTrace(); + } catch (Exception e) { + logger.warn("[移动位置通知] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); } - } - taskQueueHandlerRun = false; }); } - - } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java index 52e0b7f10..761481be5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/CatalogResponseMessageHandler.java @@ -1,18 +1,11 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.cmd; -import com.genersoft.iot.vmp.conf.SipConfig; -import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.*; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; import com.genersoft.iot.vmp.gb28181.session.CatalogDataCatch; -import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; -import com.genersoft.iot.vmp.gb28181.utils.Coordtransform; -import com.genersoft.iot.vmp.gb28181.utils.NumericUtil; import com.genersoft.iot.vmp.gb28181.utils.XmlUtil; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import gov.nist.javax.sip.message.SIPRequest; import org.dom4j.DocumentException; @@ -24,7 +17,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; @@ -45,12 +37,10 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp private Logger logger = LoggerFactory.getLogger(CatalogResponseMessageHandler.class); private final String cmdType = "Catalog"; - private boolean taskQueueHandlerRun = false; - @Autowired private ResponseMessageHandler responseMessageHandler; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); + private final ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Autowired private IVideoManagerStorage storager; @@ -69,6 +59,7 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp @Override public void handForDevice(RequestEvent evt, Device device, Element element) { + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(new HandlerCatchData(evt, device, element)); // 回复200 OK try { @@ -76,67 +67,71 @@ public class CatalogResponseMessageHandler extends SIPRequestProcessorParent imp } catch (SipException | InvalidArgumentException | ParseException e) { logger.error("[命令发送失败] 目录查询回复: {}", e.getMessage()); } - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + // 如果不为空则说明已经开启消息处理 + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { - HandlerCatchData take = taskQueue.poll(); - Element rootElement = null; + // 全局异常捕获,保证下一条可以得到处理 try { - rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset()); - } catch (DocumentException e) { - logger.error("[xml解析] 失败: ", e); - continue; - } - if (rootElement == null) { - logger.warn("[ 收到通道 ] content cannot be null, {}", evt.getRequest()); - continue; - } - Element deviceListElement = rootElement.element("DeviceList"); - Element sumNumElement = rootElement.element("SumNum"); - Element snElement = rootElement.element("SN"); - int sumNum = Integer.parseInt(sumNumElement.getText()); - - if (sumNum == 0) { - logger.info("[收到通道]设备:{}的: 0个", take.getDevice().getDeviceId()); - // 数据已经完整接收 - storager.cleanChannelsForDevice(take.getDevice().getDeviceId()); - catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null); - } else { - Iterator deviceListIterator = deviceListElement.elementIterator(); - if (deviceListIterator != null) { - List channelList = new ArrayList<>(); - // 遍历DeviceList - while (deviceListIterator.hasNext()) { - Element itemDevice = deviceListIterator.next(); - Element channelDeviceElement = itemDevice.element("DeviceID"); - if (channelDeviceElement == null) { - continue; - } - DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null); - deviceChannel.setDeviceId(take.getDevice().getDeviceId()); - - channelList.add(deviceChannel); - } - int sn = Integer.parseInt(snElement.getText()); - catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList); - logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 : catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum); - if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) { - // 数据已经完整接收, 此时可能存在某个设备离线变上线的情况,但是考虑到性能,此处不做处理, - // 目前支持设备通道上线通知时和设备上线时向上级通知 - boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId())); - if (!resetChannelsResult) { - String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条"; - catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), errorMsg); - } else { - catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null); - } - } + HandlerCatchData take = taskQueue.poll(); + Element rootElement = null; + try { + rootElement = getRootElement(take.getEvt(), take.getDevice().getCharset()); + } catch (DocumentException e) { + logger.error("[xml解析] 失败: ", e); + continue; } + if (rootElement == null) { + logger.warn("[ 收到通道 ] content cannot be null, {}", evt.getRequest()); + continue; + } + Element deviceListElement = rootElement.element("DeviceList"); + Element sumNumElement = rootElement.element("SumNum"); + Element snElement = rootElement.element("SN"); + int sumNum = Integer.parseInt(sumNumElement.getText()); + if (sumNum == 0) { + logger.info("[收到通道]设备:{}的: 0个", take.getDevice().getDeviceId()); + // 数据已经完整接收 + storager.cleanChannelsForDevice(take.getDevice().getDeviceId()); + catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null); + } else { + Iterator deviceListIterator = deviceListElement.elementIterator(); + if (deviceListIterator != null) { + List channelList = new ArrayList<>(); + // 遍历DeviceList + while (deviceListIterator.hasNext()) { + Element itemDevice = deviceListIterator.next(); + Element channelDeviceElement = itemDevice.element("DeviceID"); + if (channelDeviceElement == null) { + continue; + } + DeviceChannel deviceChannel = XmlUtil.channelContentHander(itemDevice, device, null); + deviceChannel.setDeviceId(take.getDevice().getDeviceId()); + + channelList.add(deviceChannel); + } + int sn = Integer.parseInt(snElement.getText()); + catalogDataCatch.put(take.getDevice().getDeviceId(), sn, sumNum, take.getDevice(), channelList); + logger.info("[收到通道]设备: {} -> {}个,{}/{}", take.getDevice().getDeviceId(), channelList.size(), catalogDataCatch.get(take.getDevice().getDeviceId()) == null ? 0 : catalogDataCatch.get(take.getDevice().getDeviceId()).size(), sumNum); + if (catalogDataCatch.get(take.getDevice().getDeviceId()).size() == sumNum) { + // 数据已经完整接收, 此时可能存在某个设备离线变上线的情况,但是考虑到性能,此处不做处理, + // 目前支持设备通道上线通知时和设备上线时向上级通知 + boolean resetChannelsResult = storager.resetChannels(take.getDevice().getDeviceId(), catalogDataCatch.get(take.getDevice().getDeviceId())); + if (!resetChannelsResult) { + String errorMsg = "接收成功,写入失败,共" + sumNum + "条,已接收" + catalogDataCatch.get(take.getDevice().getDeviceId()).size() + "条"; + catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), errorMsg); + } else { + catalogDataCatch.setChannelSyncEnd(take.getDevice().getDeviceId(), null); + } + } + } + + } + }catch (Exception e) { + logger.warn("[收到通道] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); } } - taskQueueHandlerRun = false; }); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java index 286dd5658..11d239ef3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/RecordInfoResponseMessageHandler.java @@ -9,7 +9,6 @@ import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorP import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler; import com.genersoft.iot.vmp.utils.DateUtil; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import gov.nist.javax.sip.message.SIPRequest; import org.dom4j.DocumentException; import org.dom4j.Element; @@ -21,17 +20,17 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; -import java.util.*; -import java.util.concurrent.BlockingQueue; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.LinkedBlockingQueue; import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; @@ -46,7 +45,6 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); - private boolean taskQueueHandlerRun = false; @Autowired private ResponseMessageHandler responseMessageHandler; @@ -70,6 +68,7 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent @Override public void handForDevice(RequestEvent evt, Device device, Element rootElement) { + boolean isEmpty = taskQueue.isEmpty(); try { // 回复200 OK responseAck((SIPRequest) evt.getRequest(), Response.OK); @@ -77,8 +76,7 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent logger.error("[命令发送失败] 国标级联 国标录像: {}", e.getMessage()); } taskQueue.offer(new HandlerCatchData(evt, device, rootElement)); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(()->{ while (!taskQueue.isEmpty()) { try { @@ -151,9 +149,10 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent } } catch (DocumentException e) { logger.error("xml解析异常: ", e); + } catch (Exception e) { + logger.warn("[国标录像] 发现未处理的异常, {}\r\n{}",e.getMessage(), evt.getRequest()); } } - taskQueueHandlerRun = false; }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java index d68591c46..9bb3bbd27 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisAlarmMsgListener.java @@ -38,8 +38,6 @@ public class RedisAlarmMsgListener implements MessageListener { @Autowired private IVideoManagerStorage storage; - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -49,69 +47,68 @@ public class RedisAlarmMsgListener implements MessageListener { @Override public void onMessage(@NotNull Message message, byte[] bytes) { logger.info("收到来自REDIS的ALARM通知: {}", new String(message.getBody())); - + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { logger.info("[线程池信息]活动线程数:{}, 最大线程数: {}", taskExecutor.getActiveCount(), taskExecutor.getMaxPoolSize()); taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); + try { + AlarmChannelMessage alarmChannelMessage = JSON.parseObject(msg.getBody(), AlarmChannelMessage.class); + if (alarmChannelMessage == null) { + logger.warn("[REDIS的ALARM通知]消息解析失败"); + continue; + } + String gbId = alarmChannelMessage.getGbId(); - AlarmChannelMessage alarmChannelMessage = JSON.parseObject(msg.getBody(), AlarmChannelMessage.class); - if (alarmChannelMessage == null) { - logger.warn("[REDIS的ALARM通知]消息解析失败"); - continue; - } - String gbId = alarmChannelMessage.getGbId(); + DeviceAlarm deviceAlarm = new DeviceAlarm(); + deviceAlarm.setCreateTime(DateUtil.getNow()); + deviceAlarm.setChannelId(gbId); + deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription()); + deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); + deviceAlarm.setAlarmPriority("1"); + deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601()); + deviceAlarm.setAlarmType("1"); + deviceAlarm.setLongitude(0); + deviceAlarm.setLatitude(0); - DeviceAlarm deviceAlarm = new DeviceAlarm(); - deviceAlarm.setCreateTime(DateUtil.getNow()); - deviceAlarm.setChannelId(gbId); - deviceAlarm.setAlarmDescription(alarmChannelMessage.getAlarmDescription()); - deviceAlarm.setAlarmMethod("" + alarmChannelMessage.getAlarmSn()); - deviceAlarm.setAlarmPriority("1"); - deviceAlarm.setAlarmTime(DateUtil.getNowForISO8601()); - deviceAlarm.setAlarmType("1"); - deviceAlarm.setLongitude(0); - deviceAlarm.setLatitude(0); - - if (ObjectUtils.isEmpty(gbId)) { - // 发送给所有的上级 - List parentPlatforms = storage.queryEnableParentPlatformList(true); - if (parentPlatforms.size() > 0) { - for (ParentPlatform parentPlatform : parentPlatforms) { - try { - commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); + if (ObjectUtils.isEmpty(gbId)) { + // 发送给所有的上级 + List parentPlatforms = storage.queryEnableParentPlatformList(true); + if (parentPlatforms.size() > 0) { + for (ParentPlatform parentPlatform : parentPlatforms) { + try { + commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage()); + } } } - } - }else { - Device device = storage.queryVideoDevice(gbId); - ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); - if (device != null && platform == null) { - try { - commander.sendAlarmMessage(device, deviceAlarm); - } catch (InvalidArgumentException | SipException | ParseException e) { - logger.error("[命令发送失败] 发送报警: {}", e.getMessage()); - } - }else if (device == null && platform != null){ - try { - commanderForPlatform.sendAlarmMessage(platform, deviceAlarm); - } catch (InvalidArgumentException | SipException | ParseException e) { - logger.error("[命令发送失败] 发送报警: {}", e.getMessage()); - } }else { - logger.warn("无法确定" + gbId + "是平台还是设备"); + Device device = storage.queryVideoDevice(gbId); + ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); + if (device != null && platform == null) { + try { + commander.sendAlarmMessage(device, deviceAlarm); + } catch (InvalidArgumentException | SipException | ParseException e) { + logger.error("[命令发送失败] 发送报警: {}", e.getMessage()); + } + }else if (device == null && platform != null){ + try { + commanderForPlatform.sendAlarmMessage(platform, deviceAlarm); + } catch (InvalidArgumentException | SipException | ParseException e) { + logger.error("[命令发送失败] 发送报警: {}", e.getMessage()); + } + }else { + logger.warn("无法确定" + gbId + "是平台还是设备"); + } } + }catch (Exception e) { + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); } } - taskQueueHandlerRun = false; }); } - - } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java index 1330262cc..42cbec5c9 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java @@ -88,8 +88,6 @@ public class RedisGbPlayMsgListener implements MessageListener { @Autowired private ZlmHttpHookSubscribe subscribe; - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -111,107 +109,103 @@ public class RedisGbPlayMsgListener implements MessageListener { @Override public void onMessage(Message message, byte[] bytes) { - + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); - JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class); - WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class); - if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) { - continue; - } - if (WvpRedisMsg.isRequest(wvpRedisMsg)) { - logger.info("[收到REDIS通知] 请求: {}", new String(msg.getBody())); - - switch (wvpRedisMsg.getCmd()){ - case WvpRedisMsgCmd.GET_SEND_ITEM: - RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class); - requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); - break; - case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: - RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);; - requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); - break; - default: - break; + try { + JSONObject msgJSON = JSON.parseObject(msg.getBody(), JSONObject.class); + WvpRedisMsg wvpRedisMsg = JSON.toJavaObject(msgJSON, WvpRedisMsg.class); + if (!userSetting.getServerId().equals(wvpRedisMsg.getToId())) { + continue; } + if (WvpRedisMsg.isRequest(wvpRedisMsg)) { + logger.info("[收到REDIS通知] 请求: {}", new String(msg.getBody())); - }else { - logger.info("[收到REDIS通知] 回复: {}", new String(msg.getBody())); - switch (wvpRedisMsg.getCmd()){ - case WvpRedisMsgCmd.GET_SEND_ITEM: + switch (wvpRedisMsg.getCmd()){ + case WvpRedisMsgCmd.GET_SEND_ITEM: + RequestSendItemMsg content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestSendItemMsg.class); + requestSendItemMsgHand(content, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); + break; + case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: + RequestPushStreamMsg param = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), RequestPushStreamMsg.class);; + requestPushStreamMsgHand(param, wvpRedisMsg.getFromId(), wvpRedisMsg.getSerial()); + break; + default: + break; + } - WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); + }else { + logger.info("[收到REDIS通知] 回复: {}", new String(msg.getBody())); + switch (wvpRedisMsg.getCmd()){ + case WvpRedisMsgCmd.GET_SEND_ITEM: - String key = wvpRedisMsg.getSerial(); - switch (content.getCode()) { - case 0: - ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class); - PlayMsgCallback playMsgCallback = callbacks.get(key); - if (playMsgCallback != null) { - callbacksForError.remove(key); - try { - playMsgCallback.handler(responseSendItemMsg); - } catch (ParseException e) { - logger.error("[REDIS消息处理异常] ", e); + WVPResult content = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); + + String key = wvpRedisMsg.getSerial(); + switch (content.getCode()) { + case 0: + ResponseSendItemMsg responseSendItemMsg =JSON.toJavaObject((JSONObject)content.getData(), ResponseSendItemMsg.class); + PlayMsgCallback playMsgCallback = callbacks.get(key); + if (playMsgCallback != null) { + callbacksForError.remove(key); + try { + playMsgCallback.handler(responseSendItemMsg); + } catch (ParseException e) { + logger.error("[REDIS消息处理异常] ", e); + } } - } - break; - case ERROR_CODE_MEDIA_SERVER_NOT_FOUND: - case ERROR_CODE_OFFLINE: - case ERROR_CODE_TIMEOUT: - PlayMsgErrorCallback errorCallback = callbacksForError.get(key); - if (errorCallback != null) { - callbacks.remove(key); - errorCallback.handler(content); - } - break; - default: - break; - } - break; - case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: - WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); - String serial = wvpRedisMsg.getSerial(); - switch (wvpResult.getCode()) { - case 0: - JSONObject jsonObject = (JSONObject)wvpResult.getData(); - PlayMsgCallbackForStartSendRtpStream playMsgCallback = callbacksForStartSendRtpStream.get(serial); - if (playMsgCallback != null) { - callbacksForError.remove(serial); - playMsgCallback.handler(jsonObject); - } - break; - case ERROR_CODE_MEDIA_SERVER_NOT_FOUND: - case ERROR_CODE_OFFLINE: - case ERROR_CODE_TIMEOUT: - PlayMsgErrorCallback errorCallback = callbacksForError.get(serial); - if (errorCallback != null) { - callbacks.remove(serial); - errorCallback.handler(wvpResult); - } - break; - default: - break; - } - break; - default: - break; + break; + case ERROR_CODE_MEDIA_SERVER_NOT_FOUND: + case ERROR_CODE_OFFLINE: + case ERROR_CODE_TIMEOUT: + PlayMsgErrorCallback errorCallback = callbacksForError.get(key); + if (errorCallback != null) { + callbacks.remove(key); + errorCallback.handler(content); + } + break; + default: + break; + } + break; + case WvpRedisMsgCmd.REQUEST_PUSH_STREAM: + WVPResult wvpResult = JSON.toJavaObject((JSONObject)wvpRedisMsg.getContent(), WVPResult.class); + String serial = wvpRedisMsg.getSerial(); + switch (wvpResult.getCode()) { + case 0: + JSONObject jsonObject = (JSONObject)wvpResult.getData(); + PlayMsgCallbackForStartSendRtpStream playMsgCallback = callbacksForStartSendRtpStream.get(serial); + if (playMsgCallback != null) { + callbacksForError.remove(serial); + playMsgCallback.handler(jsonObject); + } + break; + case ERROR_CODE_MEDIA_SERVER_NOT_FOUND: + case ERROR_CODE_OFFLINE: + case ERROR_CODE_TIMEOUT: + PlayMsgErrorCallback errorCallback = callbacksForError.get(serial); + if (errorCallback != null) { + callbacks.remove(serial); + errorCallback.handler(wvpResult); + } + break; + default: + break; + } + break; + default: + break; + } } + }catch (Exception e) { + logger.warn("[RedisGbPlayMsg] 发现未处理的异常, {}",e.getMessage()); } } - taskQueueHandlerRun = false; }); } - - - - - - } /** diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java index c43a9375c..0c99707ed 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGpsMsgListener.java @@ -27,8 +27,6 @@ public class RedisGpsMsgListener implements MessageListener { private final static Logger logger = LoggerFactory.getLogger(RedisGpsMsgListener.class); - private boolean taskQueueHandlerRun = false; - @Autowired private IRedisCatchStorage redisCatchStorage; @@ -44,17 +42,20 @@ public class RedisGpsMsgListener implements MessageListener { @Override public void onMessage(@NotNull Message message, byte[] bytes) { + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); - GPSMsgInfo gpsMsgInfo = JSON.parseObject(msg.getBody(), GPSMsgInfo.class); - // 只是放入redis缓存起来 - redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo); + try { + GPSMsgInfo gpsMsgInfo = JSON.parseObject(msg.getBody(), GPSMsgInfo.class); + // 只是放入redis缓存起来 + redisCatchStorage.updateGpsMsgInfo(gpsMsgInfo); + }catch (Exception e) { + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); + } } - taskQueueHandlerRun = false; }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java index 05d662d75..33eae1eb6 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamResponseListener.java @@ -1,7 +1,6 @@ package com.genersoft.iot.vmp.service.redisMsg; import com.alibaba.fastjson2.JSON; -import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.service.bean.MessageForPushChannelResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,8 +25,6 @@ public class RedisPushStreamResponseListener implements MessageListener { private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamResponseListener.class); - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -43,24 +40,27 @@ public class RedisPushStreamResponseListener implements MessageListener { @Override public void onMessage(Message message, byte[] bytes) { - logger.warn("[REDIS消息-请求推流结果]: {}", new String(message.getBody())); + logger.info("[REDIS消息-请求推流结果]: {}", new String(message.getBody())); + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); - MessageForPushChannelResponse response = JSON.parseObject(new String(msg.getBody()), MessageForPushChannelResponse.class); - if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){ - logger.info("[REDIS消息-请求推流结果]:参数不全"); - continue; - } - // 查看正在等待的invite消息 - if (responseEvents.get(response.getApp() + response.getStream()) != null) { - responseEvents.get(response.getApp() + response.getStream()).run(response); + try { + MessageForPushChannelResponse response = JSON.parseObject(new String(msg.getBody()), MessageForPushChannelResponse.class); + if (response == null || ObjectUtils.isEmpty(response.getApp()) || ObjectUtils.isEmpty(response.getStream())){ + logger.info("[REDIS消息-请求推流结果]:参数不全"); + continue; + } + // 查看正在等待的invite消息 + if (responseEvents.get(response.getApp() + response.getStream()) != null) { + responseEvents.get(response.getApp() + response.getStream()).run(response); + } + }catch (Exception e) { + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); } } - taskQueueHandlerRun = false; }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java index 15e37ecff..d8ed1a010 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusListMsgListener.java @@ -6,7 +6,6 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; -import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; import com.genersoft.iot.vmp.utils.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,7 +17,8 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import javax.annotation.Resource; -import java.util.*; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; /** @@ -38,7 +38,6 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener { @Resource private IGbStreamService gbStreamService; - private boolean taskQueueHandlerRun = false; private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @@ -49,54 +48,56 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener { @Override public void onMessage(Message message, byte[] bytes) { logger.info("[REDIS消息-推流设备列表更新]: {}", new String(message.getBody())); - + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); - List streamPushItems = JSON.parseArray(new String(msg.getBody()), StreamPushItem.class); - //查询全部的app+stream 用于判断是添加还是修改 - List allAppAndStream = streamPushService.getAllAppAndStream(); + try { + List streamPushItems = JSON.parseArray(new String(msg.getBody()), StreamPushItem.class); + //查询全部的app+stream 用于判断是添加还是修改 + List allAppAndStream = streamPushService.getAllAppAndStream(); - /** - * 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表 - */ - List streamPushItemForSave = new ArrayList<>(); - List streamPushItemForUpdate = new ArrayList<>(); - for (StreamPushItem streamPushItem : streamPushItems) { - String app = streamPushItem.getApp(); - String stream = streamPushItem.getStream(); - boolean contains = allAppAndStream.contains(app + stream); - //不存在就添加 - if (!contains) { - streamPushItem.setStreamType("push"); - streamPushItem.setCreateTime(DateUtil.getNow()); - streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId()); - streamPushItem.setOriginType(2); - streamPushItem.setOriginTypeStr("rtsp_push"); - streamPushItem.setTotalReaderCount("0"); - streamPushItemForSave.add(streamPushItem); - } else { - //存在就只修改 name和gbId - streamPushItemForUpdate.add(streamPushItem); + /** + * 用于存储更具APP+Stream过滤后的数据,可以直接存入stream_push表与gb_stream表 + */ + List streamPushItemForSave = new ArrayList<>(); + List streamPushItemForUpdate = new ArrayList<>(); + for (StreamPushItem streamPushItem : streamPushItems) { + String app = streamPushItem.getApp(); + String stream = streamPushItem.getStream(); + boolean contains = allAppAndStream.contains(app + stream); + //不存在就添加 + if (!contains) { + streamPushItem.setStreamType("push"); + streamPushItem.setCreateTime(DateUtil.getNow()); + streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId()); + streamPushItem.setOriginType(2); + streamPushItem.setOriginTypeStr("rtsp_push"); + streamPushItem.setTotalReaderCount("0"); + streamPushItemForSave.add(streamPushItem); + } else { + //存在就只修改 name和gbId + streamPushItemForUpdate.add(streamPushItem); + } } - } - if (streamPushItemForSave.size() > 0) { + if (streamPushItemForSave.size() > 0) { - logger.info("添加{}条",streamPushItemForSave.size()); - logger.info(JSONObject.toJSONString(streamPushItemForSave)); - streamPushService.batchAdd(streamPushItemForSave); + logger.info("添加{}条",streamPushItemForSave.size()); + logger.info(JSONObject.toJSONString(streamPushItemForSave)); + streamPushService.batchAdd(streamPushItemForSave); - } - if(streamPushItemForUpdate.size()>0){ - logger.info("修改{}条",streamPushItemForUpdate.size()); - logger.info(JSONObject.toJSONString(streamPushItemForUpdate)); - gbStreamService.updateGbIdOrName(streamPushItemForUpdate); + } + if(streamPushItemForUpdate.size()>0){ + logger.info("修改{}条",streamPushItemForUpdate.size()); + logger.info(JSONObject.toJSONString(streamPushItemForUpdate)); + gbStreamService.updateGbIdOrName(streamPushItemForUpdate); + } + }catch (Exception e) { + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); } } - taskQueueHandlerRun = false; }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java index 4fafa1c31..96ff8e830 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamStatusMsgListener.java @@ -29,8 +29,6 @@ public class RedisPushStreamStatusMsgListener implements MessageListener, Applic private final static Logger logger = LoggerFactory.getLogger(RedisPushStreamStatusMsgListener.class); - private boolean taskQueueHandlerRun = false; - @Autowired private IRedisCatchStorage redisCatchStorage; @@ -50,37 +48,40 @@ public class RedisPushStreamStatusMsgListener implements MessageListener, Applic @Override public void onMessage(Message message, byte[] bytes) { + boolean isEmpty = taskQueue.isEmpty(); logger.warn("[REDIS消息-推流设备状态变化]: {}", new String(message.getBody())); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); - PushStreamStatusChangeFromRedisDto statusChangeFromPushStream = JSON.parseObject(msg.getBody(), PushStreamStatusChangeFromRedisDto.class); - if (statusChangeFromPushStream == null) { - logger.warn("[REDIS消息]推流设备状态变化消息解析失败"); - continue; - } - // 取消定时任务 - dynamicTask.stop(VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED); - if (statusChangeFromPushStream.isSetAllOffline()) { - // 所有设备离线 - streamPushService.allStreamOffline(); - } - if (statusChangeFromPushStream.getOfflineStreams() != null - && statusChangeFromPushStream.getOfflineStreams().size() > 0) { - // 更新部分设备离线 - streamPushService.offline(statusChangeFromPushStream.getOfflineStreams()); - } - if (statusChangeFromPushStream.getOnlineStreams() != null && - statusChangeFromPushStream.getOnlineStreams().size() > 0) { - // 更新部分设备上线 - streamPushService.online(statusChangeFromPushStream.getOnlineStreams()); + try { + PushStreamStatusChangeFromRedisDto statusChangeFromPushStream = JSON.parseObject(msg.getBody(), PushStreamStatusChangeFromRedisDto.class); + if (statusChangeFromPushStream == null) { + logger.warn("[REDIS消息]推流设备状态变化消息解析失败"); + continue; + } + // 取消定时任务 + dynamicTask.stop(VideoManagerConstants.VM_MSG_GET_ALL_ONLINE_REQUESTED); + if (statusChangeFromPushStream.isSetAllOffline()) { + // 所有设备离线 + streamPushService.allStreamOffline(); + } + if (statusChangeFromPushStream.getOfflineStreams() != null + && statusChangeFromPushStream.getOfflineStreams().size() > 0) { + // 更新部分设备离线 + streamPushService.offline(statusChangeFromPushStream.getOfflineStreams()); + } + if (statusChangeFromPushStream.getOnlineStreams() != null && + statusChangeFromPushStream.getOnlineStreams().size() > 0) { + // 更新部分设备上线 + streamPushService.online(statusChangeFromPushStream.getOnlineStreams()); + } + }catch (Exception e) { + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); } } - taskQueueHandlerRun = false; }); } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java index 3e73fc056..1cdc527a7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java +++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java @@ -33,8 +33,6 @@ public class RedisStreamMsgListener implements MessageListener { @Autowired private ZLMMediaListManager zlmMediaListManager; - private boolean taskQueueHandlerRun = false; - private ConcurrentLinkedQueue taskQueue = new ConcurrentLinkedQueue<>(); @Qualifier("taskExecutor") @@ -43,48 +41,50 @@ public class RedisStreamMsgListener implements MessageListener { @Override public void onMessage(Message message, byte[] bytes) { - + boolean isEmpty = taskQueue.isEmpty(); taskQueue.offer(message); - if (!taskQueueHandlerRun) { - taskQueueHandlerRun = true; + if (isEmpty) { taskExecutor.execute(() -> { while (!taskQueue.isEmpty()) { Message msg = taskQueue.poll(); - JSONObject steamMsgJson = JSON.parseObject(msg.getBody(), JSONObject.class); - if (steamMsgJson == null) { - logger.warn("[收到redis 流变化]消息解析失败"); - continue; - } - String serverId = steamMsgJson.getString("serverId"); + try { + JSONObject steamMsgJson = JSON.parseObject(msg.getBody(), JSONObject.class); + if (steamMsgJson == null) { + logger.warn("[收到redis 流变化]消息解析失败"); + continue; + } + String serverId = steamMsgJson.getString("serverId"); - if (userSetting.getServerId().equals(serverId)) { - // 自己发送的消息忽略即可 - continue; - } - logger.info("[收到redis 流变化]: {}", new String(message.getBody())); - String app = steamMsgJson.getString("app"); - String stream = steamMsgJson.getString("stream"); - boolean register = steamMsgJson.getBoolean("register"); - String mediaServerId = steamMsgJson.getString("mediaServerId"); - OnStreamChangedHookParam onStreamChangedHookParam = new OnStreamChangedHookParam(); - onStreamChangedHookParam.setSeverId(serverId); - onStreamChangedHookParam.setApp(app); - onStreamChangedHookParam.setStream(stream); - onStreamChangedHookParam.setRegist(register); - onStreamChangedHookParam.setMediaServerId(mediaServerId); - onStreamChangedHookParam.setCreateStamp(System.currentTimeMillis()/1000); - onStreamChangedHookParam.setAliveSecond(0L); - onStreamChangedHookParam.setTotalReaderCount("0"); - onStreamChangedHookParam.setOriginType(0); - onStreamChangedHookParam.setOriginTypeStr("0"); - onStreamChangedHookParam.setOriginTypeStr("unknown"); - if (register) { - zlmMediaListManager.addPush(onStreamChangedHookParam); - }else { - zlmMediaListManager.removeMedia(app, stream); + if (userSetting.getServerId().equals(serverId)) { + // 自己发送的消息忽略即可 + continue; + } + logger.info("[收到redis 流变化]: {}", new String(message.getBody())); + String app = steamMsgJson.getString("app"); + String stream = steamMsgJson.getString("stream"); + boolean register = steamMsgJson.getBoolean("register"); + String mediaServerId = steamMsgJson.getString("mediaServerId"); + OnStreamChangedHookParam onStreamChangedHookParam = new OnStreamChangedHookParam(); + onStreamChangedHookParam.setSeverId(serverId); + onStreamChangedHookParam.setApp(app); + onStreamChangedHookParam.setStream(stream); + onStreamChangedHookParam.setRegist(register); + onStreamChangedHookParam.setMediaServerId(mediaServerId); + onStreamChangedHookParam.setCreateStamp(System.currentTimeMillis()/1000); + onStreamChangedHookParam.setAliveSecond(0L); + onStreamChangedHookParam.setTotalReaderCount("0"); + onStreamChangedHookParam.setOriginType(0); + onStreamChangedHookParam.setOriginTypeStr("0"); + onStreamChangedHookParam.setOriginTypeStr("unknown"); + if (register) { + zlmMediaListManager.addPush(onStreamChangedHookParam); + }else { + zlmMediaListManager.removeMedia(app, stream); + } + }catch (Exception e) { + logger.warn("[REDIS的ALARM通知] 发现未处理的异常, {}",e.getMessage()); } } - taskQueueHandlerRun = false; }); } } From 9b8c1ad8c6dfb364102b1a0718d384e070b21682 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 29 Nov 2022 11:50:21 +0800 Subject: [PATCH 12/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=85=A8=E9=87=8F?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql.sql | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/sql/mysql.sql b/sql/mysql.sql index 869482cc5..27c6da103 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -1,4 +1,4 @@ --- MySQL dump 10.13 Distrib 8.0.30, for Linux (x86_64) +-- MySQL dump 10.13 Distrib 8.0.31, for Linux (x86_64) -- -- Host: 127.0.0.1 Database: wvp -- ------------------------------------------------------ @@ -34,13 +34,13 @@ CREATE TABLE `device` ( `online` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `registerTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `keepaliveTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, - `ip` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `port` int DEFAULT NULL, `expires` int DEFAULT NULL, `subscribeCycleForCatalog` int DEFAULT NULL, - `hostAddress` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `hostAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `charset` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `subscribeCycleForMobilePosition` int DEFAULT NULL, `mobilePositionSubmissionInterval` int DEFAULT '5', @@ -48,12 +48,13 @@ CREATE TABLE `device` ( `ssrcCheck` int DEFAULT '0', `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, - `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'auto', - `custom_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, - `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, + `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, + `sdpIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, + `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `device_deviceId_uindex` (`deviceId`) -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -145,7 +146,7 @@ CREATE TABLE `device_channel` ( PRIMARY KEY (`id`), UNIQUE KEY `device_channel_id_uindex` (`id`), UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) -) ENGINE=InnoDB AUTO_INCREMENT=60301 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=74416 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -215,7 +216,7 @@ CREATE TABLE `gb_stream` ( PRIMARY KEY (`gbStreamId`) USING BTREE, UNIQUE KEY `app` (`app`,`stream`) USING BTREE, UNIQUE KEY `gbId` (`gbId`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=301059 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=331060 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -245,7 +246,7 @@ CREATE TABLE `log` ( `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=733627 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=760908 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -337,7 +338,7 @@ CREATE TABLE `parent_platform` ( PRIMARY KEY (`id`), UNIQUE KEY `parent_platform_id_uindex` (`id`), UNIQUE KEY `parent_platform_pk` (`serverGBId`) -) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -389,7 +390,7 @@ CREATE TABLE `platform_gb_channel` ( `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `deviceChannelId` int NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=3146 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -415,7 +416,7 @@ CREATE TABLE `platform_gb_stream` ( `id` int NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`), UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) -) ENGINE=InnoDB AUTO_INCREMENT=301766 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=391772 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -457,7 +458,7 @@ CREATE TABLE `stream_proxy` ( `enable_disable_none_reader` bit(1) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) -) ENGINE=InnoDB AUTO_INCREMENT=548 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=568 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -494,7 +495,7 @@ CREATE TABLE `stream_push` ( `self` int DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `stream_push_pk` (`app`,`stream`) -) ENGINE=InnoDB AUTO_INCREMENT=310558 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=361492 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -572,4 +573,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2022-10-18 17:00:02 +-- Dump completed on 2022-11-29 11:47:46 \ No newline at end of file From 3aabbd69190dff1e2df755eed3c4820558371df3 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 29 Nov 2022 12:13:54 +0800 Subject: [PATCH 13/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/all-application.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 6240e4467..ba150fb95 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -150,8 +150,6 @@ media: enable: true # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 port-range: 30000,30500 # 端口范围 - # [可选] 国标级联在此范围内选择端口发送媒体流 - send-port-range: 30000,30500 # 端口范围 # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 record-assist-port: 0 From 170b0a18004639a1855939bcdd3384ea546deed4 Mon Sep 17 00:00:00 2001 From: WuPeng Date: Tue, 29 Nov 2022 21:41:55 +0800 Subject: [PATCH 14/20] =?UTF-8?q?=E5=BC=BA=E8=BF=AB=E7=97=87=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=8C=E5=B0=86=E6=95=B0=E6=8D=AE=E8=A1=A8ID?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=96=B0=E5=A2=9E=E5=80=BC=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=BA1=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql.sql | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/sql/mysql.sql b/sql/mysql.sql index 27c6da103..87c208fa8 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -54,7 +54,7 @@ CREATE TABLE `device` ( `localIp` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `device_deviceId_uindex` (`deviceId`) -) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -86,7 +86,7 @@ CREATE TABLE `device_alarm` ( `alarmType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -146,7 +146,7 @@ CREATE TABLE `device_channel` ( PRIMARY KEY (`id`), UNIQUE KEY `device_channel_id_uindex` (`id`), UNIQUE KEY `device_channel_pk` (`channelId`,`deviceId`) -) ENGINE=InnoDB AUTO_INCREMENT=74416 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -183,7 +183,7 @@ CREATE TABLE `device_mobile_position` ( `latitudeWgs84` double DEFAULT NULL, `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=55589 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -216,7 +216,7 @@ CREATE TABLE `gb_stream` ( PRIMARY KEY (`gbStreamId`) USING BTREE, UNIQUE KEY `app` (`app`,`stream`) USING BTREE, UNIQUE KEY `gbId` (`gbId`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=331060 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -246,7 +246,7 @@ CREATE TABLE `log` ( `username` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=760908 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -338,7 +338,7 @@ CREATE TABLE `parent_platform` ( PRIMARY KEY (`id`), UNIQUE KEY `parent_platform_id_uindex` (`id`), UNIQUE KEY `parent_platform_pk` (`serverGBId`) -) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -384,13 +384,14 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `platform_gb_channel`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `platform_gb_channel` ( - `id` int NOT NULL AUTO_INCREMENT, - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, - `deviceChannelId` int NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=3146 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +CREATE TABLE `platform_gb_stream` ( + `id` int NOT NULL AUTO_INCREMENT, + `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `gbStreamId` int NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -406,17 +407,16 @@ UNLOCK TABLES; -- Table structure for table `platform_gb_stream` -- -DROP TABLE IF EXISTS `platform_gb_stream`; +CREATE TABLE `platform_gb_channel` ( + `id` int NOT NULL AUTO_INCREMENT, + `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, + `deviceChannelId` int NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; -CREATE TABLE `platform_gb_stream` ( - `platformId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, - `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, - `gbStreamId` int NOT NULL, - `id` int NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`id`), - UNIQUE KEY `platform_gb_stream_pk` (`platformId`,`catalogId`,`gbStreamId`) -) ENGINE=InnoDB AUTO_INCREMENT=391772 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +DROP TABLE IF EXISTS `platform_gb_stream`; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -458,7 +458,7 @@ CREATE TABLE `stream_proxy` ( `enable_disable_none_reader` bit(1) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `stream_proxy_pk` (`app`,`stream`) -) ENGINE=InnoDB AUTO_INCREMENT=568 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -495,7 +495,7 @@ CREATE TABLE `stream_push` ( `self` int DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `stream_push_pk` (`app`,`stream`) -) ENGINE=InnoDB AUTO_INCREMENT=361492 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -524,7 +524,7 @@ CREATE TABLE `user` ( `pushKey` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `user_username_uindex` (`username`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -551,7 +551,7 @@ CREATE TABLE `user_role` ( `createTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `updateTime` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC; /*!40101 SET character_set_client = @saved_cs_client */; -- From 2d8f57f3c9641f9b5a14f983a18f9c3e141f030b Mon Sep 17 00:00:00 2001 From: xiaoQQya Date: Wed, 30 Nov 2022 16:29:30 +0800 Subject: [PATCH 15/20] =?UTF-8?q?fix(devicePlayer):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E8=A7=86=E9=A2=91=E6=92=AD=E6=94=BE=E9=A1=B5?= =?UTF-8?q?=20RTCS=20=E5=9C=B0=E5=9D=80=E6=98=BE=E7=A4=BA=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web_src/src/components/dialog/devicePlayer.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index 7c16c7cde..e7fc28f63 100644 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -123,7 +123,7 @@ RTCS: - {{ streamInfo.rtcs }} + {{ streamInfo.rtcs.url }} RTMP: From 8f39254dd0eb7ea5cff874ae06198c983171b5a3 Mon Sep 17 00:00:00 2001 From: xiaoQQya Date: Wed, 30 Nov 2022 16:32:28 +0800 Subject: [PATCH 16/20] =?UTF-8?q?perf(PlayService):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=88=AA=E5=9B=BE=E8=AF=B7=E6=B1=82=E4=BD=BF=E7=94=A8=20FLV=20?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=EF=BC=8C=E8=A7=A3=E5=86=B3=20RTSP=20?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E6=88=AA=E5=9B=BE=E5=87=BA=E7=8E=B0=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E4=B8=A2=E5=8C=85=E6=A8=A1=E7=B3=8A=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 75fff7f66..a2b879451 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -271,7 +271,7 @@ public class PlayServiceImpl implements IPlayService { onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId); hookEvent.response(mediaServerItemInuse, response); logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId); - String streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream()); + String streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.flv", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream()); String path = "snap"; String fileName = device.getDeviceId() + "_" + channelId + ".jpg"; // 请求截图 From 142b17cc7665c573dc3fb378e926fe0c770ee385 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Fri, 2 Dec 2022 15:12:56 +0800 Subject: [PATCH 17/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/web/gb28181/ApiStreamController.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java index ab769f5bb..5381a3aec 100644 --- a/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java +++ b/src/main/java/com/genersoft/iot/vmp/web/gb28181/ApiStreamController.java @@ -12,7 +12,6 @@ import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.service.IPlayService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; -import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -120,12 +119,12 @@ public class ApiStreamController { result.put("ChannelID", code); result.put("ChannelName", deviceChannel.getName()); result.put("ChannelCustomName", ""); - result.put("FLV", streamInfo.getFlv()); - result.put("WS_FLV", streamInfo.getWs_flv()); - result.put("RTMP", streamInfo.getRtmp()); - result.put("HLS", streamInfo.getHls()); - result.put("RTSP", streamInfo.getRtsp()); - result.put("WEBRTC", streamInfo.getRtc()); + result.put("FLV", streamInfo.getFlv().getUrl()); + result.put("WS_FLV", streamInfo.getWs_flv().getUrl()); + result.put("RTMP", streamInfo.getRtmp().getUrl()); + result.put("HLS", streamInfo.getHls().getUrl()); + result.put("RTSP", streamInfo.getRtsp().getUrl()); + result.put("WEBRTC", streamInfo.getRtc().getUrl()); result.put("CDN", ""); result.put("SnapURL", ""); result.put("Transport", device.getTransport()); From 131ea7766924113f6d0b8d8d4c288084ae635a31 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 6 Dec 2022 10:33:43 +0800 Subject: [PATCH 18/20] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=97=A7=E7=9A=84stream=E4=BF=A1=E6=81=AF=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BD=BF=E7=94=A8=E8=BF=9C=E7=A8=8Bip=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E5=81=9A=E4=B8=BA=E5=9B=9E=E5=A4=8D=E7=9A=84=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E8=80=8C=E4=B8=8D=E6=98=AF=E4=BD=BF=E7=94=A8sip?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/conf/UserSetting.java | 10 + .../vmp/gb28181/bean/RemoteAddressInfo.java | 27 ++ .../impl/RegisterRequestProcessor.java | 24 +- .../cmd/KeepaliveNotifyMessageHandler.java | 37 +- .../iot/vmp/gb28181/utils/SipUtils.java | 23 ++ .../vmp/media/zlm/ZLMHttpHookListener.java | 7 +- .../dto/hook/OnStreamChangedHookParam.java | 8 +- .../vmp/service/impl/DeviceServiceImpl.java | 1 - .../iot/vmp/vmanager/bean/StreamContent.java | 325 ++++++++++++++++++ .../gb28181/media/MediaController.java | 17 +- .../vmanager/gb28181/play/PlayController.java | 35 +- .../streamProxy/StreamProxyController.java | 6 +- .../streamPush/StreamPushController.java | 16 +- src/main/resources/all-application.yml | 2 + .../src/components/dialog/devicePlayer.vue | 92 ++--- 15 files changed, 503 insertions(+), 127 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/gb28181/bean/RemoteAddressInfo.java create mode 100644 src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index eeee438fd..92528a34c 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -35,6 +35,8 @@ public class UserSetting { private Boolean useSourceIpAsStreamIp = Boolean.FALSE; + private Boolean sipUseSourceIpAsRemoteAddress = Boolean.TRUE; + private Boolean streamOnDemand = Boolean.TRUE; private Boolean pushAuthority = Boolean.TRUE; @@ -196,4 +198,12 @@ public class UserSetting { public void setSyncChannelOnDeviceOnline(Boolean syncChannelOnDeviceOnline) { this.syncChannelOnDeviceOnline = syncChannelOnDeviceOnline; } + + public Boolean getSipUseSourceIpAsRemoteAddress() { + return sipUseSourceIpAsRemoteAddress; + } + + public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) { + this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RemoteAddressInfo.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RemoteAddressInfo.java new file mode 100644 index 000000000..4107593fe --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/RemoteAddressInfo.java @@ -0,0 +1,27 @@ +package com.genersoft.iot.vmp.gb28181.bean; + +public class RemoteAddressInfo { + private String ip; + private int port; + + public RemoteAddressInfo(String ip, int port) { + this.ip = ip; + this.port = port; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index ded86ae2c..0f37bde6d 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -1,13 +1,16 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl; import com.genersoft.iot.vmp.conf.SipConfig; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper; import com.genersoft.iot.vmp.gb28181.bean.Device; +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; import com.genersoft.iot.vmp.gb28181.bean.WvpSipDate; import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.SIPSender; import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.service.IDeviceService; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.RequestEventExt; @@ -56,6 +59,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen @Autowired private SIPSender sipSender; + @Autowired + private UserSetting userSetting; + @Override public void afterPropertiesSet() throws Exception { // 添加消息处理的订阅 @@ -125,15 +131,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen // 添加Expires头 response.addHeader(request.getExpires()); - // 获取到通信地址等信息 - ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); - String received = viaHeader.getReceived(); - int rPort = viaHeader.getRPort(); - // 解析本地地址替代 - if (ObjectUtils.isEmpty(received) || rPort == -1) { - received = viaHeader.getHost(); - rPort = viaHeader.getPort(); - } + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, + userSetting.getSipUseSourceIpAsRemoteAddress()); + if (device == null) { device = new Device(); device.setStreamMode("UDP"); @@ -143,9 +143,9 @@ public class RegisterRequestProcessor extends SIPRequestProcessorParent implemen device.setDeviceId(deviceId); device.setOnline(0); } - device.setIp(received); - device.setPort(rPort); - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); + device.setIp(remoteAddressInfo.getIp()); + device.setPort(remoteAddressInfo.getPort()); + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort()))); device.setLocalIp(request.getLocalAddress().getHostAddress()); if (request.getExpires().getExpires() == 0) { // 注销成功 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 28469034e..5751a11a4 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -1,14 +1,14 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.cmd; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; -import com.genersoft.iot.vmp.gb28181.event.EventPublisher; +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; +import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.service.IDeviceService; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; -import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.DateUtil; import gov.nist.javax.sip.message.SIPRequest; import org.dom4j.Element; @@ -17,13 +17,10 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; import javax.sip.SipException; -import javax.sip.header.ViaHeader; import javax.sip.message.Response; import java.text.ParseException; @@ -33,6 +30,7 @@ import java.text.ParseException; @Component public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { + private Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; @@ -42,6 +40,9 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp @Autowired private IDeviceService deviceService; + @Autowired + private UserSetting userSetting; + @Override public void afterPropertiesSet() throws Exception { notifyMessageHandler.addHandler(cmdType, this); @@ -53,25 +54,19 @@ public class KeepaliveNotifyMessageHandler extends SIPRequestProcessorParent imp // 未注册的设备不做处理 return; } + SIPRequest request = (SIPRequest) evt.getRequest(); // 回复200 OK try { - responseAck((SIPRequest) evt.getRequest(), Response.OK); + responseAck(request, Response.OK); } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[命令发送失败] 国标级联 心跳回复: {}", e.getMessage()); + logger.error("[命令发送失败] 心跳回复: {}", e.getMessage()); } - // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 - // 获取到通信地址等信息 - ViaHeader viaHeader = (ViaHeader) evt.getRequest().getHeader(ViaHeader.NAME); - String received = viaHeader.getReceived(); - int rPort = viaHeader.getRPort(); - // 解析本地地址替代 - if (ObjectUtils.isEmpty(received) || rPort == -1) { - received = viaHeader.getHost(); - rPort = viaHeader.getPort(); - } - if (device.getPort() != rPort) { - device.setPort(rPort); - device.setHostAddress(received.concat(":").concat(String.valueOf(rPort))); + + RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); + if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort()) { + device.setPort(remoteAddressInfo.getPort()); + device.setHostAddress(remoteAddressInfo.getIp().concat(":").concat(String.valueOf(remoteAddressInfo.getPort()))); + device.setIp(remoteAddressInfo.getIp()); } device.setKeepaliveTime(DateUtil.getNow()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java index 26c8e4efe..5c31f904e 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java @@ -1,9 +1,11 @@ package com.genersoft.iot.vmp.gb28181.utils; +import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; import com.genersoft.iot.vmp.utils.GitUtil; import gov.nist.javax.sip.address.AddressImpl; import gov.nist.javax.sip.address.SipUri; import gov.nist.javax.sip.header.Subject; +import gov.nist.javax.sip.message.SIPRequest; import org.springframework.util.ObjectUtils; import javax.sip.PeerUnavailableException; @@ -119,4 +121,25 @@ public class SipUtils { return builder.toString(); } + public static RemoteAddressInfo getRemoteAddressFromRequest(SIPRequest request, boolean sipUseSourceIpAsRemoteAddress) { + + String remoteAddress; + int remotePort; + if (sipUseSourceIpAsRemoteAddress) { + remoteAddress = request.getRemoteAddress().getHostAddress(); + remotePort = request.getRemotePort(); + }else { + // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 + // 获取到通信地址等信息 + remoteAddress = request.getTopmostViaHeader().getReceived(); + remotePort = request.getTopmostViaHeader().getPort(); + // 解析本地地址替代 + if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) { + remoteAddress = request.getViaHost(); + remotePort = request.getViaPort(); + } + } + + return new RemoteAddressInfo(remoteAddress, remotePort); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 54a28905e..5c5dcab0c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -18,6 +18,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.hook.*; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -347,7 +348,7 @@ public class ZLMHttpHookListener { } StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem, param.getApp(), param.getStream(), tracks, callId); - param.setStreamInfo(streamInfoByAppAndStream); + param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); redisCatchStorage.addStream(mediaServerItem, type, param.getApp(), param.getStream(), param); if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() || param.getOriginType() == OriginType.RTMP_PUSH.ordinal() @@ -364,7 +365,7 @@ public class ZLMHttpHookListener { } GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream()); if (gbStream != null) { -// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); +// eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); } zlmMediaListManager.removeMedia(param.getApp(), param.getStream()); } @@ -527,7 +528,7 @@ public class ZLMHttpHookListener { @ResponseBody @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") public JSONObject onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param){ - logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + logger.info("[ZLM HOOK] 流未找到:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); taskExecutor.execute(()->{ MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); if (userSetting.isAutoApplyPlay() && mediaInfo != null) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java index 29f91c8ba..07c09e69f 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java @@ -1,6 +1,6 @@ package com.genersoft.iot.vmp.media.zlm.dto.hook; -import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import java.util.List; @@ -291,7 +291,7 @@ public class OnStreamChangedHookParam extends HookParam{ } } - private StreamInfo streamInfo; + private StreamContent streamInfo; public String getApp() { return app; @@ -407,11 +407,11 @@ public class OnStreamChangedHookParam extends HookParam{ this.docker = docker; } - public StreamInfo getStreamInfo() { + public StreamContent getStreamInfo() { return streamInfo; } - public void setStreamInfo(StreamInfo streamInfo) { + public void setStreamInfo(StreamContent streamInfo) { this.streamInfo = streamInfo; } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java index d25e537e6..0d56fdb5f 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java @@ -332,7 +332,6 @@ public class DeviceServiceImpl implements IDeviceService { device.setUpdateTime(DateUtil.getNow()); if (deviceMapper.update(device) > 0) { redisCatchStorage.updateDevice(device); - } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java new file mode 100644 index 000000000..368399b52 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java @@ -0,0 +1,325 @@ +package com.genersoft.iot.vmp.vmanager.bean; + +import com.genersoft.iot.vmp.common.StreamInfo; + +public class StreamContent { + + private String app; + private String stream; + + private String ip; + + private String flv; + + private String https_flv; + private String ws_flv; + private String wss_flv; + private String fmp4; + private String https_fmp4; + private String ws_fmp4; + private String wss_fmp4; + private String hls; + private String https_hls; + private String ws_hls; + private String wss_hls; + private String ts; + private String https_ts; + private String ws_ts; + private String wss_ts; + private String rtmp; + private String rtmps; + private String rtsp; + private String rtsps; + private String rtc; + + private String rtcs; + private String mediaServerId; + private Object tracks; + + public StreamContent(StreamInfo streamInfo) { + if (streamInfo == null) { + return; + } + this.app = streamInfo.getApp(); + this.stream = streamInfo.getStream(); + if (streamInfo.getFlv() != null) { + this.flv = streamInfo.getFlv().getUrl(); + } + if (streamInfo.getHttps_flv() != null) { + this.https_flv = streamInfo.getHttps_flv().getUrl(); + } + if (streamInfo.getWs_flv() != null) { + this.ws_flv = streamInfo.getWs_flv().getUrl(); + } + if (streamInfo.getWss_flv() != null) { + this.wss_flv = streamInfo.getWss_flv().getUrl(); + } + if (streamInfo.getFmp4() != null) { + this.fmp4 = streamInfo.getFmp4().getUrl(); + } + if (streamInfo.getWs_fmp4() != null) { + this.ws_fmp4 = streamInfo.getWs_fmp4().getUrl(); + } + if (streamInfo.getWss_fmp4() != null) { + this.wss_fmp4 = streamInfo.getWss_fmp4().getUrl(); + } + if (streamInfo.getHls() != null) { + this.hls = streamInfo.getHls().getUrl(); + } + if (streamInfo.getHttps_hls() != null) { + this.https_hls = streamInfo.getHttps_hls().getUrl(); + } + if (streamInfo.getWs_hls() != null) { + this.ws_hls = streamInfo.getWs_hls().getUrl(); + } + if (streamInfo.getWss_hls() != null) { + this.wss_hls = streamInfo.getWss_hls().getUrl(); + } + if (streamInfo.getTs() != null) { + this.ts = streamInfo.getTs().getUrl(); + } + if (streamInfo.getHttps_ts() != null) { + this.https_ts = streamInfo.getHttps_ts().getUrl(); + } + if (streamInfo.getWs_ts() != null) { + this.ws_ts = streamInfo.getWs_ts().getUrl(); + } + if (streamInfo.getRtmp() != null) { + this.rtmp = streamInfo.getRtmp().getUrl(); + } + if (streamInfo.getRtmps() != null) { + this.rtmps = streamInfo.getRtmps().getUrl(); + } + if (streamInfo.getRtsp() != null) { + this.rtsp = streamInfo.getRtsp().getUrl(); + } + if (streamInfo.getRtsps() != null) { + this.rtsps = streamInfo.getRtsps().getUrl(); + } + if (streamInfo.getRtc() != null) { + this.rtc = streamInfo.getRtc().getUrl(); + } + if (streamInfo.getRtcs() != null) { + this.rtcs = streamInfo.getRtcs().getUrl(); + } + + this.mediaServerId = streamInfo.getMediaServerId(); + this.tracks = streamInfo.getTracks(); + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getFlv() { + return flv; + } + + public void setFlv(String flv) { + this.flv = flv; + } + + public String getHttps_flv() { + return https_flv; + } + + public void setHttps_flv(String https_flv) { + this.https_flv = https_flv; + } + + public String getWs_flv() { + return ws_flv; + } + + public void setWs_flv(String ws_flv) { + this.ws_flv = ws_flv; + } + + public String getWss_flv() { + return wss_flv; + } + + public void setWss_flv(String wss_flv) { + this.wss_flv = wss_flv; + } + + public String getFmp4() { + return fmp4; + } + + public void setFmp4(String fmp4) { + this.fmp4 = fmp4; + } + + public String getHttps_fmp4() { + return https_fmp4; + } + + public void setHttps_fmp4(String https_fmp4) { + this.https_fmp4 = https_fmp4; + } + + public String getWs_fmp4() { + return ws_fmp4; + } + + public void setWs_fmp4(String ws_fmp4) { + this.ws_fmp4 = ws_fmp4; + } + + public String getWss_fmp4() { + return wss_fmp4; + } + + public void setWss_fmp4(String wss_fmp4) { + this.wss_fmp4 = wss_fmp4; + } + + public String getHls() { + return hls; + } + + public void setHls(String hls) { + this.hls = hls; + } + + public String getHttps_hls() { + return https_hls; + } + + public void setHttps_hls(String https_hls) { + this.https_hls = https_hls; + } + + public String getWs_hls() { + return ws_hls; + } + + public void setWs_hls(String ws_hls) { + this.ws_hls = ws_hls; + } + + public String getWss_hls() { + return wss_hls; + } + + public void setWss_hls(String wss_hls) { + this.wss_hls = wss_hls; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + + public String getHttps_ts() { + return https_ts; + } + + public void setHttps_ts(String https_ts) { + this.https_ts = https_ts; + } + + public String getWs_ts() { + return ws_ts; + } + + public void setWs_ts(String ws_ts) { + this.ws_ts = ws_ts; + } + + public String getWss_ts() { + return wss_ts; + } + + public void setWss_ts(String wss_ts) { + this.wss_ts = wss_ts; + } + + public String getRtmp() { + return rtmp; + } + + public void setRtmp(String rtmp) { + this.rtmp = rtmp; + } + + public String getRtmps() { + return rtmps; + } + + public void setRtmps(String rtmps) { + this.rtmps = rtmps; + } + + public String getRtsp() { + return rtsp; + } + + public void setRtsp(String rtsp) { + this.rtsp = rtsp; + } + + public String getRtsps() { + return rtsps; + } + + public void setRtsps(String rtsps) { + this.rtsps = rtsps; + } + + public String getRtc() { + return rtc; + } + + public void setRtc(String rtc) { + this.rtc = rtc; + } + + public String getRtcs() { + return rtcs; + } + + public void setRtcs(String rtcs) { + this.rtcs = rtcs; + } + + public String getMediaServerId() { + return mediaServerId; + } + + public void setMediaServerId(String mediaServerId) { + this.mediaServerId = mediaServerId; + } + + public Object getTracks() { + return tracks; + } + + public void setTracks(Object tracks) { + this.tracks = tracks; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java index 7e73e0582..812e04445 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java @@ -5,10 +5,11 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException; import com.genersoft.iot.vmp.conf.security.SecurityUtils; import com.genersoft.iot.vmp.conf.security.dto.LoginUser; import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.service.IMediaService; +import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -53,11 +54,11 @@ public class MediaController { @Parameter(name = "useSourceIpAsStreamIp", description = "是否使用请求IP作为返回的地址IP") @GetMapping(value = "/stream_info_by_app_and_stream") @ResponseBody - public StreamInfo getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app, - @RequestParam String stream, - @RequestParam(required = false) String mediaServerId, - @RequestParam(required = false) String callId, - @RequestParam(required = false) Boolean useSourceIpAsStreamIp){ + public StreamContent getStreamInfoByAppAndStream(HttpServletRequest request, @RequestParam String app, + @RequestParam String stream, + @RequestParam(required = false) String mediaServerId, + @RequestParam(required = false) String callId, + @RequestParam(required = false) Boolean useSourceIpAsStreamIp){ boolean authority = false; if (callId != null) { // 权限校验 @@ -90,7 +91,7 @@ public class MediaController { WVPResult result = new WVPResult<>(); if (streamInfo != null){ - return streamInfo; + return new StreamContent(streamInfo); }else { //获取流失败,重启拉流后重试一次 streamProxyService.stop(app,stream); @@ -109,7 +110,7 @@ public class MediaController { streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority); } if (streamInfo != null){ - return streamInfo; + return new StreamContent(streamInfo); }else { throw new ControllerException(ErrorCode.ERROR100); } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java index 9fed0c59d..46aa63cc9 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java @@ -21,6 +21,7 @@ import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.vmanager.bean.DeferredResultEx; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -80,8 +81,8 @@ public class PlayController { @Parameter(name = "deviceId", description = "设备国标编号", required = true) @Parameter(name = "channelId", description = "通道国标编号", required = true) @GetMapping("/start/{deviceId}/{channelId}") - public DeferredResult> play(HttpServletRequest request, @PathVariable String deviceId, - @PathVariable String channelId) { + public DeferredResult> play(HttpServletRequest request, @PathVariable String deviceId, + @PathVariable String channelId) { // 获取可用的zlm Device device = storager.queryVideoDevice(deviceId); @@ -93,8 +94,8 @@ public class PlayController { msg.setKey(key); String uuid = UUID.randomUUID().toString(); msg.setId(uuid); - DeferredResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); - DeferredResultEx> deferredResultEx = new DeferredResultEx<>(result); + DeferredResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + DeferredResultEx> deferredResultEx = new DeferredResultEx<>(result); result.onTimeout(()->{ logger.info("点播接口等待超时"); @@ -106,24 +107,24 @@ public class PlayController { resultHolder.invokeResult(msg); }); - if (userSetting.getUseSourceIpAsStreamIp()) { + // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误 deferredResultEx.setFilter(result1 -> { WVPResult wvpResult1 = (WVPResult)result1; - WVPResult clone = null; - try { - clone = (WVPResult)wvpResult1.clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); + WVPResult resultStream = null; + if (wvpResult1.getCode() == ErrorCode.SUCCESS.getCode()) { + StreamInfo data = wvpResult1.getData().clone(); + if (userSetting.getUseSourceIpAsStreamIp()) { + data.channgeStreamIp(request.getLocalName()); + } + resultStream = new WVPResult<>(); + resultStream.setCode(wvpResult1.getCode()); + resultStream.setMsg(wvpResult1.getMsg()); + resultStream.setData(new StreamContent(wvpResult1.getData())); } - if (clone.getCode() == ErrorCode.SUCCESS.getCode()) { - StreamInfo data = clone.getData().clone(); - data.channgeStreamIp(request.getLocalName()); - clone.setData(data); - } - return clone; + return resultStream; }); - } + // 录像查询以channelId作为deviceId查询 resultHolder.put(key, uuid, deferredResultEx); diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java index d1368d818..65ec3d339 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamProxy/StreamProxyController.java @@ -1,13 +1,13 @@ package com.genersoft.iot.vmp.vmanager.streamProxy; import com.alibaba.fastjson2.JSONObject; -import com.genersoft.iot.vmp.common.StreamInfo; 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.StreamProxyItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamProxyService; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -58,7 +58,7 @@ public class StreamProxyController { }) @PostMapping(value = "/save") @ResponseBody - public StreamInfo save(@RequestBody StreamProxyItem param){ + public StreamContent save(@RequestBody StreamProxyItem param){ logger.info("添加代理: " + JSONObject.toJSONString(param)); if (ObjectUtils.isEmpty(param.getMediaServerId())) { param.setMediaServerId("auto"); @@ -69,7 +69,7 @@ public class StreamProxyController { if (ObjectUtils.isEmpty(param.getGbId())) { param.setGbId(null); } - return streamProxyService.save(param); + return new StreamContent(streamProxyService.save(param)); } @GetMapping(value = "/ffmpeg_cmd/list") diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java index d0aff58e3..7506433f9 100644 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java @@ -11,22 +11,16 @@ import com.genersoft.iot.vmp.conf.security.dto.LoginUser; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; -import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IMediaService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.service.impl.StreamPushUploadFileHandler; -import com.genersoft.iot.vmp.vmanager.bean.BatchGBStreamParam; -import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; -import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto; -import com.genersoft.iot.vmp.vmanager.bean.WVPResult; +import com.genersoft.iot.vmp.vmanager.bean.*; import com.github.pagehelper.PageInfo; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import org.apache.poi.sl.usermodel.Sheet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -34,12 +28,10 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.async.DeferredResult; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; @@ -243,8 +235,8 @@ public class StreamPushController { @Parameter(name = "app", description = "应用名", required = true) @Parameter(name = "stream", description = "流id", required = true) @Parameter(name = "mediaServerId", description = "媒体服务器id") - public StreamInfo getPlayUrl(@RequestParam String app,@RequestParam String stream, - @RequestParam(required = false) String mediaServerId){ + public StreamContent getPlayUrl(@RequestParam String app, @RequestParam String stream, + @RequestParam(required = false) String mediaServerId){ boolean authority = false; // 是否登陆用户, 登陆用户返回完整信息 LoginUser userInfo = SecurityUtils.getUserInfo(); @@ -259,7 +251,7 @@ public class StreamPushController { if (streamInfo == null){ throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取播放地址失败"); } - return streamInfo; + return new StreamContent(streamInfo); } /** diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index ba150fb95..491544beb 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -195,6 +195,8 @@ user-settings: gb-send-stream-strict: false # 设备上线时是否自动同步通道 sync-channel-on-device-online: false + # 设备上线时是否自动同步通道 + sip-use-source-ip-as-remote-address: true # 关闭在线文档(生产环境建议关闭) springdoc: diff --git a/web_src/src/components/dialog/devicePlayer.vue b/web_src/src/components/dialog/devicePlayer.vue index e7fc28f63..9ecbb9b2d 100644 --- a/web_src/src/components/dialog/devicePlayer.vue +++ b/web_src/src/components/dialog/devicePlayer.vue @@ -53,93 +53,93 @@ 更多地址 - + FLV: - {{ streamInfo.flv.url }} + {{ streamInfo.flv }} - + FLV(https): - {{ streamInfo.https_flv.url }} + {{ streamInfo.https_flv }} - + FLV(ws): - {{ streamInfo.ws_flv.url }} + {{ streamInfo.ws_flv }} - + FLV(wss): - {{ streamInfo.wss_flv.url }} + {{ streamInfo.wss_flv }} - + FMP4: - {{ streamInfo.fmp4.url }} + {{ streamInfo.fmp4 }} - + FMP4(https): - {{ streamInfo.https_fmp4.url }} + {{ streamInfo.https_fmp4 }} - + FMP4(ws): - {{ streamInfo.ws_fmp4.url }} + {{ streamInfo.ws_fmp4 }} - + FMP4(wss): - {{ streamInfo.wss_fmp4.url }} + {{ streamInfo.wss_fmp4 }} - + HLS: - {{ streamInfo.hls.url }} + {{ streamInfo.hls }} - + HLS(https): - {{ streamInfo.https_hls.url }} + {{ streamInfo.https_hls }} - + HLS(ws): - {{ streamInfo.ws_hls.url }} + {{ streamInfo.ws_hls }} - + HLS(wss): - {{ streamInfo.wss_hls.url }} + {{ streamInfo.wss_hls }} - + TS: - {{ streamInfo.ts.url }} + {{ streamInfo.ts }} - + TS(https): - {{ streamInfo.https_ts.url }} + {{ streamInfo.https_ts }} - + TS(ws): - {{ streamInfo.ws_ts.url }} + {{ streamInfo.ws_ts }} - + TS(wss): - {{ streamInfo.wss_ts.url }} + {{ streamInfo.wss_ts }} - + RTC: - {{ streamInfo.rtc.url }} + {{ streamInfo.rtc }} - + RTCS: - {{ streamInfo.rtcs.url }} + {{ streamInfo.rtcs }} - + RTMP: - {{ streamInfo.rtmp.url }} + {{ streamInfo.rtmp }} - + RTMPS: - {{ streamInfo.rtmps.url }} + {{ streamInfo.rtmps }} - + RTSP: - {{ streamInfo.rtsp.url }} + {{ streamInfo.rtsp }} - + RTSPS: - {{ streamInfo.rtsps.url }} + {{ streamInfo.rtsps }} @@ -450,9 +450,9 @@ export default { getUrlByStreamInfo(){ console.log(this.streamInfo) if (location.protocol === "https:") { - this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]].url + this.videoUrl = this.streamInfo[this.player[this.activePlayer][1]] }else { - this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]].url + this.videoUrl = this.streamInfo[this.player[this.activePlayer][0]] } return this.videoUrl; From 5606bce885c444df46b81432a725f34a490383e8 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 6 Dec 2022 16:35:14 +0800 Subject: [PATCH 19/20] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=BB=8D=E4=BD=BF?= =?UTF-8?q?=E7=94=A8via=20ip=20=E5=81=9A=E4=B8=BA=E5=9B=9E=E5=A4=8D?= =?UTF-8?q?=E7=9A=84ip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java index 92528a34c..72f5d14c1 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java @@ -35,7 +35,7 @@ public class UserSetting { private Boolean useSourceIpAsStreamIp = Boolean.FALSE; - private Boolean sipUseSourceIpAsRemoteAddress = Boolean.TRUE; + private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE; private Boolean streamOnDemand = Boolean.TRUE; From 151699137259a9a92463b36795a5f935c62349c6 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Tue, 6 Dec 2022 17:12:12 +0800 Subject: [PATCH 20/20] =?UTF-8?q?=E5=9B=9E=E6=BB=9Avia=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/vmp/gb28181/utils/SipUtils.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java index 5c31f904e..56fdb5b68 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/utils/SipUtils.java @@ -13,6 +13,7 @@ import javax.sip.SipFactory; import javax.sip.header.FromHeader; import javax.sip.header.Header; import javax.sip.header.UserAgentHeader; +import javax.sip.header.ViaHeader; import javax.sip.message.Request; import java.text.ParseException; import java.util.ArrayList; @@ -121,6 +122,12 @@ public class SipUtils { return builder.toString(); } + /** + * 从请求中获取设备ip地址和端口号 + * @param request 请求 + * @param sipUseSourceIpAsRemoteAddress false 从via中获取地址, true 直接获取远程地址 + * @return 地址信息 + */ public static RemoteAddressInfo getRemoteAddressFromRequest(SIPRequest request, boolean sipUseSourceIpAsRemoteAddress) { String remoteAddress; @@ -131,12 +138,13 @@ public class SipUtils { }else { // 判断RPort是否改变,改变则说明路由nat信息变化,修改设备信息 // 获取到通信地址等信息 - remoteAddress = request.getTopmostViaHeader().getReceived(); - remotePort = request.getTopmostViaHeader().getPort(); + ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME); + remoteAddress = viaHeader.getReceived(); + remotePort = viaHeader.getRPort(); // 解析本地地址替代 if (ObjectUtils.isEmpty(remoteAddress) || remotePort == -1) { - remoteAddress = request.getViaHost(); - remotePort = request.getViaPort(); + remoteAddress = viaHeader.getHost(); + remotePort = viaHeader.getPort(); } }