From 8489f48f922d43395b3500fa5f9b8130bc63c962 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Sat, 4 Dec 2021 17:27:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AC=AC=E4=B8=89=E6=96=B9?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=8F=82=E4=B8=8E=E7=9A=84=E6=8E=A8=E6=B5=81?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E8=BD=AC=E5=8F=91=E5=88=B0=E5=9B=BD=E6=A0=87?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql.sql | 1 + .../iot/vmp/common/VideoManagerConstants.java | 5 +- .../com/genersoft/iot/vmp/conf/UserSetup.java | 10 +++ .../iot/vmp/gb28181/bean/ParentPlatform.java | 13 +++ .../request/impl/InviteRequestProcessor.java | 4 +- .../vmp/media/zlm/ZLMMediaListManager.java | 51 ++++++++++- .../iot/vmp/service/IStreamPushService.java | 9 ++ .../iot/vmp/service/bean/ThirdPartyGB.java | 23 +++++ .../service/impl/StreamProxyServiceImpl.java | 54 ++++++------ .../service/impl/StreamPushServiceImpl.java | 18 ++++ .../iot/vmp/storager/IRedisCatchStorage.java | 8 ++ .../vmp/storager/IVideoManagerStorager.java | 2 +- .../iot/vmp/storager/dao/GbStreamMapper.java | 5 +- .../storager/dao/ParentPlatformMapper.java | 10 ++- .../storager/dao/PlatformGbStreamMapper.java | 3 + .../storager/impl/RedisCatchStorageImpl.java | 11 ++- .../impl/VideoManagerStoragerImpl.java | 39 ++++++++- .../streamPush/StreamPushController.java | 18 ++++ src/main/resources/all-application.yml | 2 + src/main/resources/wvp.sqlite | Bin 143360 -> 143360 bytes web_src/src/components/PushVideoList.vue | 34 +++++--- web_src/src/components/StreamProxyList.vue | 1 + .../src/components/dialog/platformEdit.vue | 80 ++++++++++++------ 23 files changed, 324 insertions(+), 77 deletions(-) create mode 100644 src/main/java/com/genersoft/iot/vmp/service/bean/ThirdPartyGB.java diff --git a/sql/mysql.sql b/sql/mysql.sql index 38cc8814..64fed126 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -173,6 +173,7 @@ create table parent_platform ptz int null, rtcp int null, status bit null, + shareAllLiveStream int null, primary key (id, serverGBId) ); diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index da58e107..3b47ff0e 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -55,5 +55,8 @@ public class VideoManagerConstants { public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_MEDIA_TRANSACTION_"; //************************** redis 消息********************************* - public static final String WVP_MSG_STREAM_CHANGE__PREFIX = "WVP_MSG_STREAM_CHANGE_"; + public static final String WVP_MSG_STREAM_CHANGE_PREFIX = "WVP_MSG_STREAM_CHANGE_"; + + //************************** 第三方 **************************************** + public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_"; } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/UserSetup.java b/src/main/java/com/genersoft/iot/vmp/conf/UserSetup.java index 13831b45..140295e8 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/UserSetup.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/UserSetup.java @@ -29,6 +29,8 @@ public class UserSetup { private String serverId = "000000"; + private String thirdPartyGBIdReg = "[\\s\\S]*"; + private List interfaceAuthenticationExcludes = new ArrayList<>(); public Boolean getSavePositionHistory() { @@ -114,4 +116,12 @@ public class UserSetup { public void setServerId(String serverId) { this.serverId = serverId; } + + public String getThirdPartyGBIdReg() { + return thirdPartyGBIdReg; + } + + public void setThirdPartyGBIdReg(String thirdPartyGBIdReg) { + this.thirdPartyGBIdReg = thirdPartyGBIdReg; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java index 96fcd36d..fabae8a1 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java @@ -104,6 +104,11 @@ public class ParentPlatform { */ private int channelCount; + /** + * 共享所有的直播流 + */ + private boolean shareAllLiveStream; + public Integer getId() { return id; } @@ -264,4 +269,12 @@ public class ParentPlatform { this.channelCount = channelCount; } + + public boolean isShareAllLiveStream() { + return shareAllLiveStream; + } + + public void setShareAllLiveStream(boolean shareAllLiveStream) { + this.shareAllLiveStream = shareAllLiveStream; + } } 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 1cb4af59..2635a5fd 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 @@ -31,6 +31,7 @@ import javax.sip.header.FromHeader; import javax.sip.message.Request; import javax.sip.message.Response; import java.text.ParseException; +import java.util.List; import java.util.Vector; /** @@ -105,7 +106,8 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements if (platform != null) { // 查询平台下是否有该通道 DeviceChannel channel = storager.queryChannelInParentPlatform(requesterId, channelId); - GbStream gbStream = storager.queryStreamInParentPlatform(requesterId, channelId); + List gbStreams = storager.queryStreamInParentPlatform(requesterId, channelId); + GbStream gbStream = gbStreams.size() > 0? gbStreams.get(0):null; MediaServerItem mediaServerItem = null; // 不是通道可能是直播流 if (channel != null && gbStream == null ) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java index 49fe098e..baf0b3c7 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -1,21 +1,28 @@ package com.genersoft.iot.vmp.media.zlm; import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.conf.UserSetup; +import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; 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.StreamPushItem; import com.genersoft.iot.vmp.service.IStreamPushService; +import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; +import com.genersoft.iot.vmp.storager.dao.StreamPushMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Component public class ZLMMediaListManager { @@ -40,9 +47,15 @@ public class ZLMMediaListManager { @Autowired private IStreamPushService streamPushService; + @Autowired + private StreamPushMapper streamPushMapper; + @Autowired private ZLMHttpHookSubscribe subscribe; + @Autowired + private UserSetup userSetup; + public void updateMediaList(MediaServerItem mediaServerItem) { storager.clearMediaList(); @@ -89,7 +102,43 @@ public class ZLMMediaListManager { } public void addMedia(MediaItem mediaItem) { - storager.updateMedia(streamPushService.transform(mediaItem)); + // 查找此直播流是否存在redis预设gbId + StreamPushItem transform = streamPushService.transform(mediaItem); + // 从streamId取出查询关键值 + Pattern pattern = Pattern.compile(userSetup.getThirdPartyGBIdReg()); + Matcher matcher = pattern.matcher(mediaItem.getStream());// 指定要匹配的字符串 + String queryKey = null; + if (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配 + queryKey = matcher.group(); + } + if (queryKey != null) { + ThirdPartyGB thirdPartyGB = redisCatchStorage.queryMemberNoGBId(queryKey); + if (thirdPartyGB != null && !StringUtils.isEmpty(thirdPartyGB.getNationalStandardNo())) { + transform.setGbId(thirdPartyGB.getNationalStandardNo()); + transform.setName(thirdPartyGB.getName()); + } + } + storager.updateMedia(transform); + if (!StringUtils.isEmpty(transform.getGbId())) { + // 如果这个国标ID已经给了其他推流且流已离线,则移除其他推流 + List gbStreams = gbStreamMapper.selectByGBId(transform.getGbId()); + if (gbStreams.size() > 0) { + for (GbStream gbStream : gbStreams) { + // 出现使用相同国标Id的视频流时,使用新流替换旧流, + gbStreamMapper.del(gbStream.getApp(), gbStream.getStream()); + platformGbStreamMapper.delByAppAndStream(gbStream.getApp(), gbStream.getStream()); + if (!gbStream.isStatus()) { + streamPushMapper.del(gbStream.getApp(), gbStream.getStream()); + } + } + } + if (gbStreamMapper.selectOne(transform.getApp(), transform.getStream()) != null) { + gbStreamMapper.update(transform); + }else { + gbStreamMapper.add(transform); + } + + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java index 2b45ce7d..7733254e 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java @@ -37,4 +37,13 @@ public interface IStreamPushService { StreamPushItem transform(MediaItem item); StreamPushItem getPush(String app, String streamId); + + /** + * 停止一路推流 + * @param app 应用名 + * @param streamId 流ID + * @return + */ + boolean stop(String app, String streamId); + } diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/ThirdPartyGB.java b/src/main/java/com/genersoft/iot/vmp/service/bean/ThirdPartyGB.java new file mode 100644 index 00000000..9d6b06a4 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/service/bean/ThirdPartyGB.java @@ -0,0 +1,23 @@ +package com.genersoft.iot.vmp.service.bean; + +public class ThirdPartyGB { + + private String name; + private String nationalStandardNo; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNationalStandardNo() { + return nationalStandardNo; + } + + public void setNationalStandardNo(String nationalStandardNo) { + this.nationalStandardNo = nationalStandardNo; + } +} 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 3ffc68e3..2961bc64 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 @@ -79,44 +79,38 @@ public class StreamProxyServiceImpl implements IStreamProxyService { StringBuffer result = new StringBuffer(); boolean streamLive = false; param.setMediaServerId(mediaInfo.getId()); + boolean saveResult; // 更新 if (videoManagerStorager.queryStreamProxy(param.getApp(), param.getStream()) != null) { - if (videoManagerStorager.updateStreamProxy(param)) { - result.append("保存成功"); - if (param.isEnable()){ - JSONObject jsonObject = addStreamProxyToZlm(param); - if (jsonObject == null) { - result.append(", 但是启用失败,请检查流地址是否可用"); - param.setEnable(false); - videoManagerStorager.updateStreamProxy(param); - }else { - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( - mediaInfo, param.getApp(), param.getStream(), null); - wvpResult.setData(streamInfo); - } - } - } + saveResult = videoManagerStorager.updateStreamProxy(param); }else { // 新增 - if (videoManagerStorager.addStreamProxy(param)){ - result.append("保存成功"); - streamLive = true; - if (param.isEnable()) { - JSONObject jsonObject = addStreamProxyToZlm(param); - if (jsonObject == null) { - streamLive = false; - result.append(", 但是启用失败,请检查流地址是否可用"); - param.setEnable(false); - videoManagerStorager.updateStreamProxy(param); - }else { + saveResult = videoManagerStorager.addStreamProxy(param); + } + if (saveResult) { + result.append("保存成功"); + if (param.isEnable()) { + JSONObject jsonObject = addStreamProxyToZlm(param); + if (jsonObject == null) { + streamLive = false; + result.append(", 但是启用失败,请检查流地址是否可用"); + param.setEnable(false); + videoManagerStorager.updateStreamProxy(param); + }else { + Integer code = jsonObject.getInteger("code"); + if (code == 0) { StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream( mediaInfo, param.getApp(), param.getStream(), null); wvpResult.setData(streamInfo); + }else { + result.append(", 但是启用失败,请检查流地址是否可用"); + param.setEnable(false); + videoManagerStorager.updateStreamProxy(param); } - } - }else { - result.append("保存失败"); - } + } + } + }else { + result.append("保存失败"); } if (param.getPlatformGbId() != null && streamLive) { List gbStreams = new ArrayList<>(); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java index 634f670d..41db0fe6 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java @@ -12,6 +12,7 @@ import com.genersoft.iot.vmp.service.IMediaServerService; import com.genersoft.iot.vmp.service.IStreamPushService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; +import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; import com.genersoft.iot.vmp.storager.dao.StreamPushMapper; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @@ -32,6 +33,9 @@ public class StreamPushServiceImpl implements IStreamPushService { @Autowired private StreamPushMapper streamPushMapper; + @Autowired + private PlatformGbStreamMapper platformGbStreamMapper; + @Autowired private ZLMRESTfulUtils zlmresTfulUtils; @@ -116,4 +120,18 @@ public class StreamPushServiceImpl implements IStreamPushService { return streamPushMapper.selectOne(app, streamId); } + + @Override + public boolean stop(String app, String streamId) { + StreamPushItem streamPushItem = streamPushMapper.selectOne(app, streamId); + int delStream = streamPushMapper.del(app, streamId); + gbStreamMapper.del(app, streamId); + platformGbStreamMapper.delByAppAndStream(app, streamId); + if (delStream > 0) { + MediaServerItem mediaServerItem = mediaServerService.getOne(streamPushItem.getMediaServerId()); + zlmresTfulUtils.closeStreams(mediaServerItem,app, streamId); + } + return true; + } + } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 3314fb20..04589414 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; import java.util.List; import java.util.Map; @@ -152,4 +153,11 @@ public interface IRedisCatchStorage { boolean startDownload(StreamInfo streamInfo); StreamInfo queryDownloadByStreamId(String streamId); + + /** + * 查找第三方系统留下的国标预设值 + * @param queryKey + * @return + */ + ThirdPartyGB queryMemberNoGBId(String queryKey); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java index 570718b3..39dc5ad0 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java @@ -327,7 +327,7 @@ public interface IVideoManagerStorager { * @param channelId * @return */ - GbStream queryStreamInParentPlatform(String platformId, String channelId); + List queryStreamInParentPlatform(String platformId, String channelId); /** * 获取平台关联的直播流 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 ebf4239a..84c04a16 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 @@ -40,10 +40,13 @@ public interface GbStreamMapper { @Select("SELECT * FROM gb_stream WHERE app=#{app} AND stream=#{stream}") StreamProxyItem selectOne(String app, String stream); + @Select("SELECT * FROM gb_stream WHERE gbId=#{gbId}") + List selectByGBId(String gbId); + @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " + "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " + "WHERE gs.gbId = '${gbId}' AND pgs.platformId = '${platformId}'") - GbStream queryStreamInPlatform(String platformId, String gbId); + List queryStreamInPlatform(String platformId, String gbId); @Select("SELECT gs.*, pgs.platformId FROM gb_stream gs " + "LEFT JOIN platform_gb_stream pgs ON gs.app = pgs.app AND gs.stream = pgs.stream " + diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java index bb81171b..c92711ae 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java @@ -15,10 +15,10 @@ public interface ParentPlatformMapper { @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + - " status) " + + " status, shareAllLiveStream) " + " VALUES (${enable}, '${name}', '${serverGBId}', '${serverGBDomain}', '${serverIP}', ${serverPort}, '${deviceGBId}', '${deviceIp}', " + " '${devicePort}', '${username}', '${password}', '${expires}', '${keepTimeout}', '${transport}', '${characterSet}', ${ptz}, ${rtcp}, " + - " ${status})") + " ${status}, ${shareAllLiveStream})") int addParentPlatform(ParentPlatform parentPlatform); @Update("UPDATE parent_platform " + @@ -39,7 +39,8 @@ public interface ParentPlatformMapper { "characterSet=#{characterSet}, " + "ptz=#{ptz}, " + "rtcp=#{rtcp}, " + - "status=#{status} " + + "status=#{status}, " + + "shareAllLiveStream=#{shareAllLiveStream} " + "WHERE id=#{id}") int updateParentPlatform(ParentPlatform parentPlatform); @@ -70,4 +71,7 @@ public interface ParentPlatformMapper { @Update("UPDATE parent_platform SET status=#{online} WHERE serverGBId=#{platformGbID}" ) int updateParentPlatformStatus(String platformGbID, boolean online); + + @Select("SELECT * FROM parent_platform WHERE shareAllLiveStream=true") + List selectAllAhareAllLiveStream(); } 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 6243f32a..a51eda2d 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 @@ -24,4 +24,7 @@ public interface PlatformGbStreamMapper { @Select("SELECT * FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream}") List selectByAppAndStream(String app, String stream); + + @Select("SELECT * FROM platform_gb_stream WHERE app=#{app} AND stream=#{stream} AND platformId=#{serverGBId}") + StreamProxyItem selectOne(String app, String stream, String serverGBId); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index c008d1e5..984b994b 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; +import com.genersoft.iot.vmp.service.bean.ThirdPartyGB; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.utils.redis.RedisUtil; @@ -13,6 +14,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; import java.util.*; @@ -324,7 +326,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { @Override public void sendStreamChangeMsg(String type, JSONObject jsonObject) { - String key = VideoManagerConstants.WVP_MSG_STREAM_CHANGE__PREFIX + type; + String key = VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + type; logger.debug("[redis 流变化事件] {}: {}", key, jsonObject.toString()); redis.convertAndSend(key, jsonObject); } @@ -350,4 +352,11 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage { if (playLeys == null || playLeys.size() == 0) return null; return (StreamInfo)redis.get(playLeys.get(0).toString()); } + + @Override + public ThirdPartyGB queryMemberNoGBId(String queryKey) { + String key = VideoManagerConstants.WVP_STREAM_GB_ID_PREFIX + queryKey; + JSONObject jsonObject = (JSONObject)redis.get(key); + return JSONObject.toJavaObject(jsonObject, ThirdPartyGB.class); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java index 9ad44d40..916f8a57 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java @@ -5,6 +5,7 @@ import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 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.StreamPushItem; +import com.genersoft.iot.vmp.service.IGbStreamService; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; import com.genersoft.iot.vmp.storager.dao.*; @@ -19,6 +20,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -69,6 +71,16 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @Autowired private GbStreamMapper gbStreamMapper; +; + + @Autowired + private PlatformGbStreamMapper platformGbStreamMapper; + + @Autowired + private IGbStreamService gbStreamService; + + @Autowired + private ParentPlatformMapper parentPlatformMapper; @Autowired private VideoStreamSessionManager streamSession; @@ -356,6 +368,15 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { // 更新缓存 parentPlatformCatch.setParentPlatform(parentPlatform); redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch); + // 共享所有视频流,需要将现有视频流添加到此平台 + List gbStreams = gbStreamMapper.selectAll(); + if (gbStreams.size() > 0) { + if (parentPlatform.isShareAllLiveStream()) { + gbStreamService.addPlatformInfo(gbStreams, parentPlatform.getServerGBId()); + }else { + gbStreamService.delPlatformInfo(gbStreams); + } + } return result > 0; } @@ -561,7 +582,7 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { * @return */ @Override - public GbStream queryStreamInParentPlatform(String platformId, String gbId) { + public List queryStreamInParentPlatform(String platformId, String gbId) { return gbStreamMapper.queryStreamInPlatform(platformId, gbId); } @@ -602,6 +623,22 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { streamPushMapper.del(streamPushItem.getApp(), streamPushItem.getStream()); streamPushMapper.add(streamPushItem); gbStreamMapper.setStatus(streamPushItem.getApp(), streamPushItem.getStream(), true); + if(!StringUtils.isEmpty(streamPushItem.getGbId() )){ + // 查找开启了全部直播流共享的上级平台 + List parentPlatforms = parentPlatformMapper.selectAllAhareAllLiveStream(); + if (parentPlatforms.size() > 0) { + for (ParentPlatform parentPlatform : parentPlatforms) { + streamPushItem.setPlatformId(parentPlatform.getServerGBId()); + String stream = streamPushItem.getStream(); + StreamProxyItem streamProxyItems = platformGbStreamMapper.selectOne(streamPushItem.getApp(), stream, parentPlatform.getServerGBId()); + if (streamProxyItems == null) { + platformGbStreamMapper.add(streamPushItem); + } + + } + } + } + } @Override 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 c266ff6d..5fcb6bd5 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 @@ -3,6 +3,7 @@ package com.genersoft.iot.vmp.vmanager.streamPush; import com.genersoft.iot.vmp.gb28181.bean.GbStream; import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; import com.genersoft.iot.vmp.service.IStreamPushService; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -71,4 +72,21 @@ public class StreamPushController { return "fail"; } } + + + @ApiOperation("中止一个推流") + @ApiImplicitParams({ + @ApiImplicitParam(name = "app", value = "应用名", required = true, dataTypeClass = String.class), + @ApiImplicitParam(name = "streamId", value = "流ID", required = true, dataTypeClass = String.class), + }) + @PostMapping(value = "/stop") + @ResponseBody + public Object removeFormGB(@RequestParam(required = true)String app, @RequestParam(required = true)String streamId){ + if (streamPushService.stop(app, streamId)){ + return "success"; + }else { + return "fail"; + } + } + } diff --git a/src/main/resources/all-application.yml b/src/main/resources/all-application.yml index 752008b2..c00ee2a1 100644 --- a/src/main/resources/all-application.yml +++ b/src/main/resources/all-application.yml @@ -160,6 +160,8 @@ user-settings: record-push-live: true # 是否将日志存储进数据库 logInDatebase: true + # 第三方匹配,用于从stream钟获取有效信息 + thirdPartyGBIdReg: [\s\S]* # 在线文档: swagger-ui(生产环境建议关闭) swagger-ui: diff --git a/src/main/resources/wvp.sqlite b/src/main/resources/wvp.sqlite index f969514a31bb26b222e37d31fa254e41e3912b5b..a1df1735628ecf8727738da22e638475b502962b 100644 GIT binary patch delta 2273 zcmb7FUu;uV7(b`$+Iu^0Pe+-hK;7N2B5p1BPw(Ar<8a+p$8@01i3>h-T~@cr#>V~# zn2@rd2?ohLOs!EvChChu6nLmYBGHhj5sA8B;-8S25GHR%4ZQf^cW>98ZtMZi>FLe+ z&iCi{{qFajduX0JG|#=VZngbigwRGaey@Z;LoS~-XawN0S=G{A#%^z zN>6}fe$#@!VBG5^YS6YtwW%udb819VBx@`_BuQ)C7TU41Q#15PsJ%5cFqtY9M8c9J z!?H$LtyjQ4BugPhd9w8}_`z0@L$VT*BBHFv)JRO0ndDonv zOo<)D3Z-GeSy5KSkBtna!Iz)LtE!wl2qwqVV+A7J``r7$X4sv_^`wuWH_AVB=v&d>dGc>Q0F?}+n zB(r4kn2aedVR{8p7ezq82U^Y2`~=R*Pq6aKFz1DUy4Kd5Y#G>-lyvR?=E%I=A=JB| zwidA#U;X=J?rf#!ZPNWTX8sE3B$>%r4CopZ;@L?-Ti2M3X`k#7bK)#sAaqtN$6(6m zDrfOO7LV0dJ+(4|Re#8S44=Q6d8c z+5S`s61h-HtbtUseO6Ra)QF}x7^)=c843Eb4dA`TS7|lDQXD+uhX(hQ)T>eq!o0F@ zy6(MLA}{JPjb(r!1xeauRx4!75Ltklmvrs|`31=OfrQo+Ndd%u7L6e*EA%6I6-ueZ~j4tInUC(~b*{=gaHtH|<~GIdi%$ zxh_$9-t|H^ar)}&@R9!P13rAs_2TY;(-#clqyCxG_CPMW9e-uZ)^5Ph=9;|t?=rrq zo&)uWt)^ZaA4rX*<3mFogU_X(m>5f^hQ;S}zrJ$uTJecRW!bSC0m z39&2Q+>sD#`+Jk)7T#L%J{Mn`8Xc|WyAs`9^{`nyDDL}v+xyt*p44zUd;B51Wn*5i z>%eH5osLhWCML&g`9&78m$zYGb|!)S9y3IJ!S`m@=93=rjA-|`tQ-7Ga+q{LDshr& z3=zKC&cW9O%14SCk|8BE!)yzvs4wpu z8Io;mV!U8iH=MUq4C6p&qVM6vPOwH>3+7Er!meb0dAWV@GFl+l$&Zl5N96H!xCB4= zH(*6dWsp$g2v~ delta 1291 zcma)5U2NM_6!vkP#BtN!q-z_JZp;vhN@;?BlBTJ&tx1R`*tA7m5YvR@I*D1cIgRHy z)hZrZ#-9X8EK4;%zyq76y-ZA7qcvzk5S|dyBtY6;kbuHNAK(RP2quIC*9k*ul?Tqf zS3dgA&pqe(eyf}G>Lz_YFi36@1QEn%H$Egm*d}U|f&-)BL+5W6-bWC)ngRC0*VF)o z?h)vF^ar|!w$Nt{FZ&Tnpe~xuNwN9bz;CaOQ7rSFWv9DuDH%P1;>5+FZL_cUFtpCtoudx z)8)S;ai{I4{tH+@QrV54BnIsIj1TWLs#UIr0M0e%iX#^HJ46g(`+`8 zJe+2`EzCH>Vlg2BL-mZEGGjjApRejFn@u0jPPUB|JuhuX3KgS`Bo7}=c6^LtNhwzi zsZ?Q~JCaQwOwV<2b0q=8N$U#T&?IA7Q@Ro>i&oLng1RH+d z4Lem=(BQ=p7&qA@JVCV^SWUrb^XXx@Z)}TGru|l959U!oC83iS3#>KM%Z(K zfYTQY!fUT|5A58&4*Gh+yp)7d|7g#7RVxeiyUr&?qio3PoFW$#JyotQ8eJWg_2S9m zV%BPN`xqWe!O*x>XdeF|Lpf&1C2hNltQMD)V@kffSg4<%Cw8=Eem(@J>gE1@&EI#! z$D{+lzt91{c_{^tnBjwf% zj=z4B+SB~g3tx~M8KAiaJ#X{We>^bKVCR2877c3|rycMeqYbb28`@}r%L9in;hse+ zw}Mzm8ZVM`y#REO4vAtnSG#E2TlKXjniCJ6ni+qI6QlW<_;M_i%T47%k?HApNRIK* zP$915gaVF^=JS7JwsPF0$VEBsOm10>%i7dgZE1Pov|f<~%-#?e3kflnkIY2*8A0d) XZEV7?$b*Bo#jdv~&n=4l>zRK5k1 播放 - 停止 + 移除 加入国标 移出国标 @@ -151,7 +151,21 @@ }); }, stopPuhsh: function(row){ - console.log(row) + var that = this; + that.$axios({ + method:"post", + url:"/api/push/stop", + params: { + app: row.app, + streamId: row.stream + } + }).then((res)=>{ + if (res.data == "success") { + that.initData() + } + }).catch(function (error) { + console.log(error); + }); }, addToGB: function(row){ this.$refs.addStreamTOGB.openDialog({app: row.app, stream: row.stream, mediaServerId: row.mediaServerId}, this.initData); @@ -159,16 +173,16 @@ removeFromGB: function(row){ var that = this; that.$axios({ - method:"delete", - url:"/api/push/remove_form_gb", - data:row - }).then((res)=>{ - if (res.data == "success") { + method:"delete", + url:"/api/push/remove_form_gb", + data:row + }).then((res)=>{ + if (res.data == "success") { that.initData() } - }).catch(function (error) { - console.log(error); - }); + }).catch(function (error) { + console.log(error); + }); }, dateFormat: function(/** timestamp=0 **/) { var ts = arguments[0] || 0; diff --git a/web_src/src/components/StreamProxyList.vue b/web_src/src/components/StreamProxyList.vue index 27dab67c..64e994a8 100644 --- a/web_src/src/components/StreamProxyList.vue +++ b/web_src/src/components/StreamProxyList.vue @@ -50,6 +50,7 @@ +