From 298fb053783fafcf4a0a0d5ea1aafcd906a324e8 Mon Sep 17 00:00:00 2001 From: lin <648540858@qq.com> Date: Thu, 13 Mar 2025 16:48:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BD=95=E5=83=8F=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E3=80=82=20=E6=94=AF=E6=8C=81=E5=85=AB=E5=80=8D?= =?UTF-8?q?=E9=80=9F=EF=BC=88=E8=AE=BE=E5=A4=87=E6=94=AF=E6=8C=81=E7=9A=84?= =?UTF-8?q?=E6=9C=80=E9=AB=98=E9=80=9F=E5=BA=A6=EF=BC=89=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/InviteInfo.java | 4 ++ .../vmp/gb28181/controller/DeviceQuery.java | 8 +++- .../gb28181/service/impl/PlayServiceImpl.java | 3 ++ .../cmd/MediaStatusNotifyMessageHandler.java | 37 ++++++++++--------- .../service/impl/MediaServerServiceImpl.java | 1 - .../vmp/service/impl/MediaServiceImpl.java | 6 +-- .../com/genersoft/iot/vmp/utils/JsonUtil.java | 3 ++ web_src/src/components/GBRecordDetail.vue | 31 +++++++++++++--- .../src/components/dialog/recordDownload.vue | 1 + 9 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java b/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java index 41b363e4..0c127968 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteInfo.java @@ -37,6 +37,10 @@ public class InviteInfo { private Boolean record; + private String startTime; + + private String endTime; + public static InviteInfo getInviteInfo(String deviceId, Integer channelId, String stream, SSRCInfo ssrcInfo, String mediaServerId, String receiveIp, Integer receivePort, String streamMode, diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java index 1e65c1c1..c18df8f5 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/controller/DeviceQuery.java @@ -15,7 +15,6 @@ import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.CatalogSubscribeTask; import com.genersoft.iot.vmp.gb28181.task.impl.MobilePositionSubscribeTask; import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; -import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.service.redisMsg.IRedisRpcService; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; @@ -210,6 +209,13 @@ public class DeviceQuery { public void updateChannelStreamIdentification(DeviceChannel channel){ deviceChannelService.updateChannelStreamIdentification(channel); } + @Operation(summary = "获取单个通道详情", security = @SecurityRequirement(name = JwtUtils.HEADER)) + @Parameter(name = "deviceId", description = "设备的国标编码", required = true) + @Parameter(name = "channelDeviceId", description = "通道的国标编码", required = true) + @GetMapping("/channel/one") + public DeviceChannel getChannel(String deviceId, String channelDeviceId){ + return deviceChannelService.getOne(deviceId, channelDeviceId); + } @Operation(summary = "修改数据流传输模式", security = @SecurityRequirement(name = JwtUtils.HEADER)) diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java index e443f68b..95e2e790 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/service/impl/PlayServiceImpl.java @@ -390,6 +390,7 @@ public class PlayServiceImpl implements IPlayService { rtpServerParam.setTcpMode(tcpMode); rtpServerParam.setOnlyAuto(false); rtpServerParam.setDisableAudio(!channel.isHasAudio()); + SSRCInfo ssrcInfo = receiveRtpServerService.openRTPServer(rtpServerParam, (code, msg, result) -> { if (code == InviteErrorCode.SUCCESS.getCode() && result != null && result.getHookData() != null) { @@ -1055,6 +1056,8 @@ public class PlayServiceImpl implements IPlayService { InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channel.getId(), ssrcInfo.getStream(), ssrcInfo, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.DOWNLOAD, InviteSessionStatus.ready, true); + inviteInfo.setStartTime(startTime); + inviteInfo.setEndTime(endTime); inviteStreamService.updateInviteInfo(inviteInfo); try { diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java index 6b368b72..41fa636a 100755 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java @@ -14,7 +14,6 @@ import com.genersoft.iot.vmp.media.event.hook.Hook; import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; import com.genersoft.iot.vmp.media.event.hook.HookType; import com.genersoft.iot.vmp.service.ISendRtpServerService; -import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import gov.nist.javax.sip.message.SIPRequest; import lombok.extern.slf4j.Slf4j; import org.dom4j.Element; @@ -101,23 +100,25 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i // 去除监听流注销自动停止下载的监听 Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId()); subscribe.removeSubscribe(hook); - // 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定 - SendRtpInfo sendRtpInfo = sendRtpServerService.queryByChannelId(ssrcTransaction.getChannelId(), ssrcTransaction.getPlatformId()); - if (sendRtpInfo != null) { - Platform parentPlatform = platformService.queryPlatformByServerGBId(sendRtpInfo.getTargetId()); - if (parentPlatform == null) { - log.warn("[级联消息发送]:发送MediaStatus发现上级平台{}不存在", sendRtpInfo.getTargetId()); - return; - } - CommonGBChannel channel = platformChannelService.queryChannelByPlatformIdAndChannelId(parentPlatform.getId(), sendRtpInfo.getChannelId()); - if (channel == null) { - log.warn("[级联消息发送]:发送MediaStatus发现通道{}不存在", sendRtpInfo.getChannelId()); - return; - } - try { - sipCommanderFroPlatform.sendMediaStatusNotify(parentPlatform, sendRtpInfo, channel); - } catch (SipException | InvalidArgumentException | ParseException e) { - log.error("[命令发送失败] 国标级联 录像播放完毕: {}", e.getMessage()); + if (ssrcTransaction.getPlatformId() != null) { + // 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题,需要将点播CallId进行上下级绑定 + SendRtpInfo sendRtpInfo = sendRtpServerService.queryByChannelId(ssrcTransaction.getChannelId(), ssrcTransaction.getPlatformId()); + if (sendRtpInfo != null) { + Platform parentPlatform = platformService.queryPlatformByServerGBId(sendRtpInfo.getTargetId()); + if (parentPlatform == null) { + log.warn("[级联消息发送]:发送MediaStatus发现上级平台{}不存在", sendRtpInfo.getTargetId()); + return; + } + CommonGBChannel channel = platformChannelService.queryChannelByPlatformIdAndChannelId(parentPlatform.getId(), sendRtpInfo.getChannelId()); + if (channel == null) { + log.warn("[级联消息发送]:发送MediaStatus发现通道{}不存在", sendRtpInfo.getChannelId()); + return; + } + try { + sipCommanderFroPlatform.sendMediaStatusNotify(parentPlatform, sendRtpInfo, channel); + } catch (SipException | InvalidArgumentException | ParseException e) { + log.error("[命令发送失败] 国标级联 录像播放完毕: {}", e.getMessage()); + } } } }else { diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index cf85ba48..0a089cf2 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -807,7 +807,6 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) { - System.out.println(callId); StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java index 99303ede..6f5d990d 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java @@ -173,9 +173,9 @@ public class MediaServiceImpl implements IMediaService { if (ssrcTransaction.getType() == InviteSessionType.DOWNLOAD) { // 获取录像的总时长,然后设置为这个视频的时长 InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, channelId, stream); - if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) { - String startTime = inviteInfoForDownload.getStreamInfo().getStartTime(); - String endTime = inviteInfoForDownload.getStreamInfo().getEndTime(); + if (inviteInfoForDownload != null) { + String startTime = inviteInfoForDownload.getStartTime(); + String endTime = inviteInfoForDownload.getEndTime(); long difference = DateUtil.getDifference(startTime, endTime) / 1000; result.setMp4_max_second((int) difference); result.setEnable_mp4(true); diff --git a/src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java index 46c71b4b..b44af109 100755 --- a/src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/JsonUtil.java @@ -33,6 +33,9 @@ public final class JsonUtil { } public static T redisHashJsonToObject(RedisTemplate redisTemplate, String key, String objKey, Class clazz) { +// if (key == null || objKey == null) { +// return null; +// } Object jsonObject = redisTemplate.opsForHash().get(key, objKey); if (Objects.isNull(jsonObject)) { return null; diff --git a/web_src/src/components/GBRecordDetail.vue b/web_src/src/components/GBRecordDetail.vue index 9cc853ae..dfb02fcd 100755 --- a/web_src/src/components/GBRecordDetail.vue +++ b/web_src/src/components/GBRecordDetail.vue @@ -65,11 +65,7 @@ 倍速 - 0.25倍速 - 0.5倍速 - 1倍速 - 2倍速 - 4倍速 + {{item}}倍速 @@ -115,6 +111,7 @@ return { deviceId: this.$route.params.deviceId, channelId: this.$route.params.channelId, + downloadSpeedArray: [0.25, 0.5, 1, 2, 4], recordsLoading: false, streamId: "", hasAudio: false, @@ -184,6 +181,7 @@ this.playerBoxStyle["height"] = this.winHeight + "px"; this.chooseDate = moment().format('YYYY-MM-DD') this.dateChange(); + this.getDownloadSpeedArray() window.addEventListener('beforeunload', this.stopPlayRecord) }, destroyed() { @@ -274,6 +272,27 @@ }); } }, + getDownloadSpeedArray(){ + this.$axios({ + method: 'get', + url: '/api/device/query/channel/one', + params: { + deviceId: this.deviceId, + channelDeviceId: this.channelId, + } + }).then((res)=> { + if (res.data.code === 0 && res.data.data.downloadSpeed) { + let speedArray = res.data.data.downloadSpeed.split('/'); + + speedArray.forEach(item => { + if (parseInt(item) > 4) { + this.downloadSpeedArray.push(parseInt(item)); + console.log(this.downloadSpeedArray); + } + }) + } + }) + }, gbPlay(){ console.log('前端控制:播放'); this.$axios({ @@ -317,7 +336,7 @@ this.$axios({ method: 'get', url: '/api/gb_record/download/start/' + this.deviceId + '/' + this.channelId + '?startTime=' + row.startTime + '&endTime=' + - row.endTime + '&downloadSpeed=4' + row.endTime + '&downloadSpeed='+ this.downloadSpeedArray[this.downloadSpeedArray.length - 1] }).then( (res)=> { if (res.data.code === 0) { let streamInfo = res.data.data; diff --git a/web_src/src/components/dialog/recordDownload.vue b/web_src/src/components/dialog/recordDownload.vue index fc4f7400..170807f0 100755 --- a/web_src/src/components/dialog/recordDownload.vue +++ b/web_src/src/components/dialog/recordDownload.vue @@ -53,6 +53,7 @@ export default { this.showDialog = true; this.getProgressRun = true; this.percentage = 0.0; + this.downloadFile = null; this.getProgressTimer() }, getProgressTimer: function (){