From 76ef652e7cec2d8215fd45dc7c101032f8136481 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: Thu, 12 Sep 2024 17:49:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=86=E5=B1=8F=E7=9B=91?= =?UTF-8?q?=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CommonChannelController.java | 54 ++- .../service/IGbChannelPlayService.java | 6 + .../impl/GbChannelPlayServiceImpl.java | 9 +- .../service/impl/GbChannelServiceImpl.java | 1 - .../request/impl/InviteRequestProcessor.java | 341 ------------------ .../streamProxy/dao/StreamProxyMapper.java | 6 + .../impl/StreamProxyPlayServiceImpl.java | 2 +- .../service/impl/StreamProxyServiceImpl.java | 3 +- web_src/src/components/common/DeviceTree.vue | 163 ++------- web_src/src/components/common/GroupTree.vue | 23 +- web_src/src/components/common/RegionTree.vue | 18 +- web_src/src/components/group.vue | 2 +- web_src/src/components/live.vue | 122 ++++--- web_src/src/components/region.vue | 2 +- web_src/src/layout/UiHeader.vue | 2 +- web_src/static/css/iconfont.css | 22 +- web_src/static/css/iconfont.woff2 | Bin 55428 -> 55596 bytes 17 files changed, 222 insertions(+), 554 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java index b386d56e..398b107d 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/CommonChannelController.java @@ -1,17 +1,21 @@ package com.genersoft.iot.vmp.gb28181.controller; +import com.genersoft.iot.vmp.common.StreamInfo; +import com.genersoft.iot.vmp.conf.UserSetting; import com.genersoft.iot.vmp.conf.security.JwtUtils; -import com.genersoft.iot.vmp.gb28181.bean.CommonGBChannel; -import com.genersoft.iot.vmp.gb28181.bean.DeviceType; -import com.genersoft.iot.vmp.gb28181.bean.IndustryCodeType; -import com.genersoft.iot.vmp.gb28181.bean.NetworkIdentificationType; +import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToGroupByGbDeviceParam; import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToGroupParam; import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToRegionByGbDeviceParam; import com.genersoft.iot.vmp.gb28181.controller.bean.ChannelToRegionParam; +import com.genersoft.iot.vmp.gb28181.service.IGbChannelPlayService; import com.genersoft.iot.vmp.gb28181.service.IGbChannelService; import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.service.bean.ErrorCallback; +import com.genersoft.iot.vmp.service.bean.InviteErrorCode; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.vmanager.bean.StreamContent; +import com.genersoft.iot.vmp.vmanager.bean.WVPResult; import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -22,7 +26,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; +import javax.sip.message.Response; import java.util.List; @@ -41,6 +47,12 @@ public class CommonChannelController { @Autowired private IMediaServerService mediaServerService; + @Autowired + private IGbChannelPlayService channelPlayService; + + @Autowired + private UserSetting userSetting; + @Operation(summary = "查询通道信息", security = @SecurityRequirement(name = JwtUtils.HEADER)) @Parameter(name = "id", description = "通道的数据库自增Id", required = true) @@ -167,4 +179,38 @@ public class CommonChannelController { Assert.notEmpty(param.getDeviceIds(),"参数异常"); channelService.deleteChannelToGroupByGbDevice(param.getDeviceIds()); } + + @Operation(summary = "播放通道", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @GetMapping("/play") + public DeferredResult> deleteChannelToGroupByGbDevice(Integer channelId){ + Assert.notNull(channelId,"参数异常"); + CommonGBChannel channel = channelService.getOne(channelId); + Assert.notNull(channel, "通道不存在"); + + DeferredResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue()); + + ErrorCallback callback = (code, msg, data) -> { + if (code == InviteErrorCode.SUCCESS.getCode()) { + result.setResult(WVPResult.success(new StreamContent(data))); + }else { + result.setResult(WVPResult.fail(code, msg)); + } + }; + + if (channel.getGbDeviceDbId() != null) { + // 国标通道 + channelPlayService.playGbDeviceChannel(channel, callback); + } else if (channel.getStreamProxyId() != null) { + // 拉流代理 + channelPlayService.playProxy(channel, callback); + } else if (channel.getStreamPushId() != null) { + // 推流 + channelPlayService.playPush(channel, null, null, callback); + } else { + // 通道数据异常 + log.error("[点播通用通道] 通道数据异常,无法识别通道来源: {}({})", channel.getGbName(), channel.getGbDeviceId()); + throw new PlayException(Response.SERVER_INTERNAL_ERROR, "server internal error"); + } + return result; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java index da530aca..8abb0160 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/IGbChannelPlayService.java @@ -9,4 +9,10 @@ import com.genersoft.iot.vmp.service.bean.ErrorCallback; public interface IGbChannelPlayService { void start(CommonGBChannel channel, InviteInfo inviteInfo, Platform platform, ErrorCallback callback); + + void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback callback); + + void playProxy(CommonGBChannel channel, ErrorCallback callback); + + void playPush(CommonGBChannel channel, String platformDeviceId, String platformName, ErrorCallback callback); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java index df94e217..2d25f2d0 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelPlayServiceImpl.java @@ -101,7 +101,8 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { } } - private void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback callback){ + @Override + public void playGbDeviceChannel(CommonGBChannel channel, ErrorCallback callback){ // 国标通道 try { deviceChannelPlayService.play(channel, callback); @@ -113,7 +114,8 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { } } - private void playProxy(CommonGBChannel channel, ErrorCallback callback){ + @Override + public void playProxy(CommonGBChannel channel, ErrorCallback callback){ // 拉流代理通道 try { StreamInfo streamInfo = streamProxyPlayService.start(channel.getStreamProxyId()); @@ -127,7 +129,8 @@ public class GbChannelPlayServiceImpl implements IGbChannelPlayService { } } - private void playPush(CommonGBChannel channel, String platformDeviceId, String platformName, ErrorCallback callback){ + @Override + public void playPush(CommonGBChannel channel, String platformDeviceId, String platformName, ErrorCallback callback){ // 推流 try { streamPushPlayService.start(channel.getStreamPushId(), callback, platformDeviceId, platformName); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java index b89ed35c..ffbe6f64 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/GbChannelServiceImpl.java @@ -675,5 +675,4 @@ public class GbChannelServiceImpl implements IGbChannelService { } } } - } 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 a63f7fb0..9691d380 100755 --- 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 @@ -247,347 +247,6 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements log.error("[命令发送失败] invite 点播失败: {}", sendException.getMessage()); } } - -// // Invite Request消息实现,此消息一般为级联消息,上级给下级发送请求视频指令 -// try { -// -// -// -// -// -// -// -// // 查询请求是否来自上级平台\设备 -// Platform platform = platformService.queryPlatformByServerGBId(requesterId); -// -// if (platform == null) { -// inviteFromDeviceHandle(request, requesterId, channelId); -// -// } else { -// // 查询平台下是否有该通道 -// CommonGBChannel channel= channelService.queryOneWithPlatform(platform.getId(), channelId); -// MediaServer mediaServerItem = null; -// StreamPush streamPushItem = null; -// StreamProxy proxyByAppAndStream = null; -// if (channel == null) { -// log.info("[上级INVITE] 通道不存在,返回404: {}", channelId); -// try { -// // 通道不存在,发404,资源不存在 -// responseAck(request, Response.NOT_FOUND); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] invite 通道不存在: {}", e.getMessage()); -// } -// return; -// } -// // 通道存在,发100,TRYING -// try { -// responseAck(request, Response.TRYING); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] invite TRYING: {}", e.getMessage()); -// } -// -// -// -// Device device = null; -// // 通过 channel 和 gbStream 是否为null 值判断来源是直播流合适国标 -// if (channel != null) { -// device = storager.queryVideoDeviceByPlatformIdAndChannelId(requesterId, channelId); -// if (device == null) { -// log.warn("点播平台{}的通道{}时未找到设备信息", requesterId, channel); -// try { -// responseAck(request, Response.SERVER_INTERNAL_ERROR); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] invite 未找到设备信息: {}", e.getMessage()); -// } -// return; -// } -// mediaServerItem = playService.getNewMediaServerItem(device); -// if (mediaServerItem == null) { -// log.warn("未找到可用的zlm"); -// try { -// responseAck(request, Response.BUSY_HERE); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] invite BUSY_HERE: {}", e.getMessage()); -// } -// return; -// } -// -// String ssrc; -// if (userSetting.getUseCustomSsrcForParentInvite() || gb28181Sdp.getSsrc() == null) { -// // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 -// ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); -// }else { -// ssrc = gb28181Sdp.getSsrc(); -// } -// String streamTypeStr = null; -// if (mediaTransmissionTCP) { -// if (tcpActive) { -// streamTypeStr = "TCP-ACTIVE"; -// } else { -// streamTypeStr = "TCP-PASSIVE"; -// } -// } else { -// streamTypeStr = "UDP"; -// } -// -// SendRtpItem sendRtpItem = mediaServerService.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, -// device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp()); -// -// if (tcpActive != null) { -// sendRtpItem.setTcpActive(tcpActive); -// } -// if (sendRtpItem == null) { -// log.warn("服务器端口资源不足"); -// try { -// responseAck(request, Response.BUSY_HERE); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] invite 服务器端口资源不足: {}", e.getMessage()); -// } -// return; -// } -// sendRtpItem.setCallId(callIdHeader.getCallId()); -// sendRtpItem.setPlayType("Play".equalsIgnoreCase(sessionName) ? InviteStreamType.PLAY : InviteStreamType.PLAYBACK); -// -// Long finalStartTime = startTime; -// Long finalStopTime = stopTime; -// ErrorCallback hookEvent = (code, msg, data) -> { -// StreamInfo streamInfo = (StreamInfo)data; -// MediaServer mediaServerItemInUSe = mediaServerService.getOne(streamInfo.getMediaServerId()); -// log.info("[上级Invite]下级已经开始推流。 回复200OK(SDP), {}/{}", streamInfo.getApp(), streamInfo.getStream()); -// // * 0 等待设备推流上来 -// // * 1 下级已经推流,等待上级平台回复ack -// // * 2 推流中 -// sendRtpItem.setStatus(1); -// redisCatchStorage.updateSendRTPSever(sendRtpItem); -// String sdpIp = mediaServerItemInUSe.getSdpIp(); -// if (!ObjectUtils.isEmpty(platform.getSendStreamIp())) { -// sdpIp = platform.getSendStreamIp(); -// } -// StringBuffer content = new StringBuffer(200); -// content.append("v=0\r\n"); -// content.append("o=" + channelId + " 0 0 IN IP4 " + sdpIp + "\r\n"); -// content.append("s=" + sessionName + "\r\n"); -// content.append("c=IN IP4 " + sdpIp + "\r\n"); -// if ("Playback".equalsIgnoreCase(sessionName)) { -// content.append("t=" + finalStartTime + " " + finalStopTime + "\r\n"); -// } else { -// content.append("t=0 0\r\n"); -// } -// int localPort = sendRtpItem.getLocalPort(); -// if (localPort == 0) { -// // 非严格模式端口不统一, 增加兼容性,修改为一个不为0的端口 -// localPort = new Random().nextInt(65535) + 1; -// } -// if (sendRtpItem.isTcp()) { -// content.append("m=video " + localPort + " TCP/RTP/AVP 96\r\n"); -// if (!sendRtpItem.isTcpActive()) { -// content.append("a=setup:active\r\n"); -// } else { -// content.append("a=setup:passive\r\n"); -// } -// }else { -// content.append("m=video " + localPort + " RTP/AVP 96\r\n"); -// } -// content.append("a=sendonly\r\n"); -// content.append("a=rtpmap:96 PS/90000\r\n"); -// content.append("y=" + sendRtpItem.getSsrc() + "\r\n"); -// content.append("f=\r\n"); -// -// -// try { -// // 超时未收到Ack应该回复bye,当前等待时间为10秒 -// dynamicTask.startDelay(callIdHeader.getCallId(), () -> { -// log.info("Ack 等待超时"); -// mediaServerService.releaseSsrc(mediaServerItemInUSe.getId(), sendRtpItem.getSsrc()); -// // 回复bye -// try { -// cmderFroPlatform.streamByeCmd(platform, callIdHeader.getCallId()); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage()); -// } -// }, 60 * 1000); -// responseSdpAck(request, content.toString(), platform); -// // tcp主动模式,回复sdp后开启监听 -// if (sendRtpItem.isTcpActive()) { -// MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); -// try { -// mediaServerService.startSendRtpPassive(mediaServer, sendRtpItem, 5); -// redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, platform); -// }catch (ControllerException e) {} -// } -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] 国标级联 回复SdpAck", e); -// } -// }; -// ErrorCallback errorEvent = ((statusCode, msg, data) -> { -// log.info("[上级Invite] {}, 失败, 平台:{}, 通道:{}, code: {}, msg;{}", sessionName, username, channelId, statusCode, msg); -// // 未知错误。直接转发设备点播的错误 -// try { -// Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); -// sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); -// } catch (ParseException | SipException e) { -// log.error("未处理的异常 ", e); -// } -// }); -// sendRtpItem.setApp("rtp"); -// if ("Playback".equalsIgnoreCase(sessionName)) { -// sendRtpItem.setPlayType(InviteStreamType.PLAYBACK); -// String startTimeStr = DateUtil.urlFormatter.format(start); -// String endTimeStr = DateUtil.urlFormatter.format(end); -// String stream = device.getDeviceId() + "_" + channelId + "_" + startTimeStr + "_" + endTimeStr; -// int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0); -// SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, -// device.isSsrcCheck(), true, 0,false,!channel.isHasAudio(), false, tcpMode); -// sendRtpItem.setStream(stream); -// // 写入redis, 超时时回复 -// redisCatchStorage.updateSendRTPSever(sendRtpItem); -// playService.playBack(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), -// DateUtil.formatter.format(end), -// (code, msg, data) -> { -// if (code == InviteErrorCode.SUCCESS.getCode()) { -// hookEvent.run(code, msg, data); -// } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { -// log.info("[录像回放]超时, 用户:{}, 通道:{}", username, channelId); -// redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); -// errorEvent.run(code, msg, data); -// } else { -// errorEvent.run(code, msg, data); -// } -// }); -// } else if ("Download".equalsIgnoreCase(sessionName)) { -// // 获取指定的下载速度 -// Vector sdpMediaDescriptions = sdp.getMediaDescriptions(true); -// MediaDescription mediaDescription = null; -// String downloadSpeed = "1"; -// if (sdpMediaDescriptions.size() > 0) { -// mediaDescription = (MediaDescription) sdpMediaDescriptions.get(0); -// } -// if (mediaDescription != null) { -// downloadSpeed = mediaDescription.getAttribute("downloadspeed"); -// } -// -// sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD); -// int tcpMode = device.getStreamMode().equals("TCP-ACTIVE")? 2: (device.getStreamMode().equals("TCP-PASSIVE")? 1:0); -// SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, -// device.isSsrcCheck(), true, 0, false,!channel.isHasAudio(), false, tcpMode); -// sendRtpItem.setStream(ssrcInfo.getStream()); -// // 写入redis, 超时时回复 -// redisCatchStorage.updateSendRTPSever(sendRtpItem); -// playService.download(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start), -// DateUtil.formatter.format(end), Integer.parseInt(downloadSpeed), -// (code, msg, data) -> { -// if (code == InviteErrorCode.SUCCESS.getCode()) { -// hookEvent.run(code, msg, data); -// } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { -// log.info("[录像下载]超时, 用户:{}, 通道:{}", username, channelId); -// redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); -// errorEvent.run(code, msg, data); -// } else { -// errorEvent.run(code, msg, data); -// } -// }); -// } else { -// sendRtpItem.setPlayType(InviteStreamType.PLAY); -// String streamId = String.format("%s_%s", device.getDeviceId(), channelId); -// sendRtpItem.setStream(streamId); -// redisCatchStorage.updateSendRTPSever(sendRtpItem); -// SSRCInfo ssrcInfo = playService.play(mediaServerItem, device.getDeviceId(), channelId, ssrc, ((code, msg, data) -> { -// if (code == InviteErrorCode.SUCCESS.getCode()) { -// hookEvent.run(code, msg, data); -// } else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()) { -// log.info("[上级点播]超时, 用户:{}, 通道:{}", username, channelId); -// redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null); -// errorEvent.run(code, msg, data); -// } else { -// errorEvent.run(code, msg, data); -// } -// })); -// sendRtpItem.setSsrc(ssrcInfo.getSsrc()); -// redisCatchStorage.updateSendRTPSever(sendRtpItem); -// -// } -// } else if (gbStream != null) { -// SendRtpItem sendRtpItem = new SendRtpItem(); -// if (!userSetting.getUseCustomSsrcForParentInvite() && gb28181Sdp.getSsrc() != null) { -// sendRtpItem.setSsrc(gb28181Sdp.getSsrc()); -// } -// -// if (tcpActive != null) { -// sendRtpItem.setTcpActive(tcpActive); -// } -// sendRtpItem.setTcp(mediaTransmissionTCP); -// sendRtpItem.setRtcp(platform.isRtcp()); -// sendRtpItem.setPlatformName(platform.getName()); -// sendRtpItem.setPlatformId(platform.getServerGBId()); -// sendRtpItem.setMediaServerId(mediaServerItem.getId()); -// sendRtpItem.setChannelId(channelId); -// sendRtpItem.setIp(addressStr); -// sendRtpItem.setPort(port); -// sendRtpItem.setUsePs(true); -// sendRtpItem.setApp(gbStream.getApp()); -// sendRtpItem.setStream(gbStream.getStream()); -// sendRtpItem.setCallId(callIdHeader.getCallId()); -// sendRtpItem.setFromTag(request.getFromTag()); -// sendRtpItem.setOnlyAudio(false); -// sendRtpItem.setStatus(0); -// sendRtpItem.setSessionName(sessionName); -// // 清理可能存在的缓存避免用到旧的数据 -// List sendRtpItemList = redisCatchStorage.querySendRTPServer(platform.getServerGBId(), channelId, gbStream.getStream()); -// if (!sendRtpItemList.isEmpty()) { -// for (SendRtpItem rtpItem : sendRtpItemList) { -// redisCatchStorage.deleteSendRTPServer(rtpItem); -// } -// } -// if ("push".equals(gbStream.getStreamType())) { -// sendRtpItem.setPlayType(InviteStreamType.PUSH); -// if (streamPushItem != null) { -// // 从redis查询是否正在接收这个推流 -// MediaInfo mediaInfo = redisCatchStorage.getPushListItem(gbStream.getApp(), gbStream.getStream()); -// if (mediaInfo != null) { -// sendRtpItem.setServerId(mediaInfo.getServerId()); -// sendRtpItem.setMediaServerId(mediaInfo.getMediaServer().getId()); -// -// redisCatchStorage.updateSendRTPSever(sendRtpItem); -// // 开始推流 -// sendPushStream(sendRtpItem, mediaServerItem, platform, request); -// }else { -// if (!platform.isStartOfflinePush()) { -// // 平台设置中关闭了拉起离线的推流则直接回复 -// try { -// log.info("[上级点播] 失败,推流设备未推流,channel: {}, app: {}, stream: {}", sendRtpItem.getChannelId(), sendRtpItem.getApp(), sendRtpItem.getStream()); -// responseAck(request, Response.TEMPORARILY_UNAVAILABLE, "channel stream not pushing"); -// } catch (SipException | InvalidArgumentException | ParseException e) { -// log.error("[命令发送失败] invite 通道未推流: {}", e.getMessage()); -// } -// return; -// } -// notifyPushStreamOnline(sendRtpItem, mediaServerItem, platform, request); -// } -// } -// } else if ("proxy".equals(gbStream.getStreamType())) { -// if (null != proxyByAppAndStream) { -// sendRtpItem.setServerId(userSetting.getServerId()); -// if (sendRtpItem.getSsrc() == null) { -// // 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 -// String ssrc = "Play".equalsIgnoreCase(sessionName) ? ssrcFactory.getPlaySsrc(mediaServerItem.getId()) : ssrcFactory.getPlayBackSsrc(mediaServerItem.getId()); -// sendRtpItem.setSsrc(ssrc); -// } -// MediaInfo mediaInfo = redisCatchStorage.getProxyStream(gbStream.getApp(), gbStream.getStream()); -// if (mediaInfo != null) { -// sendProxyStream(sendRtpItem, mediaServerItem, platform, request); -// } else { -// //开启代理拉流 -// notifyProxyStreamOnline(sendRtpItem, mediaServerItem, platform, request); -// } -// } -// } -// } -// } -// } catch (SdpParseException e) { -// log.error("sdp解析错误", e); -// } catch (SdpException e) { -// log.error("未处理的异常 ", e); -// } } private InviteInfo decode(RequestEvent evt) throws SdpException { diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java index 7cf0a213..74fe9dbf 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/dao/StreamProxyMapper.java @@ -84,4 +84,10 @@ public interface StreamProxyMapper { @SelectProvider(type = StreamProxyProvider.class, method = "select") StreamProxy select(@Param("id") int id); + + @Update("UPDATE wvp_stream_proxy " + + "SET pulling=false, " + + "stream_key = null " + + "WHERE id=#{id}") + void removeStream(@Param("id")int id); } diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyPlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyPlayServiceImpl.java index 4a1104b6..170ed6fd 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyPlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyPlayServiceImpl.java @@ -91,7 +91,7 @@ public class StreamProxyPlayServiceImpl implements IStreamProxyPlayService { streamProxy.setMediaServerId(mediaServer.getId()); streamProxy.setStreamKey(null); streamProxy.setPulling(false); - streamProxyMapper.update(streamProxy); + streamProxyMapper.removeStream(streamProxy.getId()); } } diff --git a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java index eafd0fbf..4224e3a1 100755 --- a/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/streamProxy/service/impl/StreamProxyServiceImpl.java @@ -209,7 +209,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { if (streamProxyInDb == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "代理不存在"); } - if (streamProxyMapper.update(streamProxy) > 0 && !ObjectUtils.isEmpty(streamProxy.getGbDeviceId())) { + int updateResult = streamProxyMapper.update(streamProxy); + if (updateResult > 0 && !ObjectUtils.isEmpty(streamProxy.getGbDeviceId())) { if (streamProxy.getGbId() > 0) { gbChannelService.update(streamProxy.buildCommonGBChannel()); }else { diff --git a/web_src/src/components/common/DeviceTree.vue b/web_src/src/components/common/DeviceTree.vue index 6030dc8a..58ee921f 100755 --- a/web_src/src/components/common/DeviceTree.vue +++ b/web_src/src/components/common/DeviceTree.vue @@ -1,32 +1,24 @@