From 4548695a0b79cc6a3cc940d698cdf1d0b535d570 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期日, 31 三月 2024 00:28:45 +0800
Subject: [PATCH] hook优化

---
 src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java                                                                |    2 
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java                                 |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java                                                 |   14 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java                                                    |    4 
 src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java                                                             |   40 
 src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java                                                           |    4 
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java                                                           |   58 ++
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java                                                    |   33 +
 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java                                                            |    2 
 src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java                                                      |   32 +
 src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java                                                                  |   86 +++
 src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java                                                   |    4 
 src/main/java/com/genersoft/iot/vmp/service/IPlayService.java                                                                   |    3 
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java                                                |   17 
 src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java                                                                  |   92 +++
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java                                         |    2 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java                                                           |    2 
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java                                                   |   22 
 src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java                                                       |   30 
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java                                       |    2 
 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java                                                           |   87 +-
 src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java                                               |    2 
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java                                                  |   22 
 src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java                                              |   73 ++
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java                                        |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/MediaStatusNotifyMessageHandler.java |    9 
 src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java                                                   |    7 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java                             |   17 
 src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java                                                           |   19 
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java                                           |   22 
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java                                                  |   36 +
 src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java                                                    |   15 
 src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java                                                     |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java                                                 |   51 -
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java                                                   |    4 
 src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java                                                  |   13 
 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java                                                          |   67 --
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java                                                      |    2 
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java                                                    |    2 
 src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java                                                               |   28 
 src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java                                                                   |   57 ++
 src/main/java/com/genersoft/iot/vmp/service/IMediaService.java                                                                  |   33 -
 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java                                                         |  189 ++----
 src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java                                                            |    5 
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java                                       |    2 
 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java                                                              |  132 +++++
 src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java                                                       |   14 
 /dev/null                                                                                                                       |   36 -
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                                                          |   37 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java                                      |   14 
 src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java   |   23 
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java                                         |    2 
 src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java                                                              |    2 
 src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java                                                    |   46 +
 src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java                                                    |   28 
 src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java                                         |    4 
 56 files changed, 995 insertions(+), 564 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
index f386c33..299d59a 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
@@ -6,8 +6,8 @@
 import com.genersoft.iot.vmp.gb28181.event.record.RecordEndEvent;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.mobilePosition.MobilePositionEvent;
-import com.genersoft.iot.vmp.media.event.MediaServerOfflineEvent;
-import com.genersoft.iot.vmp.media.event.MediaServerOnlineEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOfflineEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerOnlineEvent;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Component;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java
index f5385d4..24eadba 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java
@@ -1,26 +1,13 @@
 package com.genersoft.iot.vmp.gb28181.session;
 
 import com.genersoft.iot.vmp.conf.SipConfig;
-import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
 import com.genersoft.iot.vmp.gb28181.bean.AudioBroadcastCatch;
-import com.genersoft.iot.vmp.gb28181.bean.Device;
-import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
-import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.media.event.MediaDepartureEvent;
-import com.genersoft.iot.vmp.service.IDeviceService;
-import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.event.EventListener;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
-import javax.sip.InvalidArgumentException;
-import javax.sip.SipException;
-import java.text.ParseException;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
index 14d496d..1711938 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -14,12 +14,11 @@
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
 import com.genersoft.iot.vmp.gb28181.utils.NumericUtil;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamPush;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -279,11 +278,11 @@
         }
 
         logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getSdpIp(), ssrcInfo.getPort());
-        HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
-        subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> {
+        Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId());
+        subscribe.addSubscribe(rtpHook, (hookData) -> {
             if (event != null) {
-                event.response(mediaServerItemInUse, hookParam);
-                subscribe.removeSubscribe(hookSubscribe);
+                event.response(hookData);
+                subscribe.removeSubscribe(rtpHook);
             }
         });
         String sdpIp;
@@ -453,13 +452,13 @@
         //ssrc
         content.append("y=" + ssrcInfo.getSsrc() + "\r\n");
 
-        HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
+        Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId());
         // 娣诲姞璁㈤槄
-        subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> {
+        subscribe.addSubscribe(rtpHook, (hookData) -> {
             if (hookEvent != null) {
-                hookEvent.response(mediaServerItemInUse, hookParam);
+                hookEvent.response(hookData);
             }
-            subscribe.removeSubscribe(hookSubscribe);
+            subscribe.removeSubscribe(rtpHook);
         });
         Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc());
 
@@ -554,19 +553,18 @@
 
         content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
         logger.debug("姝ゆ椂璇锋眰涓嬭浇淇′护鐨剆src===>{}",ssrcInfo.getSsrc());
-        HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
+        Hook rtpHook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId());
         // 娣诲姞璁㈤槄
         CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport());
         String callId= newCallIdHeader.getCallId();
