From c6dfb63f8fd5f04fa00ac6c45da2eb6bcc5cada4 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期一, 25 三月 2024 23:59:50 +0800 Subject: [PATCH] 优化hook通知 --- src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 249 +++++++++++++------------------------------------ 1 files changed, 67 insertions(+), 182 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 1ac61bd..ca52619 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -10,20 +10,23 @@ import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException; import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.event.EventPublisher; -import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; +import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager; import com.genersoft.iot.vmp.gb28181.session.SSRCFactory; import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; 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.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; -import com.genersoft.iot.vmp.media.IMediaServerService; -import com.genersoft.iot.vmp.media.zlm.dto.HookType; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo; -import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; +import com.genersoft.iot.vmp.media.bean.MediaInfo; +import com.genersoft.iot.vmp.media.bean.ResultForOnPublish; +import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; +import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; +import com.genersoft.iot.vmp.media.service.IMediaServerService; +import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.hook.*; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerKeepaliveEvent; +import com.genersoft.iot.vmp.media.zlm.event.HookZlmServerStartEvent; import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.bean.MessageForPushChannel; import com.genersoft.iot.vmp.service.bean.SSRCInfo; @@ -38,6 +41,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.util.ObjectUtils; @@ -72,9 +76,6 @@ @Autowired private AudioBroadcastManager audioBroadcastManager; - - @Autowired - private ZLMServerFactory zlmServerFactory; @Autowired private IPlayService playService; @@ -125,9 +126,6 @@ private VideoStreamSessionManager sessionManager; @Autowired - private AssistRESTfulUtils assistRESTfulUtils; - - @Autowired private SSRCFactory ssrcFactory; @Qualifier("taskExecutor") @@ -137,25 +135,25 @@ @Autowired private RedisTemplate<Object, Object> redisTemplate; + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + /** * 鏈嶅姟鍣ㄥ畾鏃朵笂鎶ユ椂闂达紝涓婃姤闂撮殧鍙厤缃紝榛樿10s涓婃姤涓�娆� */ @ResponseBody - @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param) { - - - taskExecutor.execute(() -> { - List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive); - if (subscribes != null && subscribes.size() > 0) { - for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { - subscribe.response(null, param); - } + try { + HookZlmServerKeepaliveEvent event = new HookZlmServerKeepaliveEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); } - }); - mediaServerService.updateMediaServerKeepalive(param.getMediaServerId(), param.getData()); - + }catch (Exception e) { + logger.info("[ZLM-HOOK-蹇冭烦] 鍙戦�侀�氱煡澶辫触 ", e); + } return HookResult.SUCCESS(); } @@ -163,30 +161,16 @@ * 鎾斁鍣ㄩ壌鏉冧簨浠讹紝rtsp/rtmp/http-flv/ws-flv/hls鐨勬挱鏀鹃兘灏嗚Е鍙戞閴存潈浜嬩欢銆� */ @ResponseBody - @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8") public HookResult onPlay(@RequestBody OnPlayHookParam param) { if (logger.isDebugEnabled()) { - logger.debug("[ZLM HOOK] 鎾斁閴存潈锛歿}->{}" + param.getMediaServerId(), param); + logger.debug("[ZLM HOOK] 鎾斁閴存潈锛歿}->{}", param.getMediaServerId(), param); } - String mediaServerId = param.getMediaServerId(); - - taskExecutor.execute(() -> { - JSONObject json = (JSONObject) JSON.toJSON(param); - ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json); - if (subscribe != null) { - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo != null) { - subscribe.response(mediaInfo, param); - } - } - }); - if (!"rtp".equals(param.getApp())) { - Map<String, String> paramMap = urlParamToMap(param.getParams()); - StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream()); - if (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId"))) { - return new HookResult(401, "Unauthorized"); - } + Map<String, String> paramMap = urlParamToMap(param.getParams()); + // 瀵逛簬鎾斁娴佽繘琛岄壌鏉� + boolean authenticateResult = mediaService.authenticatePlay(param.getApp(), param.getStream(), paramMap.get("callId")); + if (!authenticateResult) { + return new HookResult(401, "Unauthorized"); } return HookResult.SUCCESS(); @@ -202,140 +186,31 @@ JSONObject json = (JSONObject) JSON.toJSON(param); logger.info("[ZLM HOOK]鎺ㄦ祦閴存潈锛歿}->{}", param.getMediaServerId(), param); + // TODO 鍔犲揩澶勭悊閫熷害 String mediaServerId = json.getString("mediaServerId"); - MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo == null) { + MediaServer mediaServer = mediaServerService.getOne(mediaServerId); + if (mediaServer == null) { return new HookResultForOnPublish(200, "success"); } - // 鎺ㄦ祦閴存潈鐨勫鐞� - if (!"rtp".equals(param.getApp())) { - StreamProxyItem stream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream()); - if (stream != null) { - HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); - result.setEnable_audio(stream.isEnableAudio()); - result.setEnable_mp4(stream.isEnableMp4()); - return result; - } - if (userSetting.getPushAuthority()) { - // 鎺ㄦ祦閴存潈 - if (param.getParams() == null) { - logger.info("鎺ㄦ祦閴存潈澶辫触锛� 缂哄皯蹇呰鍙傛暟锛歴ign=md5(user琛ㄧ殑pushKey)"); - return new HookResultForOnPublish(401, "Unauthorized"); - } - Map<String, String> paramMap = urlParamToMap(param.getParams()); - String sign = paramMap.get("sign"); - if (sign == null) { - logger.info("鎺ㄦ祦閴存潈澶辫触锛� 缂哄皯蹇呰鍙傛暟锛歴ign=md5(user琛ㄧ殑pushKey)"); - return new HookResultForOnPublish(401, "Unauthorized"); - } - // 鎺ㄦ祦鑷畾涔夋挱鏀鹃壌鏉冪爜 - String callId = paramMap.get("callId"); - // 閴存潈閰嶇疆 - boolean hasAuthority = userService.checkPushAuthority(callId, sign); - if (!hasAuthority) { - logger.info("鎺ㄦ祦閴存潈澶辫触锛� sign 鏃犳潈闄�: callId={}. sign={}", callId, sign); - return new HookResultForOnPublish(401, "Unauthorized"); - } - StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - streamAuthorityInfo.setCallId(callId); - streamAuthorityInfo.setSign(sign); - // 閴存潈閫氳繃 - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo); - } - } else { - zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId()); - } - - HookResultForOnPublish result = HookResultForOnPublish.SUCCESS(); - result.setEnable_audio(true); taskExecutor.execute(() -> { ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json); if (subscribe != null) { - if (mediaInfo != null) { - subscribe.response(mediaInfo, param); - } else { - new HookResultForOnPublish(1, "zlm not register"); - } + subscribe.response(mediaServer, param); } }); - // 鏄惁褰曞儚 - if ("rtp".equals(param.getApp())) { - result.setEnable_mp4(userSetting.getRecordSip()); - } else { - result.setEnable_mp4(userSetting.isRecordPushLive()); + ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams()); + if (resultForOnPublish != null) { + HookResultForOnPublish successResult = HookResultForOnPublish.getInstance(resultForOnPublish); + logger.info("[ZLM HOOK]鎺ㄦ祦閴存潈 鍝嶅簲锛歿}->{}->>>>{}", param.getMediaServerId(), param, successResult); + return successResult; + }else { + HookResultForOnPublish fail = HookResultForOnPublish.Fail(); + logger.info("[ZLM HOOK]鎺ㄦ祦閴存潈 鍝嶅簲锛歿}->{}->>>>{}", param.getMediaServerId(), param, fail); + return fail; } - // 鍥芥爣娴� - if ("rtp".equals(param.getApp())) { - - InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream()); - - // 鍗曠鍙fā寮忎笅淇敼娴� ID - if (!mediaInfo.isRtpEnable() && inviteInfo == null) { - String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16)); - inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); - if (inviteInfo != null) { - result.setStream_replace(inviteInfo.getStream()); - logger.info("[ZLM HOOK]鎺ㄦ祦閴存潈 stream: {} 鏇挎崲涓� {}", param.getStream(), inviteInfo.getStream()); - } - } - - // 璁剧疆闊抽淇℃伅鍙婂綍鍒朵俊鎭� - List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream()); - if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) { - - // 涓哄綍鍒跺浗鏍囨ā鎷熶竴涓壌鏉冧俊鎭�, 鏂逛究鍚庣画鍐欏叆褰曞儚鏂囦欢鏃朵娇鐢� - StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param); - streamAuthorityInfo.setApp(param.getApp()); - streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream()); - streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId()); - - redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo); - - String deviceId = ssrcTransactionForAll.get(0).getDeviceId(); - String channelId = ssrcTransactionForAll.get(0).getChannelId(); - DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); - if (deviceChannel != null) { - result.setEnable_audio(deviceChannel.isHasAudio()); - } - // 濡傛灉鏄綍鍍忎笅杞藉氨璁剧疆瑙嗛闂撮殧鍗佺 - if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) { - // 鑾峰彇褰曞儚鐨勬�绘椂闀匡紝鐒跺悗璁剧疆涓鸿繖涓棰戠殑鏃堕暱 - InviteInfo inviteInfoForDownload = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, param.getStream()); - if (inviteInfoForDownload != null && inviteInfoForDownload.getStreamInfo() != null) { - String startTime = inviteInfoForDownload.getStreamInfo().getStartTime(); - String endTime = inviteInfoForDownload.getStreamInfo().getEndTime(); - long difference = DateUtil.getDifference(startTime, endTime) / 1000; - result.setMp4_max_second((int) difference); - result.setEnable_mp4(true); - // 璁剧疆涓�2淇濊瘉寰楀埌鐨刴p4鐨勬椂闀挎槸姝e父鐨� - result.setModify_stamp(2); - } - } - // 濡傛灉鏄痶alk瀵硅锛屽垯榛樿鑾峰彇澹伴煶 - if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.TALK) { - result.setEnable_audio(true); - } - } - } else if (param.getApp().equals("broadcast")) { - result.setEnable_audio(true); - } else if (param.getApp().equals("talk")) { - result.setEnable_audio(true); - } - if (param.getApp().equalsIgnoreCase("rtp")) { - String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + param.getStream(); - OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo) redisTemplate.opsForValue().get(receiveKey); - - String receiveKeyForPS = VideoManagerConstants.WVP_OTHER_RECEIVE_PS_INFO + userSetting.getServerId() + "_" + param.getStream(); - OtherPsSendInfo otherPsSendInfo = (OtherPsSendInfo) redisTemplate.opsForValue().get(receiveKeyForPS); - if (otherRtpSendInfo != null || otherPsSendInfo != null) { - result.setEnable_mp4(true); - } - } - logger.info("[ZLM HOOK]鎺ㄦ祦閴存潈 鍝嶅簲锛歿}->{}->>>>{}", param.getMediaServerId(), param, result); - return result; } @@ -346,16 +221,25 @@ @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") public HookResult onStreamChanged(@RequestBody OnStreamChangedHookParam param) { + MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId()); + if (param.isRegist()) { logger.info("[ZLM HOOK] 娴佹敞鍐�, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + MediaArrivalEvent mediaArrivalEvent = MediaArrivalEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaArrivalEvent); } else { logger.info("[ZLM HOOK] 娴佹敞閿�, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream()); + MediaDepartureEvent mediaArrivalEvent = MediaDepartureEvent.getInstance(this, param, mediaServer); + applicationEventPublisher.publishEvent(mediaArrivalEvent); } + return HookResult.SUCCESS(); + + JSONObject json = (JSONObject) JSON.toJSON(param); taskExecutor.execute(() -> { ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json); - MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); if (mediaInfo == null) { logger.info("[ZLM HOOK] 娴佸彉鍖栨湭鎵惧埌ZLM, {}", param.getMediaServerId()); return; @@ -364,7 +248,6 @@ subscribe.response(mediaInfo, param); } - List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks(); // TODO 閲嶆瀯姝ゅ閫昏緫 if (param.isRegist()) { // 澶勭悊娴佹敞鍐岀殑閴存潈淇℃伅锛� 娴佹敞閿�杩欓噷涓嶅啀鍒犻櫎閴存潈淇℃伅锛屼笅娆℃潵浜嗘柊鐨勯壌鏉冧俊鎭細瀵瑰氨鐨勮繘琛岃鐩� @@ -468,7 +351,7 @@ callId = streamAuthorityInfo.getCallId(); } StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaInfo, - param.getApp(), param.getStream(), tracks, callId); + param.getApp(), param.getStream(), MediaInfo.getInstance(param), callId); param.setStreamInfo(new StreamContent(streamInfoByAppAndStream)); redisCatchStorage.addStream(mediaInfo, type, param.getApp(), param.getStream(), param); if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal() @@ -580,9 +463,9 @@ } // 鏀跺埌鏃犱汉瑙傜湅璇存槑娴佷篃娌℃湁鍦ㄥ線涓婄骇鎺ㄩ�� if (redisCatchStorage.isChannelSendingRTP(inviteInfo.getChannelId())) { - List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChnnelId( + List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByChannelId( inviteInfo.getChannelId()); - if (sendRtpItems.size() > 0) { + if (!sendRtpItems.isEmpty()) { for (SendRtpItem sendRtpItem : sendRtpItems) { ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); try { @@ -656,12 +539,6 @@ } return ret; } - // TODO 鎺ㄦ祦鍏锋湁涓诲姩鎬э紝鏆傛椂涓嶅仛澶勭悊 -// StreamPushItem streamPushItem = streamPushService.getPush(app, streamId); -// if (streamPushItem != null) { -// // TODO 鍙戦�佸仠姝� -// -// } } return ret; } @@ -676,7 +553,7 @@ DeferredResult<HookResult> defaultResult = new DeferredResult<>(); - MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId()); + MediaServer mediaInfo = mediaServerService.getOne(param.getMediaServerId()); if (!userSetting.isAutoApplyPlay() || mediaInfo == null) { defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg())); return defaultResult; @@ -799,13 +676,22 @@ logger.info("[ZLM HOOK] zlm 鍚姩 " + zlmServerConfig.getGeneralMediaServerId()); taskExecutor.execute(() -> { List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started); - if (subscribes != null && subscribes.size() > 0) { + if (subscribes != null && !subscribes.isEmpty()) { for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { subscribe.response(null, zlmServerConfig); } } - mediaServerService.zlmServerOnline(zlmServerConfig); }); + try { + HookZlmServerStartEvent event = new HookZlmServerStartEvent(this); + MediaServer mediaServerItem = mediaServerService.getOne(zlmServerConfig.getMediaServerId()); + if (mediaServerItem != null) { + event.setMediaServerItem(mediaServerItem); + applicationEventPublisher.publishEvent(event); + } + }catch (Exception e) { + logger.info("[ZLM-HOOK-ZLM鍚姩] 鍙戦�侀�氱煡澶辫触 ", e); + } return HookResult.SUCCESS(); } @@ -848,12 +734,11 @@ */ @ResponseBody @PostMapping(value = "/on_rtp_server_timeout", produces = "application/json;charset=UTF-8") - public HookResult onRtpServerTimeout(HttpServletRequest request, @RequestBody OnRtpServerTimeoutHookParam + public HookResult onRtpServerTimeout(@RequestBody OnRtpServerTimeoutHookParam param) { logger.info("[ZLM HOOK] rtpServer鏀舵祦瓒呮椂锛歿}->{}({})", param.getMediaServerId(), param.getStream_id(), param.getSsrc()); taskExecutor.execute(() -> { - JSONObject json = (JSONObject) JSON.toJSON(param); List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout); if (subscribes != null && !subscribes.isEmpty()) { for (ZlmHttpHookSubscribe.Event subscribe : subscribes) { -- Gitblit v1.8.0