From 764d04b497356ba6bcbb75fd42b51eca750f7223 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期三, 29 五月 2024 15:02:51 +0800 Subject: [PATCH] 调整上级观看消息的发送 --- src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 408 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 204 insertions(+), 204 deletions(-) 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 65cf693..43b4d66 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -1,6 +1,5 @@ package com.genersoft.iot.vmp.service.impl; -import com.alibaba.fastjson2.JSONObject; import com.baomidou.dynamic.datasource.annotation.DS; import com.genersoft.iot.vmp.common.*; import com.genersoft.iot.vmp.conf.DynamicTask; @@ -17,20 +16,18 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.utils.SipUtils; import com.genersoft.iot.vmp.media.bean.MediaInfo; -import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; -import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.bean.RecordInfo; +import com.genersoft.iot.vmp.media.event.hook.Hook; +import com.genersoft.iot.vmp.media.event.hook.HookType; +import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.event.media.MediaNotFoundEvent; import com.genersoft.iot.vmp.media.service.IMediaServerService; import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; -import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; -import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; -import com.genersoft.iot.vmp.media.zlm.dto.*; -import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; -import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType; +import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; +import com.genersoft.iot.vmp.media.bean.MediaServer; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.*; -import com.genersoft.iot.vmp.service.redisMsg.RedisGbPlayMsgListener; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.utils.CloudRecordUtils; @@ -85,19 +82,13 @@ private IRedisCatchStorage redisCatchStorage; @Autowired - private ZLMServerFactory zlmServerFactory; - - @Autowired private IInviteStreamService inviteStreamService; @Autowired - private ZlmHttpHookSubscribe subscribe; + private HookSubscribe subscribe; @Autowired private SendRtpPortManager sendRtpPortManager; - - @Autowired - private IMediaService mediaService; @Autowired private IMediaServerService mediaServerService; @@ -116,9 +107,6 @@ @Autowired private ISIPCommanderForPlatform commanderForPlatform; - - @Autowired - private RedisGbPlayMsgListener redisGbPlayMsgListener; @Autowired private SSRCFactory ssrcFactory; @@ -172,6 +160,33 @@ @Async("taskExecutor") @EventListener public void onApplicationEvent(MediaDepartureEvent event) { + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); + if (!sendRtpItems.isEmpty()) { + for (SendRtpItem sendRtpItem : sendRtpItems) { + if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) { + String platformId = sendRtpItem.getPlatformId(); + Device device = deviceService.getDevice(platformId); + try { + if (device != null) { + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), event.getStream(), sendRtpItem.getCallId()); + if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) + || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + if (audioBroadcastCatch != null) { + // 鏉ヨ嚜涓婄骇骞冲彴鐨勫仠姝㈠璁� + logger.info("[鍋滄瀵硅] 鏉ヨ嚜涓婄骇锛屽钩鍙帮細{}, 閫氶亾锛歿}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + } + } + } + } catch (SipException | InvalidArgumentException | ParseException | + SsrcTransactionNotFoundException e) { + logger.error("[鍛戒护鍙戦�佸け璐 鍙戦�丅YE: {}", e.getMessage()); + } + } + } + } + if ("broadcast".equals(event.getApp()) || "talk".equals(event.getApp())) { if (event.getStream().indexOf("_") > 0) { String[] streamArray = event.getStream().split("_"); @@ -188,9 +203,55 @@ }else if ("talk".equals(event.getApp())) { stopTalk(device, channelId, false); } - } } + } + } + + /** + * 娴佹湭鎵惧埌鐨勫鐞� + */ + @Async("taskExecutor") + @EventListener + public void onApplicationEvent(MediaNotFoundEvent event) { + if (!"rtp".equals(event.getApp())) { + return; + } + String[] s = event.getStream().split("_"); + if ((s.length != 2 && s.length != 4)) { + return; + } + String deviceId = s[0]; + String channelId = s[1]; + Device device = redisCatchStorage.getDevice(deviceId); + if (device == null || !device.isOnLine()) { + return; + } + DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); + if (deviceChannel == null) { + return; + } + if (s.length == 2) { + logger.info("[ZLM HOOK] 棰勮娴佹湭鎵惧埌, 鍙戣捣鑷姩鐐规挱锛歿}->{}->{}/{}", event.getMediaServer().getId(), event.getSchema(), event.getApp(), event.getStream()); + play(event.getMediaServer(), deviceId, channelId, null, null); + } else if (s.length == 4) { + // 姝ゆ椂涓哄綍鍍忓洖鏀撅紝 褰曞儚鍥炴斁鏍煎紡涓�> 璁惧ID_閫氶亾ID_寮�濮嬫椂闂確缁撴潫鏃堕棿 + String startTimeStr = s[2]; + String endTimeStr = s[3]; + if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) { + return; + } + String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr); + String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr); + logger.info("[ZLM HOOK] 鍥炴斁娴佹湭鎵惧埌, 鍙戣捣鑷姩鐐规挱锛歿}->{}->{}/{}-{}-{}", + event.getMediaServer().getId(), event.getSchema(), + event.getApp(), event.getStream(), + startTime, endTime + ); + + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(event.getMediaServer(), event.getStream(), null, + device.isSsrcCheck(), true, 0, false, !deviceChannel.getHasAudio(), false, device.getStreamModeForParam()); + playBack(event.getMediaServer(), ssrcInfo, deviceId, channelId, startTime, endTime, null); } } @@ -201,7 +262,6 @@ logger.warn("[鐐规挱] 鏈壘鍒板彲鐢ㄧ殑zlm deviceId: {},channelId:{}", deviceId, channelId); throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒板彲鐢ㄧ殑zlm"); } - Device device = redisCatchStorage.getDevice(deviceId); if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && !mediaServerItem.isRtpEnable()) { logger.warn("[鐐规挱] 鍗曠鍙f敹娴佹椂涓嶆敮鎸乀CP涓诲姩鏂瑰紡鏀舵祦 deviceId: {},channelId:{}", deviceId, channelId); @@ -215,6 +275,8 @@ InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId); if (inviteInfo != null ) { if (inviteInfo.getStreamInfo() == null) { + // 閲婃斁鐢熸垚鐨剆src锛屼娇鐢ㄤ笂涓�娆$敵璇风殑 + ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc); // 鐐规挱鍙戣捣浜嗕絾鏄皻鏈垚鍔�, 浠呮敞鍐屽洖璋冪瓑寰呯粨鏋滃嵆鍙� inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback); logger.info("[鐐规挱寮�濮媇 宸茬粡璇锋眰涓紝绛夊緟缁撴灉锛� deviceId: {}, channelId: {}", device.getDeviceId(), channelId); @@ -232,8 +294,7 @@ } String mediaServerId = streamInfo.getMediaServerId(); MediaServer mediaInfo = mediaServerService.getOne(mediaServerId); - - Boolean ready = zlmServerFactory.isStreamReady(mediaInfo, "rtp", streamId); + Boolean ready = mediaServerService.isStreamReady(mediaInfo, "rtp", streamId); if (ready != null && ready) { callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, @@ -251,7 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null, @@ -265,7 +326,7 @@ } private void talk(MediaServer mediaServerItem, Device device, String channelId, String stream, - ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, + HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, Runnable timeoutCallback, AudioBroadcastEvent audioEvent) { String playSsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); @@ -321,38 +382,25 @@ } }, userSetting.getPlayTimeout()); - Map<String, Object> param = new HashMap<>(12); - param.put("vhost","__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - param.put("src_port", sendRtpItem.getLocalPort()); - param.put("pt", sendRtpItem.getPt()); - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); - param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1"); - param.put("recv_stream_id", sendRtpItem.getReceiveStream()); - param.put("close_delay_ms", userSetting.getPlayTimeout() * 1000); - - zlmServerFactory.startSendRtpPassive(mediaServerItem, param, jsonObject -> { - if (jsonObject == null || jsonObject.getInteger("code") != 0 ) { - mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); - logger.info("[璇煶瀵硅]澶辫触 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); - audioEvent.call("澶辫触, " + jsonObject.getString("msg")); - // 鏌ョ湅鏄惁宸茬粡寤虹珛浜嗛�氶亾锛屽瓨鍦ㄥ垯鍙戦�乥ye - stopTalk(device, channelId); - } - }); + try { + mediaServerService.startSendRtpPassive(mediaServerItem, sendRtpItem, userSetting.getPlayTimeout() * 1000); + }catch (ControllerException e) { + mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc()); + logger.info("[璇煶瀵硅]澶辫触 deviceId: {}, channelId: {}", device.getDeviceId(), channelId); + audioEvent.call("澶辫触, " + e.getMessage()); + // 鏌ョ湅鏄惁宸茬粡寤虹珛浜嗛�氶亾锛屽瓨鍦ㄥ垯鍙戦�乥ye + stopTalk(device, channelId); + } // 鏌ョ湅璁惧鏄惁宸茬粡鍦ㄦ帹娴� try { - cmder.talkStreamCmd(mediaServerItem, sendRtpItem, device, channelId, callId, (mediaServerItemInuse, hookParam) -> { - logger.info("[璇煶瀵硅] 娴佸凡鐢熸垚锛� 寮�濮嬫帹娴侊細 " + hookParam); + cmder.talkStreamCmd(mediaServerItem, sendRtpItem, device, channelId, callId, (hookData) -> { + logger.info("[璇煶瀵硅] 娴佸凡鐢熸垚锛� 寮�濮嬫帹娴侊細 " + hookData); dynamicTask.stop(timeOutTaskKey); // TODO 鏆備笉鍋氬鐞� - }, (mediaServerItemInuse, hookParam) -> { - logger.info("[璇煶瀵硅] 璁惧寮�濮嬫帹娴侊細 " + hookParam); + }, (hookData) -> { + logger.info("[璇煶瀵硅] 璁惧寮�濮嬫帹娴侊細 " + hookData); dynamicTask.stop(timeOutTaskKey); }, (event) -> { @@ -462,8 +510,7 @@ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); // 鍙栨秷璁㈤槄娑堟伅鐩戝惉 - HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); - subscribe.removeSubscribe(hookSubscribe); + subscribe.removeSubscribe(Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId())); } }else { logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {},鐮佹祦锛歿}锛岀鍙o細{}, SSRC: {}", @@ -478,11 +525,11 @@ }, userSetting.getPlayTimeout()); try { - cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channel, (mediaServerItemInuse, hookParam ) -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + hookParam); + cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channel, (hookData ) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + hookData); dynamicTask.stop(timeOutTaskKey); // hook鍝嶅簲 - StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, hookParam, device.getDeviceId(), channel.getChannelId()); + StreamInfo streamInfo = onPublishHandlerForPlay(hookData.getMediaServer(), hookData.getMediaInfo(), device.getDeviceId(), channel.getChannelId()); if (streamInfo == null){ callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null); @@ -498,7 +545,7 @@ streamInfo); logger.info("[鐐规挱鎴愬姛] deviceId: {}, channelId:{}, 鐮佹祦绫诲瀷锛歿}", device.getDeviceId(), channel.getChannelId(), channel.getStreamIdentification()); - snapOnPlay(mediaServerItemInuse, device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); + snapOnPlay(hookData.getMediaServer(), device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); }, (eventResult) -> { // 澶勭悊鏀跺埌200ok鍚庣殑TCP涓诲姩杩炴帴浠ュ強SSRC涓嶄竴鑷寸殑闂 InviteOKHandler(eventResult, ssrcInfo, mediaServerItem, device, channel.getChannelId(), @@ -512,8 +559,7 @@ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); - callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(), - String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg), null); + callback.run(event.statusCode, event.msg, null); inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null, InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(), String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg), null); @@ -624,11 +670,10 @@ mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName); } - public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, HookParam hookParam, String deviceId, String channelId) { + public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId) { StreamInfo streamInfo = null; Device device = redisCatchStorage.getDevice(deviceId); - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam; - streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); + streamInfo = onPublishHandler(mediaServerItem, mediaInfo, deviceId, channelId); if (streamInfo != null) { DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); if (deviceChannel != null) { @@ -646,9 +691,8 @@ } - private StreamInfo onPublishHandlerForPlayback(MediaServer mediaServerItem, HookParam param, String deviceId, String channelId, String startTime, String endTime) { - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) param; - StreamInfo streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId); + private StreamInfo onPublishHandlerForPlayback(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId, String startTime, String endTime) { + StreamInfo streamInfo = onPublishHandler(mediaServerItem, mediaInfo, deviceId, channelId); if (streamInfo != null) { streamInfo.setStartTime(startTime); streamInfo.setEndTime(endTime); @@ -657,7 +701,7 @@ deviceChannel.setStreamId(streamInfo.getStream()); storager.startPlay(deviceId, channelId, streamInfo.getStream()); } - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, ((OnStreamChangedHookParam) param).getStream()); + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, mediaInfo.getStream()); if (inviteInfo != null) { inviteInfo.setStatus(InviteSessionStatus.ok); @@ -695,6 +739,12 @@ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒拌澶囷細" + deviceId); } + DeviceChannel channel = channelService.getOne(deviceId, channelId); + if (channel == null) { + logger.warn("[褰曞儚鍥炴斁] 鏈壘鍒伴�氶亾 deviceId: {},channelId:{}", deviceId, channelId); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒伴�氶亾锛�" + channelId); + } + MediaServer newMediaServerItem = getNewMediaServerItem(device); if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && ! newMediaServerItem.isRtpEnable()) { logger.warn("[褰曞儚鍥炴斁] 鍗曠鍙f敹娴佹椂涓嶆敮鎸乀CP涓诲姩鏂瑰紡鏀舵祦 deviceId: {},channelId:{}", deviceId, channelId); @@ -707,7 +757,7 @@ .replace(":", "") .replace(" ", ""); String stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr; - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback); } @@ -763,10 +813,10 @@ inviteStreamService.removeInviteInfo(inviteInfo); }; - ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { - logger.info("鏀跺埌鍥炴斁璁㈤槄娑堟伅锛� " + hookParam); + HookSubscribe.Event hookEvent = (hookData) -> { + logger.info("鏀跺埌鍥炴斁璁㈤槄娑堟伅锛� " + hookData); dynamicTask.stop(playBackTimeOutTaskKey); - StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); + StreamInfo streamInfo = onPublishHandlerForPlayback(hookData.getMediaServer(), hookData.getMediaInfo(), deviceId, channelId, startTime, endTime); if (streamInfo == null) { logger.warn("璁惧鍥炴斁API璋冪敤澶辫触锛�"); callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), @@ -892,6 +942,10 @@ if (device == null) { return; } + DeviceChannel channel = channelService.getOne(deviceId, channelId); + if (channel == null) { + return; + } MediaServer newMediaServerItem = this.getNewMediaServerItem(device); if (newMediaServerItem == null) { callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(), @@ -900,7 +954,7 @@ return; } // 褰曞儚涓嬭浇涓嶄娇鐢ㄥ浐瀹氭祦鍦板潃锛屽浐瀹氭祦鍦板潃浼氬鑷村鏋滃紑濮嬫椂闂翠笌缁撴潫鏃堕棿涓�鑷存椂鏂囦欢閿欒鐨勫彔鍔犲湪涓�璧� - SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,false, device.getStreamModeForParam()); + SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.getHasAudio(), false, device.getStreamModeForParam()); download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, callback); } @@ -952,10 +1006,10 @@ streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); inviteStreamService.removeInviteInfo(inviteInfo); }; - ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { - logger.info("[褰曞儚涓嬭浇]鏀跺埌璁㈤槄娑堟伅锛� " + hookParam); + HookSubscribe.Event hookEvent = (hookData) -> { + logger.info("[褰曞儚涓嬭浇]鏀跺埌璁㈤槄娑堟伅锛� " + hookData); dynamicTask.stop(downLoadTimeOutTaskKey); - StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); + StreamInfo streamInfo = onPublishHandlerForDownload(hookData.getMediaServer(), hookData.getMediaInfo(), deviceId, channelId, startTime, endTime); if (streamInfo == null) { logger.warn("[褰曞儚涓嬭浇] 鑾峰彇娴佸湴鍧�淇℃伅澶辫触"); callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(), @@ -973,26 +1027,22 @@ downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD); // 娉ㄥ唽褰曞儚鍥炶皟浜嬩欢锛屽綍鍍忎笅杞界粨鏉熷悗鍐欏叆涓嬭浇鍦板潃 - ZlmHttpHookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> { + HookSubscribe.Event hookEventForRecord = (hookData) -> { logger.info("[褰曞儚涓嬭浇] 鏀跺埌褰曞儚鍐欏叆纾佺洏娑堟伅锛� 锛� {}/{}-{}", inviteInfo.getDeviceId(), inviteInfo.getChannelId(), ssrcInfo.getStream()); - logger.info("[褰曞儚涓嬭浇] 鏀跺埌褰曞儚鍐欏叆纾佺洏娑堟伅鍐呭锛� " + hookParam); - OnRecordMp4HookParam recordMp4HookParam = (OnRecordMp4HookParam)hookParam; - String filePath = recordMp4HookParam.getFile_path(); + logger.info("[褰曞儚涓嬭浇] 鏀跺埌褰曞儚鍐欏叆纾佺洏娑堟伅鍐呭锛� " + hookData); + RecordInfo recordInfo = hookData.getRecordInfo(); + String filePath = recordInfo.getFilePath(); DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath); InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId() , inviteInfo.getChannelId(), inviteInfo.getStream()); inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo); inviteStreamService.updateInviteInfo(inviteInfoForNew); }; - HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4( - mediaServerItem.getId(), "rtp", ssrcInfo.getStream()); - + Hook hook = Hook.getInstance(HookType.on_record_mp4, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()); // 璁剧疆杩囨湡鏃堕棿锛屼笅杞藉け璐ユ椂鑷姩澶勭悊璁㈤槄鏁版嵁 -// long difference = DateUtil.getDifference(startTime, endTime)/1000; -// Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(difference * 2)); -// hookSubscribe.setExpires(expiresInstant); - subscribe.addSubscribe(hookSubscribe, hookEventForRecord); + hook.setExpireTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000); + subscribe.addSubscribe(hook, hookEventForRecord); }); } catch (InvalidArgumentException | SipException | ParseException e) { logger.error("[鍛戒护鍙戦�佸け璐 褰曞儚涓嬭浇: {}", e.getMessage()); @@ -1031,12 +1081,8 @@ return null; } String app = "rtp"; - MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, app, stream); - if (mediaInfo == null) { - logger.warn("[鑾峰彇涓嬭浇杩涘害] 鏌ヨ杩涘害澶辫触, 鑺傜偣Id锛� {}锛� {}/{}", mediaServerId, app, stream); - return null; - } - if (mediaInfo.getDuration() == 0) { + Long duration = mediaServerService.updateDownloadProcess(mediaServerItem, app, stream); + if (duration == null || duration == 0) { inviteInfo.getStreamInfo().setProgress(0); } else { String startTime = inviteInfo.getStreamInfo().getStartTime(); @@ -1045,7 +1091,7 @@ long start = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime); long end = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime); - BigDecimal currentCount = new BigDecimal(mediaInfo.getDuration()); + BigDecimal currentCount = new BigDecimal(duration); BigDecimal totalCount = new BigDecimal((end - start) * 1000); BigDecimal divide = currentCount.divide(totalCount, 2, RoundingMode.HALF_UP); double process = divide.doubleValue(); @@ -1058,9 +1104,8 @@ return inviteInfo.getStreamInfo(); } - private StreamInfo onPublishHandlerForDownload(MediaServer mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) { - OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam; - StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, streamChangedHookParam, deviceId, channelId); + private StreamInfo onPublishHandlerForDownload(MediaServer mediaServerItemInuse, MediaInfo mediaInfo, String deviceId, String channelId, String startTime, String endTime) { + StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, mediaInfo, deviceId, channelId); if (streamInfo != null) { streamInfo.setProgress(0); streamInfo.setStartTime(startTime); @@ -1077,9 +1122,8 @@ } - public StreamInfo onPublishHandler(MediaServer mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) { - MediaInfo mediaInfo = MediaInfo.getInstance(hookParam); - StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), mediaInfo, null); + public StreamInfo onPublishHandler(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId) { + StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", mediaInfo.getStream(), mediaInfo, null); streamInfo.setDeviceID(deviceId); streamInfo.setChannelId(channelId); return streamInfo; @@ -1144,7 +1188,7 @@ AudioBroadcastResult audioBroadcastResult = new AudioBroadcastResult(); audioBroadcastResult.setApp(app); audioBroadcastResult.setStream(stream); - audioBroadcastResult.setStreamInfo(new StreamContent(mediaService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null, false))); + audioBroadcastResult.setStreamInfo(new StreamContent(mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null, false))); audioBroadcastResult.setCodec("G.711"); return audioBroadcastResult; } @@ -1166,7 +1210,7 @@ SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬� - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("璇煶骞挎挱宸茬粡寮�鍚細 {}", channelId); event.call("璇煶骞挎挱宸茬粡寮�鍚�"); @@ -1176,18 +1220,6 @@ } } } -// SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); -// if (sendRtpItem != null) { -// MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); -// Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); -// if (streamReady) { -// logger.warn("[璇煶瀵硅] 杩涜涓細 {}", channelId); -// event.call("璇煶瀵硅杩涜涓�"); -// return false; -// } else { -// stopTalk(device, channelId); -// } -// } // 鍙戦�侀�氱煡 cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> { @@ -1202,7 +1234,7 @@ dynamicTask.startDelay(key, ()->{ logger.info("[璇煶骞挎挱]绛夊緟invite娑堟伅瓒呮椂锛歿}/{}", device.getDeviceId(), channelId); stopAudioBroadcast(device.getDeviceId(), channelId); - }, 2000); + }, 10*1000); }, eventResultForError -> { // 鍙戦�佸け璐� logger.error("璇煶骞挎挱鍙戦�佸け璐ワ細 {}:{}", channelId, eventResultForError.msg); @@ -1219,7 +1251,7 @@ if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬� MediaServer mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerServiceOne, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServerServiceOne, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("璇煶骞挎挱閫氶亾浣跨敤涓細 {}", channelId); return true; @@ -1375,100 +1407,51 @@ @Override public void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader) { // 寮�濮嬪彂娴� - String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - logger.info("[寮�濮嬫帹娴乚 rtp/{}, 鐩爣={}:{}锛孲SRC={}, RTCP={}", sendRtpItem.getStream(), - sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); - Map<String, Object> param = new HashMap<>(12); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - param.put("src_port", sendRtpItem.getLocalPort()); - param.put("pt", sendRtpItem.getPt()); - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); - param.put("is_udp", is_Udp); - if (!sendRtpItem.isTcp()) { - // udp妯″紡涓嬪紑鍚痳tcp淇濇椿 - param.put("udp_rtcp_timeout", sendRtpItem.isRtcp() ? "1" : "0"); - } - if (mediaInfo == null) { - RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( - sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStream(), - sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isTcp(), - sendRtpItem.getLocalPort(), sendRtpItem.getPt(), sendRtpItem.isUsePs(), sendRtpItem.isOnlyAudio()); - redisGbPlayMsgListener.sendMsgForStartSendRtpStream(sendRtpItem.getServerId(), requestPushStreamMsg, json -> { - startSendRtpStreamHand(sendRtpItem, platform, json, param, callIdHeader); - }); - } else { - // 濡傛灉鏄弗鏍兼ā寮忥紝闇�瑕佸叧闂鍙e崰鐢� - JSONObject startSendRtpStreamResult = null; - if (sendRtpItem.getLocalPort() != 0) { + if (mediaInfo != null) { + try { if (sendRtpItem.isTcpActive()) { - startSendRtpStreamResult = zlmServerFactory.startSendRtpPassive(mediaInfo, param); + mediaServerService.startSendRtpPassive(mediaInfo, sendRtpItem, null); } else { - param.put("dst_url", sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - startSendRtpStreamResult = zlmServerFactory.startSendRtpStream(mediaInfo, param); + mediaServerService.startSendRtp(mediaInfo, sendRtpItem); } - } else { - if (sendRtpItem.isTcpActive()) { - startSendRtpStreamResult = zlmServerFactory.startSendRtpPassive(mediaInfo, param); - } else { - param.put("dst_url", sendRtpItem.getIp()); - param.put("dst_port", sendRtpItem.getPort()); - startSendRtpStreamResult = zlmServerFactory.startSendRtpStream(mediaInfo, param); - } + redisCatchStorage.sendPlatformStartPlayMsg(sendRtpItem, platform); + }catch (ControllerException e) { + logger.error("RTP鎺ㄦ祦澶辫触: {}", e.getMessage()); + startSendRtpStreamFailHand(sendRtpItem, platform, callIdHeader); + return; } - if (startSendRtpStreamResult != null) { - startSendRtpStreamHand(sendRtpItem, platform, startSendRtpStreamResult, param, callIdHeader); - } + + logger.info("RTP鎺ㄦ祦鎴愬姛[ {}/{} ]锛寋}, ", sendRtpItem.getApp(), sendRtpItem.getStream(), + sendRtpItem.isTcpActive()?"琚姩鍙戞祦": sendRtpItem.getIp() + ":" + sendRtpItem.getPort()); + } } @Override - public void startSendRtpStreamHand(SendRtpItem sendRtpItem, Object correlationInfo, - JSONObject jsonObject, Map<String, Object> param, CallIdHeader callIdHeader) { - if (jsonObject == null) { - logger.error("RTP鎺ㄦ祦澶辫触: 璇锋鏌LM鏈嶅姟"); - } else if (jsonObject.getInteger("code") == 0) { - logger.info("璋冪敤ZLM鎺ㄦ祦鎺ュ彛, 缁撴灉锛� {}", jsonObject); - logger.info("RTP鎺ㄦ祦鎴愬姛[ {}/{} ]锛寋}->{}, ", param.get("app"), param.get("stream"), jsonObject.getString("local_port"), - sendRtpItem.isTcpActive()?"琚姩鍙戞祦": param.get("dst_url") + ":" + param.get("dst_port")); - if (sendRtpItem.getPlayType() == InviteStreamType.PUSH && correlationInfo instanceof ParentPlatform) { - ParentPlatform platform = (ParentPlatform)correlationInfo; - MessageForPushChannel messageForPushChannel = MessageForPushChannel.getInstance(0, sendRtpItem.getApp(), sendRtpItem.getStream(), - sendRtpItem.getChannelId(), platform.getServerGBId(), platform.getName(), userSetting.getServerId(), - sendRtpItem.getMediaServerId()); - messageForPushChannel.setPlatFormIndex(platform.getId()); - redisCatchStorage.sendPlatformStartPlayMsg(messageForPushChannel); + public void startSendRtpStreamFailHand(SendRtpItem sendRtpItem, ParentPlatform platform, CallIdHeader callIdHeader) { + if (sendRtpItem.isOnlyAudio()) { + Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); + AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); + if (audioBroadcastCatch != null) { + try { + cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); + } catch (SipException | ParseException | InvalidArgumentException | + SsrcTransactionNotFoundException exception) { + logger.error("[鍛戒护鍙戦�佸け璐 鍋滄璇煶瀵硅: {}", exception.getMessage()); + } } } else { - logger.error("RTP鎺ㄦ祦澶辫触: {}, 鍙傛暟锛歿}", jsonObject.getString("msg"), JSONObject.toJSONString(param)); - if (sendRtpItem.isOnlyAudio()) { - Device device = deviceService.getDevice(sendRtpItem.getDeviceId()); - AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); - if (audioBroadcastCatch != null) { - try { - cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null); - } catch (SipException | ParseException | InvalidArgumentException | - SsrcTransactionNotFoundException e) { - logger.error("[鍛戒护鍙戦�佸け璐 鍋滄璇煶瀵硅: {}", e.getMessage()); - } - } - } else { + if (platform != null) { // 鍚戜笂绾у钩鍙� - if (correlationInfo instanceof ParentPlatform) { - try { - ParentPlatform parentPlatform = (ParentPlatform)correlationInfo; - commanderForPlatform.streamByeCmd(parentPlatform, callIdHeader.getCallId()); - } catch (SipException | InvalidArgumentException | ParseException e) { - logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage()); - } + try { + commanderForPlatform.streamByeCmd(platform, callIdHeader.getCallId()); + } catch (SipException | InvalidArgumentException | ParseException e) { + logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage()); } } + } } @@ -1491,7 +1474,7 @@ if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬� MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("[璇煶瀵硅] 姝e湪璇煶骞挎挱锛屾棤娉曞紑鍚闊抽�氳瘽锛� {}", channelId); event.call("姝e湪璇煶骞挎挱"); @@ -1505,7 +1488,7 @@ SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, stream, null); if (sendRtpItem != null) { MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream()); + Boolean streamReady = mediaServerService.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream()); if (streamReady) { logger.warn("[璇煶瀵硅] 杩涜涓細 {}", channelId); event.call("璇煶瀵硅杩涜涓�"); @@ -1515,7 +1498,7 @@ } } - talk(mediaServerItem, device, channelId, stream, (mediaServerItem1, hookParam) -> { + talk(mediaServerItem, device, channelId, stream, (hookData) -> { logger.info("[璇煶瀵硅] 鏀跺埌璁惧鍙戞潵鐨勬祦"); }, eventResult -> { logger.warn("[璇煶瀵硅] 澶辫触锛寋}/{}, 閿欒鐮� {} {}", device.getDeviceId(), channelId, eventResult.statusCode, eventResult.msg); @@ -1552,12 +1535,7 @@ MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (streamIsReady == null || streamIsReady) { - Map<String, Object> param = new HashMap<>(); - param.put("vhost", "__defaultVhost__"); - param.put("app", sendRtpItem.getApp()); - param.put("stream", sendRtpItem.getStream()); - param.put("ssrc", sendRtpItem.getSsrc()); - zlmServerFactory.stopSendRtpStream(mediaServer, param); + mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc()); } ssrcFactory.releaseSsrc(mediaServerId, sendRtpItem.getSsrc()); @@ -1620,4 +1598,26 @@ }); } + @Override + public void stopPlay(Device device, String channelId) { + InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); + if (inviteInfo == null) { + throw new ControllerException(ErrorCode.ERROR100.getCode(), "鐐规挱鏈壘鍒�"); + } + if (InviteSessionStatus.ok == inviteInfo.getStatus()) { + try { + logger.info("[鍋滄鐐规挱] {}/{}", device.getDeviceId(), channelId); + cmder.streamByeCmd(device, channelId, inviteInfo.getStream(), null, null); + } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) { + logger.error("[鍛戒护鍙戦�佸け璐 鍋滄鐐规挱锛� 鍙戦�丅YE: {}", e.getMessage()); + throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍛戒护鍙戦�佸け璐�: " + e.getMessage()); + } + } + inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId); + storager.stopPlay(device.getDeviceId(), channelId); + channelService.stopPlay(device.getDeviceId(), channelId); + if (inviteInfo.getStreamInfo() != null) { + mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream()); + } + } } -- Gitblit v1.8.0