-        subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
+        subscribe.addSubscribe(rtpHook, (hookData) -> {
             logger.debug("sipc 娣诲姞璁㈤槄===callId {}",callId);
-            hookEvent.response(mediaServerItemInUse, hookParam);
-            subscribe.removeSubscribe(hookSubscribe);
-            hookSubscribe.getContent().put("regist", false);
-            hookSubscribe.getContent().put("schema", "rtsp");
+            hookEvent.response(hookData);
+            subscribe.removeSubscribe(rtpHook);
             // 娣诲姞娴佹敞閿�鐨勮闃咃紝娉ㄩ攢浜嗗悗鍚戣澶囧彂閫乥ye
-            subscribe.addSubscribe(hookSubscribe,
-                    (mediaServerItemForEnd, hookParam1) -> {
+            Hook departureHook = Hook.getInstance(HookType.on_media_departure, "rtp", ssrcInfo.getStream(), mediaServerItem.getId());
+            subscribe.addSubscribe(departureHook,
+                    (departureHookData) -> {
                         logger.info("[褰曞儚]涓嬭浇缁撴潫锛� 鍙戦�丅YE");
                         try {
                             streamByeCmd(device, channelId, ssrcInfo.getStream(), callId);
@@ -604,20 +602,20 @@
         }
 
         logger.info("[璇煶鍠婅瘽] {} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), sendRtpItem.getPort());
-        HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
-        subscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItemInUse, hookParam) -> {
+        Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId());
+        subscribe.addSubscribe(hook, (hookData) -> {
             if (event != null) {
-                event.response(mediaServerItemInUse, hookParam);
-                subscribe.removeSubscribe(hookSubscribeForStreamChange);
+                event.response(hookData);
+                subscribe.removeSubscribe(hook);
             }
         });
 
         CallIdHeader callIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport());
         callIdHeader.setCallId(callId);
-        HookSubscribeForStreamPush hookSubscribeForStreamPush = HookSubscribeFactory.on_publish("rtp", stream,  null, mediaServerItem.getId());
-        subscribe.addSubscribe(hookSubscribeForStreamPush, (mediaServerItemInUse, hookParam) -> {
+        Hook publishHook = Hook.getInstance(HookType.on_publish, "rtp", stream, mediaServerItem.getId());
+        subscribe.addSubscribe(publishHook, (hookData) -> {
             if (eventForPush != null) {
-                eventForPush.response(mediaServerItemInUse, hookParam);
+                eventForPush.response(hookData);
             }
         });
         //
@@ -1260,7 +1258,6 @@
      * @param startPriority 鎶ヨ璧峰绾у埆锛堝彲閫夛級
      * @param endPriority   鎶ヨ缁堟绾у埆锛堝彲閫夛級
      * @param alarmMethod   鎶ヨ鏂瑰紡鏉′欢锛堝彲閫夛級
-     * @param alarmType     鎶ヨ绫诲瀷
      * @param startTime     鎶ヨ鍙戠敓璧峰鏃堕棿锛堝彲閫夛級
      * @param endTime       鎶ヨ鍙戠敓缁堟鏃堕棿锛堝彲閫夛級
      * @return true = 鍛戒护鍙戦�佹垚鍔�
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
index 441e0f0..21aba6c 100755
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -13,9 +13,9 @@
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderPlarformProvider;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
+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.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
@@ -905,11 +905,11 @@
         }
 
         logger.info("{} 鍒嗛厤鐨刏LM涓�: {} [{}:{}]", stream, mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
-        HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
-        subscribe.addSubscribe(hookSubscribe, (MediaServer mediaServerItemInUse, HookParam hookParam) -> {
+        Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", stream, mediaServerItem.getId());
+        subscribe.addSubscribe(hook, (hookData) -> {
             if (event != null) {
-                event.response(mediaServerItemInUse, hookParam);
-                subscribe.removeSubscribe(hookSubscribe);
+                event.response(hookData);
+                subscribe.removeSubscribe(hook);
             }
         });
         String sdpIp = mediaServerItem.getSdpIp();
@@ -949,7 +949,7 @@
         sipSender.transmitRequest(sipLayer.getLocalIp(platform.getDeviceIp()), request, (e -> {
             streamSession.remove(platform.getServerGBId(), channelId, ssrcInfo.getStream());
             mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
-            subscribe.removeSubscribe(hookSubscribe);
+            subscribe.removeSubscribe(hook);
             errorEvent.response(e);
         }), e -> {
             ResponseEvent responseEvent = (ResponseEvent) e.event;
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 a8c03d7..9f4e470 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
@@ -18,8 +18,8 @@
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
@@ -115,7 +115,7 @@
     private IMediaServerService mediaServerService;
 
     @Autowired
-    private HookSubscribe zlmHttpHookSubscribe;
+    private HookSubscribe hookSubscribe;
 
     @Autowired
     private SIPProcessorObserver sipProcessorObserver;
@@ -723,17 +723,16 @@
             // TODO 鎺у埗鍚敤浠ヤ娇璁惧涓婄嚎
             logger.info("[ app={}, stream={} ]閫氶亾鏈帹娴侊紝鍚敤娴佸悗寮�濮嬫帹娴�", gbStream.getApp(), gbStream.getStream());
             // 鐩戝惉娴佷笂绾�
-            HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(gbStream.getApp(), gbStream.getStream(), true, "rtsp", mediaServerItem.getId());
-            zlmHttpHookSubscribe.addSubscribe(hookSubscribe, (mediaServerItemInUSe, hookParam) -> {
-                OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
-                logger.info("[涓婄骇鐐规挱]鎷夋祦浠g悊宸茬粡灏辩华锛� {}/{}", streamChangedHookParam.getApp(), streamChangedHookParam.getStream());
+            Hook hook = Hook.getInstance(HookType.on_media_arrival, gbStream.getApp(), gbStream.getStream(), mediaServerItem.getId());
+            this.hookSubscribe.addSubscribe(hook, (hookData) -> {
+                logger.info("[涓婄骇鐐规挱]鎷夋祦浠g悊宸茬粡灏辩华锛� {}/{}", hookData.getApp(), hookData.getStream());
                 dynamicTask.stop(callIdHeader.getCallId());
                 pushProxyStream(evt, request, gbStream, platform, callIdHeader, mediaServerItem, port, tcpActive,
                         mediaTransmissionTCP, channelId, addressStr, ssrc, requesterId);
             });
             dynamicTask.startDelay(callIdHeader.getCallId(), () -> {
                 logger.info("[ app={}, stream={} ] 绛夊緟鎷夋祦浠g悊娴佽秴鏃�", gbStream.getApp(), gbStream.getStream());
-                zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
+                this.hookSubscribe.removeSubscribe(hook);
             }, userSetting.getPlatformPlayTimeout());
             boolean start = streamProxyService.start(gbStream.getApp(), gbStream.getStream());
             if (!start) {
@@ -742,7 +741,7 @@
                 } catch (SipException | InvalidArgumentException | ParseException e) {
                     logger.error("[鍛戒护鍙戦�佸け璐 invite 閫氶亾鏈帹娴�: {}", e.getMessage());
                 }
-                zlmHttpHookSubscribe.removeSubscribe(hookSubscribe);
+                this.hookSubscribe.removeSubscribe(hook);
                 dynamicTask.stop(callIdHeader.getCallId());
             }
         } else if ("push".equals(gbStream.getStreamType())) {
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java
index 57b7682..72ba51a 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/BroadcastNotifyMessageHandler.java
@@ -127,8 +127,7 @@
 
                 // 娑堟伅鍙戦�佹垚鍔燂紝 鍚戜笂绾у彂閫乮nvite锛岃幏鍙栨帹娴�
                 try {
-                    platformService.broadcastInvite(platform, deviceChannel.getChannelId(), mediaServerForMinimumLoad,  (mediaServerItem, hookParam)->{
-                        OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
+                    platformService.broadcastInvite(platform, deviceChannel.getChannelId(), mediaServerForMinimumLoad,  (hookData)->{
                         // 涓婄骇骞冲彴鎺ㄦ祦鎴愬姛
                         AudioBroadcastCatch broadcastCatch = audioBroadcastManager.get(device.getDeviceId(), targetId);
                         if (broadcastCatch != null ) {
@@ -136,20 +135,20 @@
                                 logger.info("[鍥芥爣绾ц仈] 璇煶鍠婅瘽 璁惧姝e湪浣跨敤涓� platform锛� {}锛� channel: {}",
                                         platform.getServerGBId(), deviceChannel.getChannelId());
                                 //  鏌ョ湅璇煶閫氶亾宸茬粡寤虹珛涓斿凡缁忓崰鐢� 鍥炲BYE
-                                platformService.stopBroadcast(platform, deviceChannel, streamChangedHookParam.getStream(),  true, mediaServerItem);
+                                platformService.stopBroadcast(platform, deviceChannel, hookData.getStream(),  true, hookData.getMediaServer());
                             }else {
                                 // 鏌ョ湅璇煶閫氶亾宸茬粡寤虹珛浣嗘槸鏈崰鐢�
-                                broadcastCatch.setApp(streamChangedHookParam.getApp());
-                                broadcastCatch.setStream(streamChangedHookParam.getStream());
-                                broadcastCatch.setMediaServerItem(mediaServerItem);
+                                broadcastCatch.setApp(hookData.getApp());
+                                broadcastCatch.setStream(hookData.getStream());
+                                broadcastCatch.setMediaServerItem(hookData.getMediaServer());
                                 audioBroadcastManager.update(broadcastCatch);
                                 // 鎺ㄦ祦鍒拌澶�
-                                SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, targetId, streamChangedHookParam.getStream(), null);
+                                SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, targetId, hookData.getStream(), null);
                                 if (sendRtpItem == null) {
-                                    logger.warn("[鍥芥爣绾ц仈] 璇煶鍠婅瘽 寮傚父锛屾湭鎵惧埌鍙戞祦淇℃伅锛� channelId: {}, stream: {}", targetId, streamChangedHookParam.getStream());
-                                    logger.info("[鍥芥爣绾ц仈] 璇煶鍠婅瘽 閲嶆柊寮�濮嬶紝channelId: {}, stream: {}", targetId, streamChangedHookParam.getStream());
+                                    logger.warn("[鍥芥爣绾ц仈] 璇煶鍠婅瘽 寮傚父锛屾湭鎵惧埌鍙戞祦淇℃伅锛� channelId: {}, stream: {}", targetId, hookData.getStream());
+                                    logger.info("[鍥芥爣绾ц仈] 璇煶鍠婅瘽 閲嶆柊寮�濮嬶紝channelId: {}, stream: {}", targetId, hookData.getStream());
                                     try {
-                                        playService.audioBroadcastCmd(device, targetId, mediaServerItem, streamChangedHookParam.getApp(), streamChangedHookParam.getStream(), 60, true, msg -> {
+                                        playService.audioBroadcastCmd(device, targetId, hookData.getMediaServer(), hookData.getApp(), hookData.getStream(), 60, true, msg -> {
                                             logger.info("[璇煶鍠婅瘽] 閫氶亾寤虹珛鎴愬姛, device: {}, channel: {}", device.getDeviceId(), targetId);
                                         });
                                     } catch (SipException | InvalidArgumentException | ParseException e) {
@@ -157,7 +156,7 @@
                                     }
                                 }else {
                                     // 鍙戞祦
-                                    JSONObject jsonObject = zlmServerFactory.startSendRtp(mediaServerItem, sendRtpItem);
+                                    JSONObject jsonObject = zlmServerFactory.startSendRtp(hookData.getMediaServer(), sendRtpItem);
                                     if (jsonObject != null && jsonObject.getInteger("code") == 0 ) {
                                         logger.info("[璇煶鍠婅瘽] 鑷姩鎺ㄦ祦鎴愬姛, device: {}, channel: {}", device.getDeviceId(), targetId);
                                     }else {
@@ -167,7 +166,7 @@
                             }
                         }else {
                             try {
-                                playService.audioBroadcastCmd(device, targetId, mediaServerItem, streamChangedHookParam.getApp(), streamChangedHookParam.getStream(), 60, true, msg -> {
+                                playService.audioBroadcastCmd(device, targetId, hookData.getMediaServer(), hookData.getApp(), hookData.getStream(), 60, true, msg -> {
                                     logger.info("[璇煶鍠婅瘽] 閫氶亾寤虹珛鎴愬姛, device: {}, channel: {}", device.getDeviceId(), targetId);
                                 });
                             } catch (SipException | InvalidArgumentException | ParseException e) {
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 b11b9a8..f8ff69c 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
@@ -13,9 +13,9 @@
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
 import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler;
+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.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.service.IInviteStreamService;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
@@ -106,9 +106,8 @@
                     logger.error("[褰曞儚娴乚鎺ㄩ�佸畬姣曪紝鏀跺埌鍏虫祦閫氱煡锛� 鍙戦�丅YE澶辫触 {}", e.getMessage());
                 }
                 // 鍘婚櫎鐩戝惉娴佹敞閿�鑷姩鍋滄涓嬭浇鐨勭洃鍚�
-                HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcTransaction.getStream(), false, "rtsp", ssrcTransaction.getMediaServerId());
-                subscribe.removeSubscribe(hookSubscribe);
-
+                Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId());
+                subscribe.removeSubscribe(hook);
                 // 濡傛灉绾ц仈鎾斁锛岄渶瑕佺粰涓婄骇鍙戦�佹閫氱煡 TODO 澶氫釜涓婄骇鍚屾椂瑙傜湅涓�涓笅绾� 鍙兘瀛樺湪鍋滈敊鐨勯棶棰橈紝闇�瑕佸皢鐐规挱CallId杩涜涓婁笅绾х粦瀹�
                 SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(null, ssrcTransaction.getChannelId(), null, null);
                 if (sendRtpItem != null) {
diff --git a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java
index 942f63a..4eb1041 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/MediaServerConfig.java
@@ -1,7 +1,7 @@
 package com.genersoft.iot.vmp.media;
 
 import com.genersoft.iot.vmp.conf.MediaConfig;
-import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import org.slf4j.Logger;
diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java
index dcb4655..62015dc 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java
@@ -8,8 +8,8 @@
 import com.genersoft.iot.vmp.media.abl.bean.ConfigKeyId;
 import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent;
 import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent;
-import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent;
-import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import org.slf4j.Logger;
@@ -20,11 +20,8 @@
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
-import org.springframework.util.ObjectUtils;
 
-import java.io.File;
 import java.lang.reflect.Field;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java
index 2cc9943..e753fb6 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaInfo.java
@@ -2,6 +2,7 @@
 
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import io.swagger.v3.oas.annotations.media.Schema;
 
@@ -12,6 +13,15 @@
  */
 @Schema(description = "瑙嗛淇℃伅")
 public class MediaInfo {
+    @Schema(description = "搴旂敤鍚�")
+    private String app;
+    @Schema(description = "娴両D")
+    private String stream;
+    @Schema(description = "娴佸獟浣撹妭鐐�")
+    private MediaServer mediaServer;
+    @Schema(description = "鍗忚")
+    private String schema;
+
     @Schema(description = "瑙傜湅浜烘暟")
     private Integer readerCount;
     @Schema(description = "瑙嗛缂栫爜绫诲瀷")
@@ -37,8 +47,15 @@
     @Schema(description = "鏁版嵁浜х敓閫熷害锛屽崟浣峛yte/s")
     private Long bytesSpeed;
 
-    public static MediaInfo getInstance(JSONObject jsonObject) {
+    public static MediaInfo getInstance(JSONObject jsonObject, MediaServer mediaServer) {
         MediaInfo mediaInfo = new MediaInfo();
+        mediaInfo.setMediaServer(mediaServer);
+        String app = jsonObject.getString("app");
+        mediaInfo.setApp(app);
+        String stream = jsonObject.getString("stream");
+        mediaInfo.setStream(stream);
+        String schema = jsonObject.getString("schema");
+        mediaInfo.setSchema(schema);
         Integer totalReaderCount = jsonObject.getInteger("totalReaderCount");
         Boolean online = jsonObject.getBoolean("online");
         Integer originType = jsonObject.getInteger("originType");
@@ -110,9 +127,13 @@
         return mediaInfo;
     }
 
-    public static MediaInfo getInstance(OnStreamChangedHookParam param) {
+    public static MediaInfo getInstance(OnStreamChangedHookParam param, MediaServer mediaServer) {
         List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
         MediaInfo mediaInfo = new MediaInfo();
+        mediaInfo.setApp(param.getApp());
+        mediaInfo.setStream(param.getStream());
+        mediaInfo.setSchema(param.getSchema());
+        mediaInfo.setMediaServer(mediaServer);
         mediaInfo.setReaderCount(param.getTotalReaderCount());
         mediaInfo.setOnline(param.isRegist());
         mediaInfo.setOriginType(param.getOriginType());
@@ -247,4 +268,36 @@
     public void setBytesSpeed(Long bytesSpeed) {
         this.bytesSpeed = bytesSpeed;
     }
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public String getStream() {
+        return stream;
+    }
+
+    public void setStream(String stream) {
+        this.stream = stream;
+    }
+
+    public MediaServer getMediaServer() {
+        return mediaServer;
+    }
+
+    public void setMediaServer(MediaServer mediaServer) {
+        this.mediaServer = mediaServer;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public void setSchema(String schema) {
+        this.schema = schema;
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java
new file mode 100644
index 0000000..aafc5db
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/bean/RecordInfo.java
@@ -0,0 +1,92 @@
+package com.genersoft.iot.vmp.media.bean;
+
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
+
+public class RecordInfo {
+    private String fileName;
+    private String filePath;
+    private long fileSize;
+    private String folder;
+    private String url;
+    private long startTime;
+    private double timeLen;
+
+    public static RecordInfo getInstance(OnRecordMp4HookParam hookParam) {
+        RecordInfo recordInfo = new RecordInfo();
+        recordInfo.setFileName(hookParam.getFile_name());
+        recordInfo.setUrl(hookParam.getUrl());
+        recordInfo.setFolder(hookParam.getFolder());
+        recordInfo.setFilePath(hookParam.getFile_path());
+        recordInfo.setFileSize(hookParam.getFile_size());
+        recordInfo.setStartTime(hookParam.getStart_time());
+        recordInfo.setTimeLen(hookParam.getTime_len());
+        return recordInfo;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public long getFileSize() {
+        return fileSize;
+    }
+
+    public void setFileSize(long fileSize) {
+        this.fileSize = fileSize;
+    }
+
+    public String getFolder() {
+        return folder;
+    }
+
+    public void setFolder(String folder) {
+        this.folder = folder;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(long startTime) {
+        this.startTime = startTime;
+    }
+
+    public double getTimeLen() {
+        return timeLen;
+    }
+
+    public void setTimeLen(double timeLen) {
+        this.timeLen = timeLen;
+    }
+
+    @Override
+    public String toString() {
+        return "RecordInfo{" +
+                "鏂囦欢鍚嶇О='" + fileName + '\'' +
+                ", 鏂囦欢璺緞='" + filePath + '\'' +
+                ", 鏂囦欢澶у皬=" + fileSize +
+                ", 寮�濮嬫椂闂�=" + startTime +
+                ", 鏃堕暱=" + timeLen +
+                '}';
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java
deleted file mode 100644
index b70fcf7..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaArrivalEvent.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.genersoft.iot.vmp.media.event;
-
-import com.genersoft.iot.vmp.media.bean.MediaInfo;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
-import org.springframework.context.ApplicationEvent;
-
-/**
- * 娴佸埌鏉ヤ簨浠�
- */
-public class MediaArrivalEvent extends ApplicationEvent {
-    public MediaArrivalEvent(Object source) {
-        super(source);
-    }
-
-    public static MediaArrivalEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){
-        MediaArrivalEvent mediaArrivalEvent = new MediaArrivalEvent(source);
-        mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam));
-        mediaArrivalEvent.setApp(hookParam.getApp());
-        mediaArrivalEvent.setStream(hookParam.getStream());
-        mediaArrivalEvent.setMediaServer(mediaServer);
-        mediaArrivalEvent.setSchema(hookParam.getSchema());
-        mediaArrivalEvent.setCallId(hookParam.getCallId());
-        return mediaArrivalEvent;
-    }
-
-    private MediaInfo mediaInfo;
-
-    private String app;
-
-    private String stream;
-
-    private MediaServer mediaServer;
-
-    private String schema;
-
-    private String callId;
-
-    public MediaInfo getMediaInfo() {
-        return mediaInfo;
-    }
-
-    public void setMediaInfo(MediaInfo mediaInfo) {
-        this.mediaInfo = mediaInfo;
-    }
-
-    public String getApp() {
-        return app;
-    }
-
-    public void setApp(String app) {
-        this.app = app;
-    }
-
-    public String getStream() {
-        return stream;
-    }
-
-    public void setStream(String stream) {
-        this.stream = stream;
-    }
-
-    public MediaServer getMediaServer() {
-        return mediaServer;
-    }
-
-    public void setMediaServer(MediaServer mediaServer) {
-        this.mediaServer = mediaServer;
-    }
-
-    public String getSchema() {
-        return schema;
-    }
-
-    public void setSchema(String schema) {
-        this.schema = schema;
-    }
-
-    public String getCallId() {
-        return callId;
-    }
-
-    public void setCallId(String callId) {
-        this.callId = callId;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java
deleted file mode 100644
index f111385..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaDepartureEvent.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.genersoft.iot.vmp.media.event;
-
-import com.genersoft.iot.vmp.media.bean.MediaInfo;
-import com.genersoft.iot.vmp.media.zlm.ZLMHttpHookListener;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
-import org.springframework.context.ApplicationEvent;
-
-/**
- * 娴佺寮�浜嬩欢
- */
-public class MediaDepartureEvent extends ApplicationEvent {
-    public MediaDepartureEvent(Object source) {
-        super(source);
-    }
-
-    private String app;
-
-    private String stream;
-
-    private MediaServer mediaServer;
-
-    private String schema;
-
-    public static MediaDepartureEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){
-        MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source);
-        mediaDepartureEven.setApp(hookParam.getApp());
-        mediaDepartureEven.setStream(hookParam.getStream());
-        mediaDepartureEven.setSchema(hookParam.getSchema());
-        mediaDepartureEven.setMediaServer(mediaServer);
-        return mediaDepartureEven;
-    }
-
-    public String getApp() {
-        return app;
-    }
-
-    public void setApp(String app) {
-        this.app = app;
-    }
-
-    public String getStream() {
-        return stream;
-    }
-
-    public void setStream(String stream) {
-        this.stream = stream;
-    }
-
-    public MediaServer getMediaServer() {
-        return mediaServer;
-    }
-
-    public void setMediaServer(MediaServer mediaServer) {
-        this.mediaServer = mediaServer;
-    }
-
-    public String getSchema() {
-        return schema;
-    }
-
-    public void setSchema(String schema) {
-        this.schema = schema;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java
deleted file mode 100644
index 2f8a840..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaNotFoundEvent.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.genersoft.iot.vmp.media.event;
-
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam;
-import org.springframework.context.ApplicationEvent;
-
-/**
- * 娴佹湭鎵惧埌
- */
-public class MediaNotFoundEvent extends ApplicationEvent {
-    public MediaNotFoundEvent(Object source) {
-        super(source);
-    }
-
-    private String app;
-
-    private String stream;
-
-    private MediaServer mediaServer;
-
-    private String schema;
-
-    public static MediaNotFoundEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){
-        MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source);
-        mediaDepartureEven.setApp(hookParam.getApp());
-        mediaDepartureEven.setStream(hookParam.getStream());
-        mediaDepartureEven.setSchema(hookParam.getSchema());
-        mediaDepartureEven.setMediaServer(mediaServer);
-        return mediaDepartureEven;
-    }
-
-    public String getApp() {
-        return app;
-    }
-
-    public void setApp(String app) {
-        this.app = app;
-    }
-
-    public String getStream() {
-        return stream;
-    }
-
-    public void setStream(String stream) {
-        this.stream = stream;
-    }
-
-    public MediaServer getMediaServer() {
-        return mediaServer;
-    }
-
-    public void setMediaServer(MediaServer mediaServer) {
-        this.mediaServer = mediaServer;
-    }
-
-    public String getSchema() {
-        return schema;
-    }
-
-    public void setSchema(String schema) {
-        this.schema = schema;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java
deleted file mode 100644
index ca01142..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaRtpServerTimeoutEvent.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.genersoft.iot.vmp.media.event;
-
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam;
-import org.springframework.context.ApplicationEvent;
-
-/**
- * rtp 鏈嶅姟鏀舵祦瓒呮椂閫氱煡
- */
-public class MediaRtpServerTimeoutEvent extends ApplicationEvent {
-    public MediaRtpServerTimeoutEvent(Object source) {
-        super(source);
-    }
-
-    private String app;
-
-    private String stream;
-
-    private MediaServer mediaServer;
-
-    public static MediaRtpServerTimeoutEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){
-        MediaRtpServerTimeoutEvent mediaDepartureEven = new MediaRtpServerTimeoutEvent(source);
-        mediaDepartureEven.setApp(hookParam.getApp());
-        mediaDepartureEven.setStream(hookParam.getStream());
-        mediaDepartureEven.setMediaServer(mediaServer);
-        return mediaDepartureEven;
-    }
-
-    public String getApp() {
-        return app;
-    }
-
-    public void setApp(String app) {
-        this.app = app;
-    }
-
-    public String getStream() {
-        return stream;
-    }
-
-    public void setStream(String stream) {
-        this.stream = stream;
-    }
-
-    public MediaServer getMediaServer() {
-        return mediaServer;
-    }
-
-    public void setMediaServer(MediaServer mediaServer) {
-        this.mediaServer = mediaServer;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java
new file mode 100755
index 0000000..a0dc7c3
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/Hook.java
@@ -0,0 +1,86 @@
+package com.genersoft.iot.vmp.media.event.hook;
+
+/**
+ * zlm hook浜嬩欢鐨勫弬鏁�
+ * @author lin
+ */
+public class Hook {
+
+    private HookType hookType;
+
+    private String app;
+
+    private String stream;
+
+    private String mediaServerId;
+
+    private Long createTime;
+
+    public static Hook getInstance(HookType hookType, String app, String stream, String mediaServerId) {
+        Hook hookSubscribe = new Hook();
+        hookSubscribe.setApp(app);
+        hookSubscribe.setStream(stream);
+        hookSubscribe.setHookType(hookType);
+        hookSubscribe.setMediaServerId(mediaServerId);
+        hookSubscribe.setCreateTime(System.currentTimeMillis());
+        return hookSubscribe;
+    }
+
+    public HookType getHookType() {
+        return hookType;
+    }
+
+    public void setHookType(HookType hookType) {
+        this.hookType = hookType;
+    }
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public String getStream() {
+        return stream;
+    }
+
+    public void setStream(String stream) {
+        this.stream = stream;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getMediaServerId() {
+        return mediaServerId;
+    }
+
+    public void setMediaServerId(String mediaServerId) {
+        this.mediaServerId = mediaServerId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Hook) {
+            Hook param = (Hook) obj;
+            return param.getHookType().equals(this.hookType)
+                    && param.getApp().equals(this.app)
+                    && param.getStream().equals(this.stream)
+                    && param.getMediaServerId().equals(this.mediaServerId);
+        }else {
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return this.getHookType() + this.getApp() + this.getStream() + this.getMediaServerId();
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java
new file mode 100644
index 0000000..25c02de
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookData.java
@@ -0,0 +1,132 @@
+package com.genersoft.iot.vmp.media.event.hook;
+
+import com.genersoft.iot.vmp.media.bean.MediaInfo;
+import com.genersoft.iot.vmp.media.bean.RecordInfo;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import io.swagger.v3.oas.annotations.media.Schema;
+
+/**
+ * Hook杩斿洖鐨勫唴瀹�
+ */
+public class HookData {
+    /**
+     * 搴旂敤鍚�
+     */
+    private String app;
+    /**
+     * 娴両D
+     */
+    private String stream;
+    /**
+     * 娴佸獟浣撹妭鐐�
+     */
+    private MediaServer mediaServer;
+    /**
+     * 鍗忚
+     */
+    private String schema;
+
+    /**
+     * 娴佷俊鎭�
+     */
+    private MediaInfo mediaInfo;
+
+    /**
+     * 褰曞儚淇℃伅
+     */
+    private RecordInfo recordInfo;
+
+    @Schema(description = "鎺ㄦ祦鐨勯澶栧弬鏁�")
+    private String params;
+    public static HookData getInstance(MediaEvent mediaEvent) {
+        HookData hookData = new HookData();
+        if (mediaEvent instanceof MediaPublishEvent) {
+            MediaPublishEvent event = (MediaPublishEvent) mediaEvent;
+            hookData.setApp(event.getApp());
+            hookData.setStream(event.getStream());
+            hookData.setSchema(event.getSchema());
+            hookData.setMediaServer(event.getMediaServer());
+            hookData.setParams(event.getParams());
+        }else if (mediaEvent instanceof MediaArrivalEvent) {
+            MediaArrivalEvent event = (MediaArrivalEvent) mediaEvent;
+            hookData.setApp(event.getApp());
+            hookData.setStream(event.getStream());
+            hookData.setSchema(event.getSchema());
+            hookData.setMediaServer(event.getMediaServer());
+            hookData.setMediaInfo(event.getMediaInfo());
+        }else if (mediaEvent instanceof MediaRecordMp4Event) {
+            MediaRecordMp4Event event = (MediaRecordMp4Event) mediaEvent;
+            hookData.setApp(event.getApp());
+            hookData.setStream(event.getStream());
+            hookData.setSchema(event.getSchema());
+            hookData.setMediaServer(event.getMediaServer());
+            hookData.setRecordInfo(event.getRecordInfo());
+        }else {
+            hookData.setApp(mediaEvent.getApp());
+            hookData.setStream(mediaEvent.getStream());
+            hookData.setSchema(mediaEvent.getSchema());
+            hookData.setMediaServer(mediaEvent.getMediaServer());
+        }
+        return hookData;
+    }
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public String getStream() {
+        return stream;
+    }
+
+    public void setStream(String stream) {
+        this.stream = stream;
+    }
+
+    public MediaServer getMediaServer() {
+        return mediaServer;
+    }
+
+    public void setMediaServer(MediaServer mediaServer) {
+        this.mediaServer = mediaServer;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public void setSchema(String schema) {
+        this.schema = schema;
+    }
+
+    public MediaInfo getMediaInfo() {
+        return mediaInfo;
+    }
+
+    public void setMediaInfo(MediaInfo mediaInfo) {
+        this.mediaInfo = mediaInfo;
+    }
+
+    public String getParams() {
+        return params;
+    }
+
+    public void setParams(String params) {
+        this.params = params;
+    }
+
+    public RecordInfo getRecordInfo() {
+        return recordInfo;
+    }
+
+    public void setRecordInfo(RecordInfo recordInfo) {
+        this.recordInfo = recordInfo;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java
index f5dac01..64b8ffe 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribe.java
@@ -1,172 +1,105 @@
 package com.genersoft.iot.vmp.media.event.hook;
 
-import com.alibaba.fastjson2.JSONObject;
-import com.genersoft.iot.vmp.media.event.MediaArrivalEvent;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+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.MediaEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaPublishEvent;
+import org.mybatis.logging.Logger;
+import org.mybatis.logging.LoggerFactory;
+import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
 
 import java.time.Instant;
-import java.util.*;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
 
 /**
- * ZLMediaServer鐨刪ook浜嬩欢璁㈤槄
+ * zlm hook浜嬩欢鐨勫弬鏁�
  * @author lin
  */
 @Component
 public class HookSubscribe {
 
-    private final static Logger logger = LoggerFactory.getLogger(HookSubscribe.class);
+    /**
+     * 璁㈤槄鏁版嵁杩囨湡鏃堕棿
+     */
+    private final long subscribeExpire = 5 * 1000;
 
     @FunctionalInterface
     public interface Event{
-        void response(MediaServer mediaServerItem, HookParam hookParam);
+        void response(HookData data);
     }
 
     /**
      * 娴佸埌鏉ョ殑澶勭悊
      */
     @Async("taskExecutor")
-    @org.springframework.context.event.EventListener
+    @EventListener
     public void onApplicationEvent(MediaArrivalEvent event) {
-        for (HookType hookType : allSubscribes.keySet()) {
-            if (hookType.equals(HookType.on_stream_changed)) {
-
-            }
-        }
-    }
-
-    private Map<HookType, Map<IHookSubscribe, HookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>();
-
-    public void addSubscribe(IHookSubscribe hookSubscribe, HookSubscribe.Event event) {
-        if (hookSubscribe.getExpires() == null) {
-            // 榛樿5鍒嗛挓杩囨湡
-            Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5));
-            hookSubscribe.setExpires(expiresInstant);
-        }
-        allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event);
-    }
-
-    public HookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) {
-        HookSubscribe.Event event= null;
-        Map<IHookSubscribe, Event> eventMap = allSubscribes.get(type);
-        if (eventMap == null) {
-            return null;
-        }
-        for (IHookSubscribe key : eventMap.keySet()) {
-            Boolean result = null;
-
-            for (String s : key.getContent().keySet()) {
-                if (result == null) {
-                    result = key.getContent().getString(s).equals(hookResponse.getString(s));
-                }else {
-                    if (key.getContent().getString(s) == null) {
-                        continue;
-                    }
-                    result = result && key.getContent().getString(s).equals(hookResponse.getString(s));
-                }
-            }
-            if (null != result && result) {
-                event = eventMap.get(key);
-            }
-        }
-        return event;
-    }
-
-    public void removeSubscribe(IHookSubscribe hookSubscribe) {
-        Map<IHookSubscribe, Event> eventMap = allSubscribes.get(hookSubscribe.getHookType());
-        if (eventMap == null) {
-            return;
+        if ("rtsp".equals(event.getSchema())) {
+            System.out.println("娴佸埌鏉ョ殑澶勭悊: " + allSubscribes.size());
+            sendNotify(HookType.on_media_arrival, event);
         }
 
-        Set<Map.Entry<IHookSubscribe, Event>> entries = eventMap.entrySet();
-        if (entries.size() > 0) {
-            List<Map.Entry<IHookSubscribe, HookSubscribe.Event>> entriesToRemove = new ArrayList<>();
-            for (Map.Entry<IHookSubscribe, HookSubscribe.Event> entry : entries) {
-                JSONObject content = entry.getKey().getContent();
-                if (content == null || content.size() == 0) {
-                    entriesToRemove.add(entry);
-                    continue;
-                }
-                Boolean result = null;
-                for (String s : content.keySet()) {
-                    if (result == null) {
-                        result = content.getString(s).equals(hookSubscribe.getContent().getString(s));
-                    }else {
-                        if (content.getString(s) == null) {
-                            continue;
-                        }
-                        result = result && content.getString(s).equals(hookSubscribe.getContent().getString(s));
-                    }
-                }
-                if (result){
-                    entriesToRemove.add(entry);
-                }
-            }
-
-            if (!CollectionUtils.isEmpty(entriesToRemove)) {
-                for (Map.Entry<IHookSubscribe, HookSubscribe.Event> entry : entriesToRemove) {
-                    eventMap.remove(entry.getKey());
-                }
-                if (eventMap.size() == 0) {
-                    allSubscribes.remove(hookSubscribe.getHookType());
-                }
-            }
-
-        }
     }
 
     /**
-     * 鑾峰彇鏌愪釜绫诲瀷鐨勬墍鏈夌殑璁㈤槄
-     * @param type
-     * @return
+     * 娴佺粨鏉熶簨浠�
      */
-    public List<HookSubscribe.Event> getSubscribes(HookType type) {
-        Map<IHookSubscribe, Event> eventMap = allSubscribes.get(type);
-        if (eventMap == null) {
-            return null;
+    @Async("taskExecutor")
+    @EventListener
+    public void onApplicationEvent(MediaDepartureEvent event) {
+        if ("rtsp".equals(event.getSchema())) {
+            sendNotify(HookType.on_media_departure, event);
         }
-        List<HookSubscribe.Event> result = new ArrayList<>();
-        for (IHookSubscribe key : eventMap.keySet()) {
-            result.add(eventMap.get(key));
-        }
-        return result;
+
+    }
+    /**
+     * 鎺ㄦ祦閴存潈浜嬩欢
+     */
+    @Async("taskExecutor")
+    @EventListener
+    public void onApplicationEvent(MediaPublishEvent event) {
+        sendNotify(HookType.on_publish, event);
     }
 
-    public List<IHookSubscribe> getAll(){
-        ArrayList<IHookSubscribe> result = new ArrayList<>();
-        Collection<Map<IHookSubscribe, Event>> values = allSubscribes.values();
-        for (Map<IHookSubscribe, Event> value : values) {
-            result.addAll(value.keySet());
+    private final Map<String, Event> allSubscribes = new ConcurrentHashMap<>();
+    private final Map<String, Hook> allHook = new ConcurrentHashMap<>();
+
+    private void sendNotify(HookType hookType, MediaEvent event) {
+        Hook paramHook = Hook.getInstance(hookType, event.getApp(), event.getStream(), event.getMediaServer().getId());
+        Event hookSubscribeEvent = allSubscribes.get(paramHook.toString());
+        if (hookSubscribeEvent != null) {
+            HookData data = HookData.getInstance(event);
+            hookSubscribeEvent.response(data);
         }
-        return result;
+    }
+
+    public void addSubscribe(Hook hook, HookSubscribe.Event event) {
+        if (hook.getCreateTime() == null) {
+            hook.setCreateTime(System.currentTimeMillis());
+        }
+        allSubscribes.put(hook.toString(), event);
+        allHook.put(hook.toString(), hook);
+    }
+
+    public void removeSubscribe(Hook hook) {
+        allSubscribes.remove(hook.toString());
+        allHook.remove(hook.toString());
     }
 
     /**
      * 瀵硅闃呮暟鎹繘琛岃繃鏈熸竻鐞�
      */
-//    @Scheduled(cron="0 0/5 * * * ?")   //姣�5鍒嗛挓鎵ц涓�娆�
-    @Scheduled(fixedRate = 2 * 1000)
+    @Scheduled(fixedRate=subscribeExpire)   //姣�5鍒嗛挓鎵ц涓�娆�
     public void execute(){
-        Instant instant = Instant.now().minusMillis(TimeUnit.MINUTES.toMillis(5));
-        int total = 0;
-        for (HookType hookType : allSubscribes.keySet()) {
-            Map<IHookSubscribe, Event> hookSubscribeEventMap = allSubscribes.get(hookType);
-            if (hookSubscribeEventMap.size() > 0) {
-                for (IHookSubscribe hookSubscribe : hookSubscribeEventMap.keySet()) {
-                    if (hookSubscribe.getExpires().isBefore(instant)) {
-                        // 杩囨湡鐨�
-                        hookSubscribeEventMap.remove(hookSubscribe);
-                        total ++;
-                    }
-                }
+        long expireTime = System.currentTimeMillis() - subscribeExpire;
+        for (Hook hook : allHook.values()) {
+            if (hook.getCreateTime() < expireTime) {
+                allSubscribes.remove(hook.toString());
+                allHook.remove(hook.toString());
             }
         }
     }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java
deleted file mode 100755
index 9182205..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeFactory.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.genersoft.iot.vmp.media.event.hook;
-
-
-import com.alibaba.fastjson2.JSONObject;
-
-/**
- * hook 璁㈤槄宸ュ巶
- * @author lin
- */
-public class HookSubscribeFactory {
-
-    public static HookSubscribeForStreamChange on_stream_changed(String app, String stream, boolean regist, String scheam, String mediaServerId) {
-        HookSubscribeForStreamChange hookSubscribe = new HookSubscribeForStreamChange();
-        JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject();
-        subscribeKey.put("app", app);
-        subscribeKey.put("stream", stream);
-        subscribeKey.put("regist", regist);
-        if (scheam != null) {
-            subscribeKey.put("schema", scheam);
-        }
-        subscribeKey.put("mediaServerId", mediaServerId);
-        hookSubscribe.setContent(subscribeKey);
-
-        return hookSubscribe;
-    }
-
-    public static HookSubscribeForRtpServerTimeout on_rtp_server_timeout(String stream, String ssrc, String mediaServerId) {
-        HookSubscribeForRtpServerTimeout hookSubscribe = new HookSubscribeForRtpServerTimeout();
-        JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject();
-        subscribeKey.put("stream_id", stream);
-        subscribeKey.put("ssrc", ssrc);
-        subscribeKey.put("mediaServerId", mediaServerId);
-        hookSubscribe.setContent(subscribeKey);
-        return hookSubscribe;
-    }
-
-    public static HookSubscribeForStreamPush on_publish(String app, String stream, String scheam, String mediaServerId) {
-        HookSubscribeForStreamPush hookSubscribe = new HookSubscribeForStreamPush();
-        JSONObject subscribeKey = new JSONObject();
-        subscribeKey.put("app", app);
-        subscribeKey.put("stream", stream);
-        if (scheam != null) {
-            subscribeKey.put("schema", scheam);
-        }
-        subscribeKey.put("mediaServerId", mediaServerId);
-        hookSubscribe.setContent(subscribeKey);
-
-        return hookSubscribe;
-    }
-
-    public static HookSubscribeForRecordMp4 on_record_mp4(String mediaServerId, String app, String stream) {
-        HookSubscribeForRecordMp4 hookSubscribe = new HookSubscribeForRecordMp4();
-        JSONObject subscribeKey = new com.alibaba.fastjson2.JSONObject();
-        subscribeKey.put("app", app);
-        subscribeKey.put("stream", stream);
-        subscribeKey.put("mediaServerId", mediaServerId);
-        hookSubscribe.setContent(subscribeKey);
-
-        return hookSubscribe;
-    }
-
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java
deleted file mode 100755
index 46f62a8..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRecordMp4.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.genersoft.iot.vmp.media.event.hook;
-
-import com.alibaba.fastjson2.JSONObject;
-import com.alibaba.fastjson2.annotation.JSONField;
-
-import java.time.Instant;
-
-/**
- * hook璁㈤槄-褰曞儚瀹屾垚
- * @author lin
- */
-public class HookSubscribeForRecordMp4 implements IHookSubscribe{
-
-    private HookType hookType = HookType.on_record_mp4;
-
-    private JSONObject content;
-
-    @JSONField(format="yyyy-MM-dd HH:mm:ss")
-    private Instant expires;
-
-    @Override
-    public HookType getHookType() {
-        return hookType;
-    }
-
-    @Override
-    public JSONObject getContent() {
-        return content;
-    }
-
-    public void setContent(JSONObject content) {
-        this.content = content;
-    }
-
-    @Override
-    public Instant getExpires() {
-        return expires;
-    }
-
-    @Override
-    public void setExpires(Instant expires) {
-        this.expires = expires;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java
deleted file mode 100755
index d526c78..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForRtpServerTimeout.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.genersoft.iot.vmp.media.event.hook;
-
-import com.alibaba.fastjson2.JSONObject;
-import com.alibaba.fastjson2.annotation.JSONField;
-
-import java.time.Instant;
-
-/**
- * hook璁㈤槄-鏀舵祦瓒呮椂
- * @author lin
- */
-public class HookSubscribeForRtpServerTimeout implements IHookSubscribe{
-
-    private HookType hookType = HookType.on_rtp_server_timeout;
-
-    private JSONObject content;
-
-    @JSONField(format="yyyy-MM-dd HH:mm:ss")
-    private Instant expires;
-
-    @Override
-    public HookType getHookType() {
-        return hookType;
-    }
-
-    @Override
-    public JSONObject getContent() {
-        return content;
-    }
-
-    public void setContent(JSONObject content) {
-        this.content = content;
-    }
-
-    @Override
-    public Instant getExpires() {
-        return expires;
-    }
-
-    @Override
-    public void setExpires(Instant expires) {
-        this.expires = expires;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java
deleted file mode 100755
index b8d2675..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamChange.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.genersoft.iot.vmp.media.event.hook;
-
-import com.alibaba.fastjson2.JSONObject;
-import com.alibaba.fastjson2.annotation.JSONField;
-
-import java.time.Instant;
-
-/**
- * hook璁㈤槄-娴佸彉鍖�
- * @author lin
- */
-public class HookSubscribeForStreamChange implements IHookSubscribe{
-
-    private HookType hookType = HookType.on_stream_changed;
-
-    private JSONObject content;
-
-    @JSONField(format="yyyy-MM-dd HH:mm:ss")
-    private Instant expires;
-
-    @Override
-    public HookType getHookType() {
-        return hookType;
-    }
-
-    @Override
-    public JSONObject getContent() {
-        return content;
-    }
-
-    public void setContent(JSONObject content) {
-        this.content = content;
-    }
-
-    @Override
-    public Instant getExpires() {
-        return expires;
-    }
-
-    @Override
-    public void setExpires(Instant expires) {
-        this.expires = expires;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java
deleted file mode 100644
index e619181..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookSubscribeForStreamPush.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.genersoft.iot.vmp.media.event.hook;
-
-
-import com.alibaba.fastjson2.JSONObject;
-
-import java.time.Instant;
-
-/**
- * hook璁㈤槄-寮�濮嬫帹娴�
- * @author lin
- */
-public class HookSubscribeForStreamPush implements IHookSubscribe{
-
-    private HookType hookType = HookType.on_publish;
-
-    private JSONObject content;
-
-    private Instant expires;
-
-    @Override
-    public HookType getHookType() {
-        return hookType;
-    }
-
-    @Override
-    public JSONObject getContent() {
-        return content;
-    }
-
-    public void setContent(JSONObject content) {
-        this.content = content;
-    }
-
-    @Override
-    public Instant getExpires() {
-        return expires;
-    }
-
-    @Override
-    public void setExpires(Instant expires) {
-        this.expires = expires;
-    }
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java
index 77e37a8..58bd656 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/hook/HookType.java
@@ -10,6 +10,6 @@
     on_publish,
     on_record_mp4,
     on_media_arrival,
-    on_stream_changed,
+    on_media_departure,
     on_rtp_server_timeout,
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java b/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java
deleted file mode 100755
index 7fb48ce..0000000
--- a/src/main/java/com/genersoft/iot/vmp/media/event/hook/IHookSubscribe.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.genersoft.iot.vmp.media.event.hook;
-
-import com.alibaba.fastjson2.JSONObject;
-
-import java.time.Instant;
-
-/**
- * zlm hook浜嬩欢鐨勫弬鏁�
- * @author lin
- */
-public interface IHookSubscribe {
-
-    /**
-     * 鑾峰彇hook绫诲瀷
-     * @return hook绫诲瀷
-     */
-    HookType getHookType();
-
-    /**
-     * 鑾峰彇hook鐨勫叿浣撳唴瀹�
-     * @return hook鐨勫叿浣撳唴瀹�
-     */
-    JSONObject getContent();
-
-    /**
-     * 璁剧疆杩囨湡鏃堕棿
-     * @param instant 杩囨湡鏃堕棿
-     */
-    void setExpires(Instant instant);
-
-    /**
-     * 鑾峰彇杩囨湡鏃堕棿
-     * @return 杩囨湡鏃堕棿
-     */
-    Instant getExpires();
-}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java
new file mode 100644
index 0000000..af1e23e
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaArrivalEvent.java
@@ -0,0 +1,46 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.bean.MediaInfo;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+
+/**
+ * 娴佸埌鏉ヤ簨浠�
+ */
+public class MediaArrivalEvent extends MediaEvent {
+    public MediaArrivalEvent(Object source) {
+        super(source);
+    }
+
+    public static MediaArrivalEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){
+        MediaArrivalEvent mediaArrivalEvent = new MediaArrivalEvent(source);
+        mediaArrivalEvent.setMediaInfo(MediaInfo.getInstance(hookParam, mediaServer));
+        mediaArrivalEvent.setApp(hookParam.getApp());
+        mediaArrivalEvent.setStream(hookParam.getStream());
+        mediaArrivalEvent.setMediaServer(mediaServer);
+        mediaArrivalEvent.setSchema(hookParam.getSchema());
+        mediaArrivalEvent.setCallId(hookParam.getCallId());
+        return mediaArrivalEvent;
+    }
+
+    private MediaInfo mediaInfo;
+
+    private String callId;
+
+    public MediaInfo getMediaInfo() {
+        return mediaInfo;
+    }
+
+    public void setMediaInfo(MediaInfo mediaInfo) {
+        this.mediaInfo = mediaInfo;
+    }
+
+
+    public String getCallId() {
+        return callId;
+    }
+
+    public void setCallId(String callId) {
+        this.callId = callId;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java
new file mode 100644
index 0000000..5cf87de
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaDepartureEvent.java
@@ -0,0 +1,22 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+
+/**
+ * 娴佺寮�浜嬩欢
+ */
+public class MediaDepartureEvent extends MediaEvent {
+    public MediaDepartureEvent(Object source) {
+        super(source);
+    }
+
+    public static MediaDepartureEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){
+        MediaDepartureEvent mediaDepartureEven = new MediaDepartureEvent(source);
+        mediaDepartureEven.setApp(hookParam.getApp());
+        mediaDepartureEven.setStream(hookParam.getStream());
+        mediaDepartureEven.setSchema(hookParam.getSchema());
+        mediaDepartureEven.setMediaServer(mediaServer);
+        return mediaDepartureEven;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java
new file mode 100644
index 0000000..54d0a42
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaEvent.java
@@ -0,0 +1,58 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.bean.MediaInfo;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * 娴佸埌鏉ヤ簨浠�
+ */
+public class MediaEvent extends ApplicationEvent {
+
+    public MediaEvent(Object source) {
+        super(source);
+    }
+
+    private String app;
+
+    private String stream;
+
+    private MediaServer mediaServer;
+
+    private String schema;
+
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public String getStream() {
+        return stream;
+    }
+
+    public void setStream(String stream) {
+        this.stream = stream;
+    }
+
+    public MediaServer getMediaServer() {
+        return mediaServer;
+    }
+
+    public void setMediaServer(MediaServer mediaServer) {
+        this.mediaServer = mediaServer;
+    }
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public void setSchema(String schema) {
+        this.schema = schema;
+    }
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java
new file mode 100644
index 0000000..b45f55e
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaNotFoundEvent.java
@@ -0,0 +1,22 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam;
+
+/**
+ * 娴佹湭鎵惧埌
+ */
+public class MediaNotFoundEvent extends MediaEvent {
+    public MediaNotFoundEvent(Object source) {
+        super(source);
+    }
+
+    public static MediaNotFoundEvent getInstance(Object source, OnStreamNotFoundHookParam hookParam, MediaServer mediaServer){
+        MediaNotFoundEvent mediaDepartureEven = new MediaNotFoundEvent(source);
+        mediaDepartureEven.setApp(hookParam.getApp());
+        mediaDepartureEven.setStream(hookParam.getStream());
+        mediaDepartureEven.setSchema(hookParam.getSchema());
+        mediaDepartureEven.setMediaServer(mediaServer);
+        return mediaDepartureEven;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java
new file mode 100644
index 0000000..b50f896
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaPublishEvent.java
@@ -0,0 +1,33 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnPublishHookParam;
+
+/**
+ * 鎺ㄦ祦閴存潈浜嬩欢
+ */
+public class MediaPublishEvent extends MediaEvent {
+    public MediaPublishEvent(Object source) {
+        super(source);
+    }
+
+    public static MediaPublishEvent getInstance(Object source, OnPublishHookParam hookParam, MediaServer mediaServer){
+        MediaPublishEvent mediaPublishEvent = new MediaPublishEvent(source);
+        mediaPublishEvent.setApp(hookParam.getApp());
+        mediaPublishEvent.setStream(hookParam.getStream());
+        mediaPublishEvent.setMediaServer(mediaServer);
+        mediaPublishEvent.setSchema(hookParam.getSchema());
+        mediaPublishEvent.setParams(hookParam.getParams());
+        return mediaPublishEvent;
+    }
+
+    private String params;
+
+    public String getParams() {
+        return params;
+    }
+
+    public void setParams(String params) {
+        this.params = params;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java
new file mode 100644
index 0000000..e4750c1
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRecordMp4Event.java
@@ -0,0 +1,36 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.bean.RecordInfo;
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+
+/**
+ * 褰曞儚鏂囦欢鐢熸垚浜嬩欢
+ */
+public class MediaRecordMp4Event extends MediaEvent {
+    public MediaRecordMp4Event(Object source) {
+        super(source);
+    }
+
+    private RecordInfo recordInfo;
+
+    public static MediaRecordMp4Event getInstance(Object source, OnRecordMp4HookParam hookParam, MediaServer mediaServer){
+        MediaRecordMp4Event mediaRecordMp4Event = new MediaRecordMp4Event(source);
+        mediaRecordMp4Event.setApp(hookParam.getApp());
+        mediaRecordMp4Event.setStream(hookParam.getStream());
+        RecordInfo recordInfo = RecordInfo.getInstance(hookParam);
+        mediaRecordMp4Event.setRecordInfo(recordInfo);
+        mediaRecordMp4Event.setMediaServer(mediaServer);
+        return mediaRecordMp4Event;
+    }
+
+    public RecordInfo getRecordInfo() {
+        return recordInfo;
+    }
+
+    public void setRecordInfo(RecordInfo recordInfo) {
+        this.recordInfo = recordInfo;
+    }
+
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java
new file mode 100644
index 0000000..939c852
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/media/MediaRtpServerTimeoutEvent.java
@@ -0,0 +1,22 @@
+package com.genersoft.iot.vmp.media.event.media;
+
+import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+
+/**
+ * RtpServer鏀舵祦瓒呮椂浜嬩欢
+ */
+public class MediaRtpServerTimeoutEvent extends MediaEvent {
+    public MediaRtpServerTimeoutEvent(Object source) {
+        super(source);
+    }
+
+    public static MediaRtpServerTimeoutEvent getInstance(Object source, OnStreamChangedHookParam hookParam, MediaServer mediaServer){
+        MediaRtpServerTimeoutEvent mediaDepartureEven = new MediaRtpServerTimeoutEvent(source);
+        mediaDepartureEven.setApp(hookParam.getApp());
+        mediaDepartureEven.setStream(hookParam.getStream());
+        mediaDepartureEven.setSchema(hookParam.getSchema());
+        mediaDepartureEven.setMediaServer(mediaServer);
+        return mediaDepartureEven;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java
similarity index 95%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java
index 9319280..c9679f7 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaSendRtpStoppedEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaSendRtpStoppedEvent.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamNotFoundHookParam;
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java
similarity index 94%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java
index 0da054f..e365045 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerChangeEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerChangeEvent.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import org.springframework.context.ApplicationEvent;
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java
similarity index 75%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java
index 10a368b..a716ff0 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerDeleteEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerDeleteEvent.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 /**
  * zlm鍦ㄧ嚎浜嬩欢
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java
similarity index 89%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java
index 91806f8..a9bf769 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerEventAbstract.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerEventAbstract.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 import org.springframework.context.ApplicationEvent;
 
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java
similarity index 61%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java
index ce3c5a9..2f9ac23 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOfflineEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOfflineEvent.java
@@ -1,6 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
-
-import com.genersoft.iot.vmp.media.event.MediaServerEventAbstract;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 /**
  * zlm绂荤嚎浜嬩欢绫�
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java
similarity index 60%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java
index 5d9bdc4..673dce4 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerOnlineEvent.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerOnlineEvent.java
@@ -1,6 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
-
-import com.genersoft.iot.vmp.media.event.MediaServerEventAbstract;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 /**
  * zlm鍦ㄧ嚎浜嬩欢
diff --git a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java
similarity index 96%
rename from src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java
rename to src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java
index 0d8e38c..2413f56 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/event/MediaServerStatusEventListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/event/mediaServer/MediaServerStatusEventListener.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.event;
+package com.genersoft.iot.vmp.media.event.mediaServer;
 
 import com.genersoft.iot.vmp.service.IPlayService;
 import com.genersoft.iot.vmp.service.IStreamProxyService;
diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java
index de095ea..4ec0bfe 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java
@@ -104,4 +104,36 @@
 
     Map<String, String> getFFmpegCMDs(MediaServer mediaServer);
 
+    /**
+     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 閫氳繃zlm鎺ュ彛妫�鏌ユ槸鍚﹀瓨鍦�
+     * @param app
+     * @param stream
+     * @return
+     */
+    StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr, boolean authority);
+
+
+    /**
+     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 閫氳繃zlm鎺ュ彛妫�鏌ユ槸鍚﹀瓨鍦�, 杩斿洖鐨刬p浣跨敤杩滅▼璁块棶ip锛岄�傜敤涓巣lm涓巜vp鍦ㄤ竴鍙颁富鏈虹殑鎯呭喌
+     * @param app
+     * @param stream
+     * @return
+     */
+    StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority);
+
+    /**
+     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 鍙槸鍦板潃鎷兼帴
+     * @param app
+     * @param stream
+     * @return
+     */
+    StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId);
+
+    /**
+     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 鍙槸鍦板潃鎷兼帴锛岃繑鍥炵殑ip浣跨敤杩滅▼璁块棶ip锛岄�傜敤涓巣lm涓巜vp鍦ㄤ竴鍙颁富鏈虹殑鎯呭喌
+     * @param app
+     * @param stream
+     * @return
+     */
+    StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay);
 }
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 58f92f8..30a9b83 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
@@ -4,17 +4,19 @@
 import com.genersoft.iot.vmp.common.CommonCallback;
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.common.VideoManagerConstants;
+import com.genersoft.iot.vmp.conf.MediaConfig;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 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.event.MediaServerChangeEvent;
-import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent;
+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.mediaServer.MediaServerChangeEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent;
 import com.genersoft.iot.vmp.media.service.IMediaNodeServerService;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
+import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
 import com.genersoft.iot.vmp.service.IInviteStreamService;
 import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
@@ -73,6 +75,10 @@
 
     @Autowired
     private ApplicationEventPublisher applicationEventPublisher;
+
+    @Autowired
+    private MediaConfig mediaConfig;
+
 
 
     /**
@@ -714,4 +720,63 @@
         }
         return mediaNodeServerService.getFFmpegCMDs(mediaServer);
     }
+
+    @Override
+    public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId) {
+        return getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, null, callId, true);
+    }
+
+    @Override
+    public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr, boolean authority) {
+        StreamInfo streamInfo = null;
+        if (mediaServerId == null) {
+            mediaServerId = mediaConfig.getId();
+        }
+        MediaServer mediaInfo = getOne(mediaServerId);
+        if (mediaInfo == null) {
+            return null;
+        }
+        String calld = null;
+        StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
+        if (streamAuthorityInfo != null) {
+            calld = streamAuthorityInfo.getCallId();
+        }
+        List<StreamInfo> streamInfoList = getMediaList(mediaInfo, app, stream, calld);
+        if (streamInfoList.isEmpty()) {
+            return null;
+        }else {
+            return streamInfoList.get(0);
+        }
+    }
+
+
+
+    @Override
+    public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority) {
+        return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null, authority);
+    }
+
+    @Override
+    public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) {
+        StreamInfo streamInfoResult = new StreamInfo();
+        streamInfoResult.setStream(stream);
+        streamInfoResult.setApp(app);
+        if (addr == null) {
+            addr = mediaServer.getStreamIp();
+        }
+
+        streamInfoResult.setIp(addr);
+        streamInfoResult.setMediaServerId(mediaServer.getId());
+        String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId;
+        streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app,  stream, callIdParam);
+        streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app,  stream, callIdParam);
+        streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
+        streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
+        streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
+        streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
+        streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam, isPlay);
+
+        streamInfoResult.setMediaInfo(mediaInfo);
+        return streamInfoResult;
+    }
 }
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 fc12859..2717fc3 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
@@ -11,9 +11,10 @@
 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.bean.ResultForOnPublish;
-import com.genersoft.iot.vmp.media.event.*;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
 import com.genersoft.iot.vmp.media.event.hook.HookType;
+import com.genersoft.iot.vmp.media.event.media.*;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig;
@@ -175,13 +176,6 @@
             return new HookResultForOnPublish(200, "success");
         }
 
-        taskExecutor.execute(() -> {
-            HookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json);
-            if (subscribe != null) {
-                subscribe.response(mediaServer, param);
-            }
-        });
-
         ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams());
         if (resultForOnPublish != null) {
             HookResultForOnPublish successResult = HookResultForOnPublish.getInstance(resultForOnPublish);
@@ -316,19 +310,12 @@
             MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
             if (mediaServerItem != null) {
                 event.setMediaServer(mediaServerItem);
+                event.setApp("rtp");
                 applicationEventPublisher.publishEvent(event);
             }
         }catch (Exception e) {
             logger.info("[ZLM-HOOK-rtpServer鏀舵祦瓒呮椂] 鍙戦�侀�氱煡澶辫触 ", e);
         }
-        taskExecutor.execute(() -> {
-            List<HookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_rtp_server_timeout);
-            if (subscribes != null && !subscribes.isEmpty()) {
-                for (HookSubscribe.Event subscribe : subscribes) {
-                    subscribe.response(null, param);
-                }
-            }
-        });
 
         return HookResult.SUCCESS();
     }
@@ -341,16 +328,16 @@
     public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) {
         logger.info("[ZLM HOOK] 褰曞儚瀹屾垚浜嬩欢锛歿}->{}", param.getMediaServerId(), param.getFile_path());
 
-        taskExecutor.execute(() -> {
-            List<HookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_record_mp4);
-            if (subscribes != null && !subscribes.isEmpty()) {
-                for (HookSubscribe.Event subscribe : subscribes) {
-                    subscribe.response(null, param);
-                }
+        try {
+            MediaRecordMp4Event event = new MediaRecordMp4Event(this);
+            MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+            if (mediaServerItem != null) {
+                event.setMediaServer(mediaServerItem);
+                applicationEventPublisher.publishEvent(event);
             }
-            cloudRecordService.addRecord(param);
-
-        });
+        }catch (Exception e) {
+            logger.info("[ZLM-HOOK-rtpServer鏀舵祦瓒呮椂] 鍙戦�侀�氱煡澶辫触 ", e);
+        }
 
         return HookResult.SUCCESS();
     }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java
index 60327eb..11e6063 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java
@@ -158,7 +158,7 @@
                     return null;
                 }
                 JSONObject mediaJSON = data.getJSONObject(0);
-                MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON);
+                MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer);
                 StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, callId, true);
                 if (streamInfo != null) {
                     streamInfoList.add(streamInfo);
@@ -207,7 +207,7 @@
         if (jsonObject.getInteger("code") != 0) {
             return null;
         }
-        return MediaInfo.getInstance(jsonObject);
+        return MediaInfo.getInstance(jsonObject, mediaServer);
     }
 
     @Override
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java
index 6d63329..27e62b2 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaServerStatusManger.java
@@ -5,8 +5,8 @@
 import com.alibaba.fastjson2.JSONObject;
 import com.genersoft.iot.vmp.conf.DynamicTask;
 import com.genersoft.iot.vmp.conf.UserSetting;
-import com.genersoft.iot.vmp.media.event.MediaServerChangeEvent;
-import com.genersoft.iot.vmp.media.event.MediaServerDeleteEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerDeleteEvent;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig;
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java
index 66d07de..8b722a9 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java
@@ -1,6 +1,6 @@
 package com.genersoft.iot.vmp.media.zlm.dto;
 
-import com.genersoft.iot.vmp.media.event.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
 
 /**
  * 娴佺殑閴存潈淇℃伅
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
index eda660e..797286f 100755
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java
@@ -2,7 +2,7 @@
 
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
-import com.genersoft.iot.vmp.media.event.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.utils.DateUtil;
 import io.swagger.v3.oas.annotations.media.Schema;
diff --git a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java
index bffd25b..86ee7b8 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java
@@ -21,11 +21,6 @@
     PageInfo<CloudRecordItem> getList(int page, int count, String query,  String app, String stream, String startTime, String endTime, List<MediaServer> mediaServerItems);
 
     /**
-     * 鏍规嵁hook娑堟伅澧炲姞涓�鏉¤褰�
-     */
-    void addRecord(OnRecordMp4HookParam param);
-
-    /**
      * 鑾峰彇鎵�鏈夌殑鏃ユ湡
      */
     List<String> getDateList(String app, String stream, int year, int month, List<MediaServer> mediaServerItems);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
index d3a57f7..649c727 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaService.java
@@ -11,39 +11,6 @@
 public interface IMediaService {
 
     /**
-     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 閫氳繃zlm鎺ュ彛妫�鏌ユ槸鍚﹀瓨鍦�
-     * @param app
-     * @param stream
-     * @return
-     */
-    StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId,String addr, boolean authority);
-
-
-    /**
-     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 閫氳繃zlm鎺ュ彛妫�鏌ユ槸鍚﹀瓨鍦�, 杩斿洖鐨刬p浣跨敤杩滅▼璁块棶ip锛岄�傜敤涓巣lm涓巜vp鍦ㄤ竴鍙颁富鏈虹殑鎯呭喌
-     * @param app
-     * @param stream
-     * @return
-     */
-    StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority);
-
-    /**
-     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 鍙槸鍦板潃鎷兼帴
-     * @param app
-     * @param stream
-     * @return
-     */
-    StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId);
-
-    /**
-     * 鏍规嵁搴旂敤鍚嶅拰娴両D鑾峰彇鎾斁鍦板潃, 鍙槸鍦板潃鎷兼帴锛岃繑鍥炵殑ip浣跨敤杩滅▼璁块棶ip锛岄�傜敤涓巣lm涓巜vp鍦ㄤ竴鍙颁富鏈虹殑鎯呭喌
-     * @param app
-     * @param stream
-     * @return
-     */
-    StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay);
-
-    /**
      * 鎾斁閴存潈
      */
     boolean authenticatePlay(String app, String stream, String callId);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
index 88cac66..9ba4964 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -7,6 +7,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
 import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
+import com.genersoft.iot.vmp.media.bean.MediaInfo;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
 import com.genersoft.iot.vmp.service.bean.ErrorCallback;
@@ -30,7 +31,7 @@
               ErrorCallback<Object> callback);
     SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<Object> callback);
 
-    StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, HookParam hookParam, String deviceId, String channelId);
+    StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId);
 
     MediaServer getNewMediaServerItem(Device device);
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java b/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java
index 771e4c8..c9a54bc 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java
@@ -1,5 +1,6 @@
 package com.genersoft.iot.vmp.service.bean;
 
+import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
 
 /**
@@ -76,18 +77,18 @@
      */
     private long timeLen;
 
-    public static CloudRecordItem getInstance(OnRecordMp4HookParam param) {
+    public static CloudRecordItem getInstance(MediaRecordMp4Event param) {
         CloudRecordItem cloudRecordItem = new CloudRecordItem();
         cloudRecordItem.setApp(param.getApp());
         cloudRecordItem.setStream(param.getStream());
-        cloudRecordItem.setStartTime(param.getStart_time()*1000);
-        cloudRecordItem.setFileName(param.getFile_name());
-        cloudRecordItem.setFolder(param.getFolder());
-        cloudRecordItem.setFileSize(param.getFile_size());
-        cloudRecordItem.setFilePath(param.getFile_path());
-        cloudRecordItem.setMediaServerId(param.getMediaServerId());
-        cloudRecordItem.setTimeLen((long) param.getTime_len() * 1000);
-        cloudRecordItem.setEndTime((param.getStart_time() + (long)param.getTime_len()) * 1000);
+        cloudRecordItem.setStartTime(param.getRecordInfo().getStartTime()*1000);
+        cloudRecordItem.setFileName(param.getRecordInfo().getFileName());
+        cloudRecordItem.setFolder(param.getRecordInfo().getFolder());
+        cloudRecordItem.setFileSize(param.getRecordInfo().getFileSize());
+        cloudRecordItem.setFilePath(param.getRecordInfo().getFilePath());
+        cloudRecordItem.setMediaServerId(param.getMediaServer().getId());
+        cloudRecordItem.setTimeLen((long) param.getRecordInfo().getTimeLen() * 1000);
+        cloudRecordItem.setEndTime((param.getRecordInfo().getStartTime() + (long)param.getRecordInfo().getTimeLen()) * 1000);
         return cloudRecordItem;
     }
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java
index de4af6c..6907e90 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java
@@ -5,6 +5,8 @@
 import com.baomidou.dynamic.datasource.annotation.DS;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
+import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaRecordMp4Event;
 import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
@@ -24,6 +26,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.time.*;
@@ -99,14 +103,15 @@
         return new ArrayList<>(resultSet);
     }
 
-    @Override
-    public void addRecord(OnRecordMp4HookParam param) {
-        CloudRecordItem cloudRecordItem = CloudRecordItem.getInstance(param);
-        StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
+    @Async("taskExecutor")
+    @EventListener
+    public void onApplicationEvent(MediaRecordMp4Event event) {
+        CloudRecordItem cloudRecordItem = CloudRecordItem.getInstance(event);
+        StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(event.getApp(), event.getStream());
         if (streamAuthorityInfo != null) {
             cloudRecordItem.setCallId(streamAuthorityInfo.getCallId());
         }
-        logger.info("[娣诲姞褰曞儚璁板綍] {}/{} 鏂囦欢澶у皬锛歿}, 鏃堕暱锛� {}绉�", param.getApp(), param.getStream(), param.getFile_size(),param.getTime_len());
+        logger.info("[娣诲姞褰曞儚璁板綍] {}/{} 鍐呭锛歿}", event.getApp(), event.getStream(), event.getRecordInfo());
         cloudRecordServiceMapper.add(cloudRecordItem);
     }
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java
index 360e29c..6e00960 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java
@@ -6,8 +6,8 @@
 import com.genersoft.iot.vmp.common.InviteSessionStatus;
 import com.genersoft.iot.vmp.common.InviteSessionType;
 import com.genersoft.iot.vmp.common.VideoManagerConstants;
-import com.genersoft.iot.vmp.media.event.MediaArrivalEvent;
-import com.genersoft.iot.vmp.media.event.MediaDepartureEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
 import com.genersoft.iot.vmp.service.IInviteStreamService;
 import com.genersoft.iot.vmp.service.bean.ErrorCallback;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
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 3fcb9d0..126ea24 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
@@ -50,12 +50,6 @@
     private IRedisCatchStorage redisCatchStorage;
 
     @Autowired
-    private IMediaServerService mediaServerService;
-
-    @Autowired
-    private MediaConfig mediaConfig;
-
-    @Autowired
     private IStreamProxyService streamProxyService;
 
     @Autowired
@@ -87,67 +81,6 @@
 
     @Autowired
     private ISIPCommander commander;
-
-
-
-    @Override
-    public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServerItem, String app, String stream, MediaInfo mediaInfo, String callId) {
-        return getStreamInfoByAppAndStream(mediaServerItem, app, stream, mediaInfo, null, callId, true);
-    }
-
-    @Override
-    public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, String addr, boolean authority) {
-        StreamInfo streamInfo = null;
-        if (mediaServerId == null) {
-            mediaServerId = mediaConfig.getId();
-        }
-        MediaServer mediaInfo = mediaServerService.getOne(mediaServerId);
-        if (mediaInfo == null) {
-            return null;
-        }
-        String calld = null;
-        StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
-        if (streamAuthorityInfo != null) {
-            calld = streamAuthorityInfo.getCallId();
-        }
-        List<StreamInfo> streamInfoList = mediaServerService.getMediaList(mediaInfo, app, stream, calld);
-        if (streamInfoList.isEmpty()) {
-            return null;
-        }else {
-            return streamInfoList.get(0);
-        }
-    }
-
-
-
-    @Override
-    public StreamInfo getStreamInfoByAppAndStreamWithCheck(String app, String stream, String mediaServerId, boolean authority) {
-        return getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, null, authority);
-    }
-
-    @Override
-    public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) {
-        StreamInfo streamInfoResult = new StreamInfo();
-        streamInfoResult.setStream(stream);
-        streamInfoResult.setApp(app);
-        if (addr == null) {
-            addr = mediaServer.getStreamIp();
-        }
-
-        streamInfoResult.setIp(addr);
-        streamInfoResult.setMediaServerId(mediaServer.getId());
-        String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId;
-        streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app,  stream, callIdParam);
-        streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app,  stream, callIdParam);
-        streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
-        streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
-        streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
-        streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam);
-        streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app,  stream, callIdParam, isPlay);
-
-        streamInfoResult.setMediaInfo(mediaInfo);
-        return streamInfoResult;
-    }
 
     @Override
     public boolean authenticatePlay(String app, String stream, String callId) {
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
index cfb9abb..48a8fbb 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java
@@ -1,9 +1,7 @@
 package com.genersoft.iot.vmp.service.impl;
 
 import com.baomidou.dynamic.datasource.annotation.DS;
-import com.genersoft.iot.vmp.common.InviteInfo;
-import com.genersoft.iot.vmp.common.InviteSessionStatus;
-import com.genersoft.iot.vmp.common.InviteSessionType;
+import com.genersoft.iot.vmp.common.*;
 import com.genersoft.iot.vmp.conf.DynamicTask;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
@@ -11,10 +9,12 @@
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
 import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.media.event.MediaDepartureEvent;
-import com.genersoft.iot.vmp.media.event.MediaSendRtpStoppedEvent;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookData;
+import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
@@ -72,7 +72,7 @@
     private IMediaServerService mediaServerService;
 
     @Autowired
-    private SIPCommanderFroPlatform commanderForPlatform;
+    private ISIPCommanderForPlatform commanderForPlatform;
 
     @Autowired
     private DynamicTask dynamicTask;
@@ -520,11 +520,11 @@
                     inviteStreamService.removeInviteInfo(inviteInfoForOld);
                 }else {
                     // 娴佺‘瀹炲皻鍦ㄦ帹娴侊紝鐩存帴鍥炶皟缁撴灉
-                    OnStreamChangedHookParam hookParam = new OnStreamChangedHookParam();
-                    hookParam.setApp(inviteInfoForOld.getStreamInfo().getApp());
-                    hookParam.setStream(inviteInfoForOld.getStreamInfo().getStream());
-
-                    hookEvent.response(mediaServerItemForStreamInfo, hookParam);
+                    HookData hookData = new HookData();
+                    hookData.setApp(inviteInfoForOld.getStreamInfo().getApp());
+                    hookData.setStream(inviteInfoForOld.getStreamInfo().getStream());
+                    hookData.setMediaServer(mediaServerItemForStreamInfo);
+                    hookEvent.response(hookData);
                     return;
                 }
             }
@@ -582,14 +582,14 @@
                 }
             }
         }, userSetting.getPlayTimeout());
-        commanderForPlatform.broadcastInviteCmd(platform, channelId, mediaServerItem, ssrcInfo, (mediaServerItemForInvite, hookParam)->{
+        commanderForPlatform.broadcastInviteCmd(platform, channelId, mediaServerItem, ssrcInfo, (hookData)->{
             logger.info("[鍥芥爣绾ц仈] 鍙戣捣璇煶鍠婅瘽 鏀跺埌涓婄骇鎺ㄦ祦 deviceId: {}, channelId: {}", platform.getServerGBId(), channelId);
             dynamicTask.stop(timeOutTaskKey);
             // hook鍝嶅簲
-            playService.onPublishHandlerForPlay(mediaServerItemForInvite, hookParam, platform.getServerGBId(), channelId);
+            playService.onPublishHandlerForPlay(hookData.getMediaServer(), hookData.getMediaInfo(), platform.getServerGBId(), channelId);
             // 鏀跺埌娴�
             if (hookEvent != null) {
-                hookEvent.response(mediaServerItem, hookParam);
+                hookEvent.response(hookData);
             }
         }, event -> {
 
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 1fad2be..32af057 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
@@ -17,16 +17,17 @@
 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.event.MediaNotFoundEvent;
+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.HookData;
+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.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRecordMp4;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
@@ -98,9 +99,6 @@
 
     @Autowired
     private SendRtpPortManager sendRtpPortManager;
-
-    @Autowired
-    private IMediaService mediaService;
 
     @Autowired
     private IMediaServerService mediaServerService;
@@ -423,12 +421,12 @@
 
         // 鏌ョ湅璁惧鏄惁宸茬粡鍦ㄦ帹娴�
         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) -> {
@@ -538,8 +536,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: {}",
@@ -554,11 +551,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);
@@ -574,7 +571,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(),
@@ -700,11 +697,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) {
@@ -722,9 +718,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);
@@ -733,7 +728,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);
 
@@ -839,10 +834,10 @@
             inviteStreamService.removeInviteInfo(inviteInfo);
         };
 
-        HookSubscribe.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(),
@@ -1028,10 +1023,10 @@
             streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
             inviteStreamService.removeInviteInfo(inviteInfo);
         };
-        HookSubscribe.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(),
@@ -1049,26 +1044,24 @@
                                 downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD);
 
                         // 娉ㄥ唽褰曞儚鍥炶皟浜嬩欢锛屽綍鍍忎笅杞界粨鏉熷悗鍐欏叆涓嬭浇鍦板潃
-                        HookSubscribe.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);
+                        subscribe.addSubscribe(hook, hookEventForRecord);
                     });
         } catch (InvalidArgumentException | SipException | ParseException e) {
             logger.error("[鍛戒护鍙戦�佸け璐 褰曞儚涓嬭浇: {}", e.getMessage());
@@ -1134,9 +1127,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);
@@ -1153,9 +1145,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;
@@ -1220,7 +1211,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;
     }
@@ -1591,7 +1582,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);
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 c768ae1..2ac9de6 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -9,19 +9,18 @@
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
 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.event.MediaNotFoundEvent;
+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.ZLMServerFactory;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.service.IGbStreamService;
-import com.genersoft.iot.vmp.service.IMediaService;
 import com.genersoft.iot.vmp.service.IStreamProxyService;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
@@ -64,9 +63,6 @@
 
     @Autowired
     private IVideoManagerStorage videoManagerStorager;
-
-    @Autowired
-    private IMediaService mediaService;
 
     @Autowired
     private ZLMServerFactory zlmServerFactory;
@@ -203,9 +199,9 @@
             callback.run(ErrorCode.ERROR100.getCode(), "淇濆瓨澶辫触", null);
             return;
         }
-        HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaServer.getId());
-        hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> {
-            StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
+        Hook hook = Hook.getInstance(HookType.on_media_arrival, param.getApp(), param.getStream(), mediaServer.getId());
+        hookSubscribe.addSubscribe(hook, (hookData) -> {
+            StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(
                     mediaServer, param.getApp(), param.getStream(), null, null);
             callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
         });
@@ -213,7 +209,7 @@
             String talkKey = UUID.randomUUID().toString();
             String delayTalkKey = UUID.randomUUID().toString();
             dynamicTask.startDelay(delayTalkKey, ()->{
-                StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaServer.getId(), false);
+                StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaServer.getId(), false);
                 if (streamInfo != null) {
                     callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
                 }else {
@@ -223,9 +219,9 @@
             }, 7000);
             WVPResult<String> result = addStreamProxyToZlm(param);
             if (result != null && result.getCode() == 0) {
-                hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
+                hookSubscribe.removeSubscribe(hook);
                 dynamicTask.stop(talkKey);
-                StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
+                StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(
                         mediaServer, param.getApp(), param.getStream(), null, null);
                 callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
             }else {
@@ -244,7 +240,7 @@
             }
         }
         else{
-            StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
+            StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(
                     mediaServer, param.getApp(), param.getStream(), null, null);
             callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
         }
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 4bdcc2f..b3c510d 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java
@@ -11,8 +11,8 @@
 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
 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.event.media.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
index d2d32e8..d14cea5 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisGbPlayMsgListener.java
@@ -6,10 +6,10 @@
 import com.genersoft.iot.vmp.conf.DynamicTask;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.bean.*;
@@ -61,9 +61,9 @@
      */
     public static final  int ERROR_CODE_TIMEOUT = -3;
 
-    private Map<String, PlayMsgCallback> callbacks = new ConcurrentHashMap<>();
-    private Map<String, PlayMsgCallbackForStartSendRtpStream> callbacksForStartSendRtpStream = new ConcurrentHashMap<>();
-    private Map<String, PlayMsgErrorCallback> callbacksForError = new ConcurrentHashMap<>();
+    private final Map<String, PlayMsgCallback> callbacks = new ConcurrentHashMap<>();
+    private final Map<String, PlayMsgCallbackForStartSendRtpStream> callbacksForStartSendRtpStream = new ConcurrentHashMap<>();
+    private final Map<String, PlayMsgErrorCallback> callbacksForError = new ConcurrentHashMap<>();
 
     @Autowired
     private UserSetting userSetting;
@@ -89,7 +89,7 @@
     @Autowired
     private HookSubscribe subscribe;
 
-    private ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
+    private final ConcurrentLinkedQueue<Message> taskQueue = new ConcurrentLinkedQueue<>();
 
     @Qualifier("taskExecutor")
     @Autowired
@@ -297,9 +297,8 @@
             }, userSetting.getPlatformPlayTimeout());
 
             // 娣诲姞璁㈤槄
-            HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed(content.getApp(), content.getStream(), true, "rtsp", mediaServerItem.getId());
-
-            subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam)->{
+            Hook hook = Hook.getInstance(HookType.on_media_arrival, content.getApp(), content.getStream(), content.getMediaServerId());
+            subscribe.addSubscribe(hook, (hookData)->{
                         dynamicTask.stop(taskKey);
                         responseSendItem(mediaServerItem, content, toId, serial);
                     });
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 7edf7e8..9cb4d38 100755
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -6,7 +6,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
-import com.genersoft.iot.vmp.media.event.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
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 2523312..3c0b749 100755
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -9,7 +9,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
-import com.genersoft.iot.vmp.media.event.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
index 56d192e..26e9685 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/media/MediaController.java
@@ -5,6 +5,7 @@
 import com.genersoft.iot.vmp.conf.security.JwtUtils;
 import com.genersoft.iot.vmp.conf.security.SecurityUtils;
 import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
+import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
 import com.genersoft.iot.vmp.service.IMediaService;
 import com.genersoft.iot.vmp.service.IStreamProxyService;
@@ -36,9 +37,10 @@
     private IRedisCatchStorage redisCatchStorage;
 
     @Autowired
-    private IMediaService mediaService;
-    @Autowired
     private IStreamProxyService streamProxyService;
+
+    @Autowired
+    private IMediaServerService mediaServerService;
 
 
     /**
@@ -85,9 +87,9 @@
             String host = request.getHeader("Host");
             String localAddr = host.split(":")[0];
             logger.info("浣跨敤{}浣滀负杩斿洖娴佺殑ip", localAddr);
-            streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority);
+            streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority);
         }else {
-            streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
+            streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
         }
 
         if (streamInfo != null){
@@ -105,9 +107,9 @@
                 String host = request.getHeader("Host");
                 String localAddr = host.split(":")[0];
                 logger.info("浣跨敤{}浣滀负杩斿洖娴佺殑ip", localAddr);
-                streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority);
+                streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, localAddr, authority);
             }else {
-                streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
+                streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
             }
             if (streamInfo != null){
                 return new StreamContent(streamInfo);
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java
index 3e1e973..dc01c43 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/ps/PsController.java
@@ -6,12 +6,11 @@
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.security.JwtUtils;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRtpServerTimeout;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
@@ -108,12 +107,11 @@
         }
         // 娉ㄥ唽鍥炶皟濡傛灉rtp鏀舵祦瓒呮椂鍒欓�氳繃鍥炶皟鍙戦�侀�氱煡
         if (callBack != null) {
-            HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(stream, String.valueOf(ssrcInt), mediaServerItem.getId());
+            Hook hook = Hook.getInstance(HookType.on_rtp_server_timeout, "rtp", stream, mediaServerItem.getId());
             // 璁㈤槄 zlm鍚姩浜嬩欢, 鏂扮殑zlm涔熶細浠庤繖閲岃繘鍏ョ郴缁�
-            hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout,
-                    (mediaServerItemInUse, hookParam)->{
-                        OnRtpServerTimeoutHookParam serverTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam;
-                        if (stream.equals(serverTimeoutHookParam.getStream_id())) {
+            hookSubscribe.addSubscribe(hook,
+                    (hookData)->{
+                        if (stream.equals(hookData.getStream())) {
                             logger.info("[绗笁鏂筆S鏈嶅姟瀵规帴->寮�鍚敹娴佸拰鑾峰彇鍙戞祦淇℃伅] 绛夊緟鏀舵祦瓒呮椂 callId->{}, 鍙戦�佸洖璋�", callId);
                             // 灏嗕俊鎭啓鍏edis涓紝浠ュ鍚庣敤
                             redisTemplate.delete(receiveKey);
@@ -126,7 +124,7 @@
                             } catch (IOException e) {
                                 logger.error("[绗笁鏂筆S鏈嶅姟瀵规帴->寮�鍚敹娴佸拰鑾峰彇鍙戞祦淇℃伅] 绛夊緟鏀舵祦瓒呮椂 callId->{}, 鍙戦�佸洖璋冨け璐�", callId, e);
                             }
-                            hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout);
+                            hookSubscribe.removeSubscribe(hook);
                         }
                     });
         }
@@ -241,18 +239,18 @@
         }else {
             logger.info("[绗笁鏂筆S鏈嶅姟瀵规帴->鍙戦�佹祦] 娴佷笉瀛樺湪锛岀瓑寰呮祦涓婄嚎锛宑allId->{}", callId);
             String uuid = UUID.randomUUID().toString();
-            HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(app, stream, true, "rtsp", mediaServerItem.getId());
+            Hook hook = Hook.getInstance(HookType.on_media_arrival, app, stream, mediaServerItem.getId());
             dynamicTask.startDelay(uuid, ()->{
                 logger.info("[绗笁鏂筆S鏈嶅姟瀵规帴->鍙戦�佹祦] 绛夊緟娴佷笂绾胯秴鏃� callId->{}", callId);
                 redisTemplate.delete(key);
-                hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
+                hookSubscribe.removeSubscribe(hook);
             }, 10000);
 
             // 璁㈤槄 zlm鍚姩浜嬩欢, 鏂扮殑zlm涔熶細浠庤繖閲岃繘鍏ョ郴缁�
             OtherPsSendInfo finalSendInfo = sendInfo;
-            hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
-            hookSubscribe.addSubscribe(hookSubscribeForStreamChange,
-                    (mediaServerItemInUse, response)->{
+            hookSubscribe.removeSubscribe(hook);
+            hookSubscribe.addSubscribe(hook,
+                    (hookData)->{
                         dynamicTask.stop(uuid);
                         logger.info("[绗笁鏂筆S鏈嶅姟瀵规帴->鍙戦�佹祦] 娴佷笂绾匡紝寮�濮嬪彂娴� callId->{}", callId);
                         try {
@@ -269,7 +267,7 @@
                             logger.info("[绗笁鏂筆S鏈嶅姟瀵规帴->鍙戦�佹祦] 瑙嗛娴佸彂娴佸け璐ワ紝callId->{}, {}", callId, jsonObject.getString("msg"));
                             throw new ControllerException(ErrorCode.ERROR100.getCode(), "[瑙嗛娴佸彂娴佸け璐 " + jsonObject.getString("msg"));
                         }
-                        hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
+                        hookSubscribe.removeSubscribe(hook);
                     });
         }
     }
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
index c810745..96b0d49 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
@@ -6,12 +6,11 @@
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.security.JwtUtils;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
 import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
 import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRtpServerTimeout;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRtpServerTimeoutHookParam;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
@@ -109,12 +108,11 @@
         }
         // 娉ㄥ唽鍥炶皟濡傛灉rtp鏀舵祦瓒呮椂鍒欓�氳繃鍥炶皟鍙戦�侀�氱煡
         if (callBack != null) {
-            HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(stream, String.valueOf(ssrcInt), mediaServerItem.getId());
+            Hook hook = Hook.getInstance(HookType.on_rtp_server_timeout, "rtp", stream, mediaServerItem.getId());
             // 璁㈤槄 zlm鍚姩浜嬩欢, 鏂扮殑zlm涔熶細浠庤繖閲岃繘鍏ョ郴缁�
-            hookSubscribe.addSubscribe(hookSubscribeForRtpServerTimeout,
-                    (mediaServerItemInUse, hookParam)->{
-                        OnRtpServerTimeoutHookParam serverTimeoutHookParam = (OnRtpServerTimeoutHookParam) hookParam;
-                        if (stream.equals(serverTimeoutHookParam.getStream_id())) {
+            hookSubscribe.addSubscribe(hook,
+                    (hookData)->{
+                        if (stream.equals(hookData.getStream())) {
                             logger.info("[寮�鍚敹娴佸拰鑾峰彇鍙戞祦淇℃伅] 绛夊緟鏀舵祦瓒呮椂 callId->{}, 鍙戦�佸洖璋�", callId);
                             OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
                             OkHttpClient client = httpClientBuilder.build();
@@ -125,7 +123,7 @@
                             } catch (IOException e) {
                                 logger.error("[绗笁鏂规湇鍔″鎺�->寮�鍚敹娴佸拰鑾峰彇鍙戞祦淇℃伅] 绛夊緟鏀舵祦瓒呮椂 callId->{}, 鍙戦�佸洖璋冨け璐�", callId, e);
                             }
-                            hookSubscribe.removeSubscribe(hookSubscribeForRtpServerTimeout);
+                            hookSubscribe.removeSubscribe(hook);
                         }
                     });
         }
@@ -225,7 +223,7 @@
         if (!((dstPortForAudio > 0 && !ObjectUtils.isEmpty(dstPortForAudio) || (dstPortForVideo > 0 && !ObjectUtils.isEmpty(dstIpForVideo))))) {
             throw new ControllerException(ErrorCode.ERROR400.getCode(), "鑷冲皯搴旇瀛樺湪涓�缁勯煶棰戞垨瑙嗛鍙戦�佸弬鏁�");
         }
-        MediaServer mediaServerItem = mediaServerService.getDefaultMediaServer();
+        MediaServer mediaServer = mediaServerService.getDefaultMediaServer();
         String key = VideoManagerConstants.WVP_OTHER_SEND_RTP_INFO + userSetting.getServerId() + "_"  + callId;
         OtherRtpSendInfo sendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(key);
         if (sendInfo == null) {
@@ -278,10 +276,10 @@
             paramForVideo = null;
         }
 
-        Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream);
+        Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, app, stream);
         if (streamReady) {
             if (paramForVideo != null) {
-                JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForVideo);
+                JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForVideo);
                 if (jsonObject.getInteger("code") == 0) {
                     logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 瑙嗛娴佸彂娴佹垚鍔燂紝callId->{}锛宲aram->{}", callId, paramForVideo);
                     redisTemplate.opsForValue().set(key, sendInfo);
@@ -292,7 +290,7 @@
                 }
             }
             if(paramForAudio != null) {
-                JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForAudio);
+                JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForAudio);
                 if (jsonObject.getInteger("code") == 0) {
                     logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 闊抽娴佸彂娴佹垚鍔燂紝callId->{}锛宲aram->{}", callId, paramForAudio);
                     redisTemplate.opsForValue().set(key, sendInfo);
@@ -305,18 +303,18 @@
         }else {
             logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 娴佷笉瀛樺湪锛岀瓑寰呮祦涓婄嚎锛宑allId->{}", callId);
             String uuid = UUID.randomUUID().toString();
-            HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(app, stream, true, "rtsp", mediaServerItem.getId());
+            Hook hook = Hook.getInstance(HookType.on_media_arrival, app, stream, mediaServer.getId());
             dynamicTask.startDelay(uuid, ()->{
                 logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 绛夊緟娴佷笂绾胯秴鏃� callId->{}", callId);
                 redisTemplate.delete(key);
-                hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
+                hookSubscribe.removeSubscribe(hook);
             }, 10000);
 
             // 璁㈤槄 zlm鍚姩浜嬩欢, 鏂扮殑zlm涔熶細浠庤繖閲岃繘鍏ョ郴缁�
             OtherRtpSendInfo finalSendInfo = sendInfo;
-            hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
-            hookSubscribe.addSubscribe(hookSubscribeForStreamChange,
-                    (mediaServerItemInUse, response)->{
+            hookSubscribe.removeSubscribe(hook);
+            hookSubscribe.addSubscribe(hook,
+                    (hookData)->{
                         dynamicTask.stop(uuid);
                         logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 娴佷笂绾匡紝寮�濮嬪彂娴� callId->{}", callId);
                         try {
@@ -325,7 +323,7 @@
                             throw new RuntimeException(e);
                         }
                         if (paramForVideo != null) {
-                            JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForVideo);
+                            JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForVideo);
                             if (jsonObject.getInteger("code") == 0) {
                                 logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 瑙嗛娴佸彂娴佹垚鍔燂紝callId->{}锛宲aram->{}", callId, paramForVideo);
                                 redisTemplate.opsForValue().set(key, finalSendInfo);
@@ -336,7 +334,7 @@
                             }
                         }
                         if(paramForAudio != null) {
-                            JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServerItem, paramForAudio);
+                            JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaServer, paramForAudio);
                             if (jsonObject.getInteger("code") == 0) {
                                 logger.info("[绗笁鏂规湇鍔″鎺�->鍙戦�佹祦] 闊抽娴佸彂娴佹垚鍔燂紝callId->{}锛宲aram->{}", callId, paramForAudio);
                                 redisTemplate.opsForValue().set(key, finalSendInfo);
@@ -346,7 +344,7 @@
                                 throw new ControllerException(ErrorCode.ERROR100.getCode(), "[闊抽娴佸彂娴佸け璐 " + jsonObject.getString("msg"));
                             }
                         }
-                        hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
+                        hookSubscribe.removeSubscribe(hook);
                     });
         }
     }
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
index dc31b5a..780f8a7 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/server/ServerController.java
@@ -9,10 +9,9 @@
 import com.genersoft.iot.vmp.conf.VersionInfo;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.conf.security.JwtUtils;
+import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
 import com.genersoft.iot.vmp.media.service.IMediaServerService;
 import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
-import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
-import com.genersoft.iot.vmp.media.event.hook.IHookSubscribe;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServer;
 import com.genersoft.iot.vmp.service.*;
 import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
@@ -40,8 +39,6 @@
 @RequestMapping("/api/server")
 public class ServerController {
 
-    @Autowired
-    private HookSubscribe zlmHttpHookSubscribe;
 
     @Autowired
     private IMediaServerService mediaServerService;
@@ -76,8 +73,6 @@
     @Autowired
     private IRedisCatchStorage redisCatchStorage;
 
-    @Autowired
-    private SendRtpPortManager sendRtpPortManager;
 
 
     @GetMapping(value = "/media_server/list")
@@ -215,13 +210,6 @@
             }
         }
         return jsonObject;
-    }
-
-    @GetMapping(value = "/hooks")
-    @ResponseBody
-    @Operation(summary = "鑾峰彇褰撳墠鎵�鏈塰ook")
-    public List<IHookSubscribe> getHooks() {
-        return zlmHttpHookSubscribe.getAll();
     }
 
     @GetMapping(value = "/system/info")
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 459f3cc..309cd69 100755
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/streamPush/StreamPushController.java
@@ -249,7 +249,7 @@
         if (push != null && !push.isSelf()) {
             throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏉ヨ嚜鍏朵粬骞冲彴鐨勬帹娴佷俊鎭�");
         }
-        StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
+        StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, mediaServerId, authority);
         if (streamInfo == null){
             throw new ControllerException(ErrorCode.ERROR100.getCode(), "鑾峰彇鎾斁鍦板潃澶辫触");
         }

--
Gitblit v1.8.0