From 4c8e2beb4d369865893ec791430d95420d4acfad Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期二, 08 十一月 2022 19:58:36 +0800
Subject: [PATCH] 优化hook处理速度

---
 src/main/java/com/genersoft/iot/vmp/service/impl/StreamPushServiceImpl.java             |   41 +-
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamPushItem.java                   |   14 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNoneReaderHookParam.java |   41 ++
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnSendRtpStoppedHookParam.java   |   27 +
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnServerKeepaliveHookParam.java  |   20 +
 web_src/src/components/console/ConsoleResource.vue                                      |   12 
 src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java        |   28 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java    |   17 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ServerKeepaliveData.java              |    4 
 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java                  |    2 
 src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java                    |    3 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java          |    6 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java                   |    2 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamAuthorityInfo.java              |   15 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java                  |  574 +++++++++++++----------------------
 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java            |   22 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPlayHookParam.java             |    6 
 src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java                    |    8 
 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java                  |   13 
 src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java            |   18 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNotFoundHookParam.java   |   10 
 src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java            |   21 
 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OriginType.java                  |    2 
 src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java                     |    6 
 24 files changed, 434 insertions(+), 478 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index 41c17ca..6392ada 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -14,6 +14,7 @@
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
 import com.genersoft.iot.vmp.media.zlm.dto.*;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
 import com.genersoft.iot.vmp.service.*;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
@@ -108,59 +109,25 @@
 	 */
 	@ResponseBody
 	@PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
-	public JSONObject onServerKeepalive(@RequestBody JSONObject json){
+	public JSONObject onServerKeepalive(@RequestBody OnServerKeepaliveHookParam param){
 
-		logger.info("[ ZLM HOOK ]on_server_keepalive API璋冪敤锛屽弬鏁帮細" + json.toString());
-		String mediaServerId = json.getString("mediaServerId");
-		List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
-		if (subscribes != null  && subscribes.size() > 0) {
-			for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
-				subscribe.response(null, json);
+		logger.info("[ZLM HOOK] 鏀跺埌zlm蹇冭烦锛�" + param.getMediaServerId());
+
+		taskExecutor.execute(()->{
+			List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_keepalive);
+			JSONObject json = (JSONObject) JSON.toJSON(param);
+			if (subscribes != null  && subscribes.size() > 0) {
+				for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
+					subscribe.response(null, json);
+				}
 			}
-		}
-		mediaServerService.updateMediaServerKeepalive(mediaServerId, json.getJSONObject("data"));
+		});
+		mediaServerService.updateMediaServerKeepalive(param.getMediaServerId(), param.getData());
 
 		JSONObject ret = new JSONObject();
 		ret.put("code", 0);
 		ret.put("msg", "success");
 
-		return ret;
-	}
-
-	/**
-	 * 娴侀噺缁熻浜嬩欢锛屾挱鏀惧櫒鎴栨帹娴佸櫒鏂紑鏃跺苟涓旇�楃敤娴侀噺瓒呰繃鐗瑰畾闃堝�兼椂浼氳Е鍙戞浜嬩欢锛岄槇鍊奸�氳繃閰嶇疆鏂囦欢general.flowThreshold閰嶇疆锛涙浜嬩欢瀵瑰洖澶嶄笉鏁忔劅銆�
-	 *  
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_flow_report", produces = "application/json;charset=UTF-8")
-	public JSONObject onFlowReport(@RequestBody JSONObject json){
-		
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_flow_report API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("msg", "success");
-		return ret;
-	}
-	
-	/**
-	 * 璁块棶http鏂囦欢鏈嶅姟鍣ㄤ笂hls涔嬪鐨勬枃浠舵椂瑙﹀彂銆�
-	 *  
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_http_access", produces = "application/json;charset=UTF-8")
-	public JSONObject onHttpAccess(@RequestBody JSONObject json){
-		
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_http_access API 璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("err", "");
-		ret.put("path", "");
-		ret.put("second", 600);
 		return ret;
 	}
 	
@@ -171,20 +138,21 @@
 	@ResponseBody
 	@PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8")
 	public JSONObject onPlay(@RequestBody OnPlayHookParam param){
-
-		JSONObject json = (JSONObject)JSON.toJSON(param);
-
 		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_play API璋冪敤锛屽弬鏁帮細" + JSON.toJSONString(param));
+			logger.debug("[ZLM HOOK] 鎾斁閴存潈锛歿}->{}" + param.getMediaServerId(), param);
 		}
 		String mediaServerId = param.getMediaServerId();
-		ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json);
-		if (subscribe != null ) {
-			MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
-			if (mediaInfo != null) {
-				subscribe.response(mediaInfo, json);
+
+		taskExecutor.execute(()->{
+			JSONObject json = (JSONObject) JSON.toJSON(param);
+			ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_play, json);
+			if (subscribe != null ) {
+				MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
+				if (mediaInfo != null) {
+					subscribe.response(mediaInfo, json);
+				}
 			}
-		}
+		});
 		JSONObject ret = new JSONObject();
 		if (!"rtp".equals(param.getApp())) {
 			Map<String, String> paramMap = urlParamToMap(param.getParams());
@@ -211,7 +179,7 @@
 
 		JSONObject json = (JSONObject) JSON.toJSON(param);
 
-		logger.info("[ ZLM HOOK ]on_publish API璋冪敤锛屽弬鏁帮細" + json.toString());
+		logger.info("[ZLM HOOK]鎺ㄦ祦閴存潈锛歿}->{}",  param.getMediaServerId(), param);
 		JSONObject ret = new JSONObject();
 		String mediaServerId = json.getString("mediaServerId");
 		MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
@@ -258,21 +226,23 @@
 
 		ret.put("code", 0);
 		ret.put("msg", "success");
-		ret.put("enable_hls", true);
+		ret.put("enable_hls", false);
+
 		if (!"rtp".equals(param.getApp())) {
 			ret.put("enable_audio", true);
 		}
 
-
-		ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json);
-		if (subscribe != null) {
-			if (mediaInfo != null) {
-				subscribe.response(mediaInfo, json);
-			}else {
-				ret.put("code", 1);
-				ret.put("msg", "zlm not register");
+		taskExecutor.execute(()->{
+			ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json);
+			if (subscribe != null) {
+				if (mediaInfo != null) {
+					subscribe.response(mediaInfo, json);
+				}else {
+					ret.put("code", 1);
+					ret.put("msg", "zlm not register");
+				}
 			}
-		}
+		});
 
 		if ("rtp".equals(param.getApp())) {
 			ret.put("enable_mp4", userSetting.getRecordSip());
@@ -292,111 +262,8 @@
 				ret.put("mp4_max_second", 10);
 				ret.put("enable_mp4", true);
 				ret.put("enable_audio", true);
-
 			}
 		}
-		return ret;
-	}
-
-
-
-	/**
-	 * 褰曞埗mp4瀹屾垚鍚庨�氱煡浜嬩欢锛涙浜嬩欢瀵瑰洖澶嶄笉鏁忔劅銆�
-	 *  
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8")
-	public JSONObject onRecordMp4(@RequestBody JSONObject json){
-		
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_record_mp4 API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("msg", "success");
-		return ret;
-	}
-	/**
-	 * 褰曞埗hls瀹屾垚鍚庨�氱煡浜嬩欢锛涙浜嬩欢瀵瑰洖澶嶄笉鏁忔劅銆�
-	 *
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_record_ts", produces = "application/json;charset=UTF-8")
-	public JSONObject onRecordTs(@RequestBody JSONObject json){
-
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_record_ts API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("msg", "success");
-		return ret;
-	}
-	
-	/**
-	 * rtsp涓撶敤鐨勯壌鏉冧簨浠讹紝鍏堣Е鍙憃n_rtsp_realm浜嬩欢鐒跺悗鎵嶄細瑙﹀彂on_rtsp_auth浜嬩欢銆�
-	 *  
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_rtsp_realm", produces = "application/json;charset=UTF-8")
-	public JSONObject onRtspRealm(@RequestBody JSONObject json){
-		
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_rtsp_realm API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("realm", "");
-		return ret;
-	}
-	
-	
-	/**
-	 * 璇tsp娴佹槸鍚﹀紑鍚痳tsp涓撶敤鏂瑰紡鐨勯壌鏉冧簨浠讹紝寮�鍚悗鎵嶄細瑙﹀彂on_rtsp_auth浜嬩欢銆傞渶瑕佹寚鍑虹殑鏄痳tsp涔熸敮鎸乽rl鍙傛暟閴存潈锛屽畠鏀寔涓ょ鏂瑰紡閴存潈銆�
-	 *  
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_rtsp_auth", produces = "application/json;charset=UTF-8")
-	public JSONObject onRtspAuth(@RequestBody JSONObject json){
-		
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_rtsp_auth API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("encrypted", false);
-		ret.put("passwd", "test");
-		return ret;
-	}
-	
-	/**
-	 * shell鐧诲綍閴存潈锛孼LMediaKit鎻愪緵绠�鍗曠殑telnet璋冭瘯鏂瑰紡锛屼娇鐢╰elnet 127.0.0.1 9000鑳借繘鍏ediaServer杩涚▼鐨剆hell鐣岄潰銆�
-	 *  
-	 */
-	@ResponseBody
-	@PostMapping(value = "/on_shell_login", produces = "application/json;charset=UTF-8")
-	public JSONObject onShellLogin(@RequestBody JSONObject json){
-		
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_shell_login API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_shell_login, json);
-		if (subscribe != null ) {
-			MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
-			if (mediaInfo != null) {
-				subscribe.response(mediaInfo, json);
-			}
-
-		}
-
-		JSONObject ret = new JSONObject();
-		ret.put("code", 0);
-		ret.put("msg", "success");
 		return ret;
 	}
 	
@@ -406,137 +273,139 @@
 	 */
 	@ResponseBody
 	@PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8")
-	public JSONObject onStreamChanged(@RequestBody MediaItem item){
+	public JSONObject onStreamChanged(@RequestBody OnStreamChangedHookParam param){
 
-		logger.info("[ ZLM HOOK ]on_stream_changed API璋冪敤锛屽弬鏁帮細" + JSONObject.toJSONString(item));
-		String mediaServerId = item.getMediaServerId();
-		JSONObject json = (JSONObject) JSON.toJSON(item);
-		ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json);
-		if (subscribe != null ) {
-			MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
-			if (mediaInfo != null) {
-				subscribe.response(mediaInfo, json);
-			}
-		}
-		// 娴佹秷澶辩Щ闄edis play
-		String app = item.getApp();
-		String stream = item.getStream();
-		String schema = item.getSchema();
-		List<MediaItem.MediaTrack> tracks = item.getTracks();
-		boolean regist = item.isRegist();
-		if (regist) {
-			if (item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
-					|| item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
-					|| item.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
-
-				StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
-				if (streamAuthorityInfo == null) {
-					streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(item);
-				}else {
-					streamAuthorityInfo.setOriginType(item.getOriginType());
-					streamAuthorityInfo.setOriginTypeStr(item.getOriginTypeStr());
-				}
-				redisCatchStorage.updateStreamAuthorityInfo(app, stream, streamAuthorityInfo);
-			}
+		if (param.isRegist()) {
+			logger.info("[ZLM HOOK] 娴佹敞鍐�, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
 		}else {
-			redisCatchStorage.removeStreamAuthorityInfo(app, stream);
+			logger.info("[ZLM HOOK] 娴佹敞閿�, {}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
 		}
 
-		if ("rtsp".equals(schema)){
-			logger.info("on_stream_changed锛氭敞鍐�->{}, app->{}, stream->{}", regist, app, stream);
-			if (regist) {
-				mediaServerService.addCount(mediaServerId);
-			}else {
-				mediaServerService.removeCount(mediaServerId);
-			}
-			if (item.getOriginType() == OriginType.PULL.ordinal()
-					|| item.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
-				// 璁剧疆鎷夋祦浠g悊涓婄嚎/绂荤嚎
-				streamProxyService.updateStatus(regist, app, stream);
-			}
-			if ("rtp".equals(app) && !regist ) {
-				StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(stream);
-				if (streamInfo!=null){
-					redisCatchStorage.stopPlay(streamInfo);
-					storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
-				}else{
-					streamInfo = redisCatchStorage.queryPlayback(null, null, stream, null);
-					if (streamInfo != null) {
-						redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(),
-								streamInfo.getStream(), null);
-					}
-				}
-			}else {
-				if (!"rtp".equals(app)){
-					String type = OriginType.values()[item.getOriginType()].getType();
-					MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
 
-					if (mediaServerItem != null){
-						if (regist) {
-							StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
-							String callId = null;
-							if (streamAuthorityInfo != null) {
-								callId = streamAuthorityInfo.getCallId();
-							}
-							StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem,
-									app, stream, tracks, callId);
-							item.setStreamInfo(streamInfoByAppAndStream);
-							redisCatchStorage.addStream(mediaServerItem, type, app, stream, item);
-							if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
-									|| item.getOriginType() == OriginType.RTMP_PUSH.ordinal()
-									|| item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
-								item.setSeverId(userSetting.getServerId());
-								zlmMediaListManager.addPush(item);
-							}
-						}else {
-							// 鍏煎娴佹敞閿�鏃剁被鍨嬩粠redis璁板綍鑾峰彇
-							MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, stream, mediaServerId);
-							if (mediaItem != null) {
-								type = OriginType.values()[mediaItem.getOriginType()].getType();
-								redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, stream);
-							}
-							GbStream gbStream = storager.getGbStream(app, stream);
-							if (gbStream != null) {
-//								eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
-							}
-							zlmMediaListManager.removeMedia(app, stream);
-						}
-						if (type != null) {
-							// 鍙戦�佹祦鍙樺寲redis娑堟伅
-							JSONObject jsonObject = new JSONObject();
-							jsonObject.put("serverId", userSetting.getServerId());
-							jsonObject.put("app", app);
-							jsonObject.put("stream", stream);
-							jsonObject.put("register", regist);
-							jsonObject.put("mediaServerId", mediaServerId);
-							redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
-						}
-					}
+		JSONObject json = (JSONObject) JSON.toJSON(param);
+		taskExecutor.execute(()->{
+			ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_stream_changed, json);
+			if (subscribe != null ) {
+				MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId());
+				if (mediaInfo != null) {
+					subscribe.response(mediaInfo, json);
 				}
 			}
-			if (!regist) {
-				List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(stream);
-				if (sendRtpItems.size() > 0) {
-					for (SendRtpItem sendRtpItem : sendRtpItems) {
-						if (sendRtpItem.getApp().equals(app)) {
-							String platformId = sendRtpItem.getPlatformId();
-							ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
-							Device device = deviceService.getDevice(platformId);
+			// 娴佹秷澶辩Щ闄edis play
+			List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
+			if (param.isRegist()) {
+				if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
+						|| param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
+						|| param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
 
-							try {
-								if (platform != null) {
-									commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
-								}else {
-									cmder.streamByeCmd(device, sendRtpItem.getChannelId(), stream, sendRtpItem.getCallId());
+					StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
+					if (streamAuthorityInfo == null) {
+						streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
+					}else {
+						streamAuthorityInfo.setOriginType(param.getOriginType());
+						streamAuthorityInfo.setOriginTypeStr(param.getOriginTypeStr());
+					}
+					redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
+				}
+			}else {
+				redisCatchStorage.removeStreamAuthorityInfo(param.getApp(), param.getStream());
+			}
+
+			if ("rtsp".equals(param.getSchema())){
+				if (param.isRegist()) {
+					mediaServerService.addCount(param.getMediaServerId());
+				}else {
+					mediaServerService.removeCount(param.getMediaServerId());
+				}
+				if (param.getOriginType() == OriginType.PULL.ordinal()
+						|| param.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
+					// 璁剧疆鎷夋祦浠g悊涓婄嚎/绂荤嚎
+					streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream());
+				}
+				if ("rtp".equals(param.getApp()) && !param.isRegist() ) {
+					StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(param.getStream());
+					if (streamInfo!=null){
+						redisCatchStorage.stopPlay(streamInfo);
+						storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
+					}else{
+						streamInfo = redisCatchStorage.queryPlayback(null, null, param.getStream(), null);
+						if (streamInfo != null) {
+							redisCatchStorage.stopPlayback(streamInfo.getDeviceID(), streamInfo.getChannelId(),
+									streamInfo.getStream(), null);
+						}
+					}
+				}else {
+					if (!"rtp".equals(param.getApp())){
+						String type = OriginType.values()[param.getOriginType()].getType();
+						MediaServerItem mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+
+						if (mediaServerItem != null){
+							if (param.isRegist()) {
+								StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
+								String callId = null;
+								if (streamAuthorityInfo != null) {
+									callId = streamAuthorityInfo.getCallId();
 								}
-							} catch (SipException | InvalidArgumentException | ParseException | SsrcTransactionNotFoundException e) {
-								logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage());
+								StreamInfo streamInfoByAppAndStream = mediaService.getStreamInfoByAppAndStream(mediaServerItem,
+										param.getApp(), param.getStream(), tracks, callId);
+								param.setStreamInfo(streamInfoByAppAndStream);
+								redisCatchStorage.addStream(mediaServerItem, type, param.getApp(), param.getStream(), param);
+								if (param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
+										|| param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
+										|| param.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
+									param.setSeverId(userSetting.getServerId());
+									zlmMediaListManager.addPush(param);
+								}
+							}else {
+								// 鍏煎娴佹敞閿�鏃剁被鍨嬩粠redis璁板綍鑾峰彇
+								OnStreamChangedHookParam onStreamChangedHookParam = redisCatchStorage.getStreamInfo(param.getApp(), param.getStream(), param.getMediaServerId());
+								if (onStreamChangedHookParam != null) {
+									type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType();
+									redisCatchStorage.removeStream(mediaServerItem.getId(), type, param.getApp(), param.getStream());
+								}
+								GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
+								if (gbStream != null) {
+//								eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF);
+								}
+								zlmMediaListManager.removeMedia(param.getApp(), param.getStream());
+							}
+							if (type != null) {
+								// 鍙戦�佹祦鍙樺寲redis娑堟伅
+								JSONObject jsonObject = new JSONObject();
+								jsonObject.put("serverId", userSetting.getServerId());
+								jsonObject.put("app", param.getApp());
+								jsonObject.put("stream", param.getStream());
+								jsonObject.put("register", param.isRegist());
+								jsonObject.put("mediaServerId", param.getMediaServerId());
+								redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
+							}
+						}
+					}
+				}
+				if (!param.isRegist()) {
+					List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream());
+					if (sendRtpItems.size() > 0) {
+						for (SendRtpItem sendRtpItem : sendRtpItems) {
+							if (sendRtpItem.getApp().equals(param.getApp())) {
+								String platformId = sendRtpItem.getPlatformId();
+								ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
+								Device device = deviceService.getDevice(platformId);
+
+								try {
+									if (platform != null) {
+										commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
+									}else {
+										cmder.streamByeCmd(device, sendRtpItem.getChannelId(), param.getStream(), sendRtpItem.getCallId());
+									}
+								} catch (SipException | InvalidArgumentException | ParseException | SsrcTransactionNotFoundException e) {
+									logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage());
+								}
 							}
 						}
 					}
 				}
 			}
-		}
+		});
 
 		JSONObject ret = new JSONObject();
 		ret.put("code", 0);
@@ -550,19 +419,16 @@
 	 */
 	@ResponseBody
 	@PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8")
-	public JSONObject onStreamNoneReader(@RequestBody JSONObject json){
+	public JSONObject onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param){
 
-		logger.info("[ ZLM HOOK ]on_stream_none_reader API璋冪敤锛屽弬鏁帮細" + json.toString());
-		String mediaServerId = json.getString("mediaServerId");
-		String streamId = json.getString("stream");
-		String app = json.getString("app");
+		logger.info("[ZLM HOOK]娴佹棤浜鸿鐪嬶細{]->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
 		JSONObject ret = new JSONObject();
 		ret.put("code", 0);
 		// 褰曞儚涓嬭浇
-		ret.put("close", userSetting.getStreamOnDemand());
-		if ("rtp".equals(app)){
+		if ("rtp".equals(param.getApp())){
+			ret.put("close", userSetting.getStreamOnDemand());
 			// 鍥芥爣娴侊紝 鐐规挱/褰曞儚鍥炴斁/褰曞儚涓嬭浇
-			StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(streamId);
+			StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(param.getStream());
 			// 鐐规挱
 			if (streamInfoForPlayCatch != null) {
 				// 鏀跺埌鏃犱汉瑙傜湅璇存槑娴佷篃娌℃湁鍦ㄥ線涓婄骇鎺ㄩ��
@@ -596,7 +462,7 @@
 				return ret;
 			}
 			// 褰曞儚鍥炴斁
-			StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, streamId, null);
+			StreamInfo streamInfoForPlayBackCatch = redisCatchStorage.queryPlayback(null, null, param.getStream(), null);
 			if (streamInfoForPlayBackCatch != null ) {
 				if (streamInfoForPlayBackCatch.isPause()) {
 					ret.put("close", false);
@@ -617,7 +483,7 @@
 				return ret;
 			}
 			// 褰曞儚涓嬭浇
-			StreamInfo streamInfoForDownload = redisCatchStorage.queryDownload(null, null, streamId, null);
+			StreamInfo streamInfoForDownload = redisCatchStorage.queryDownload(null, null, param.getStream(), null);
 			// 杩涜褰曞儚涓嬭浇鏃舵棤浜鸿鐪嬩笉鏂祦
 			if (streamInfoForDownload != null) {
 				ret.put("close", false);
@@ -626,19 +492,19 @@
 		}else {
 			// 闈炲浗鏍囨祦 鎺ㄦ祦/鎷夋祦浠g悊
 			// 鎷夋祦浠g悊
-			StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, streamId);
+			StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
 			if (streamProxyItem != null ) {
 				if (streamProxyItem.isEnable_remove_none_reader()) {
 					// 鏃犱汉瑙傜湅鑷姩绉婚櫎
 					ret.put("close", true);
-					streamProxyService.del(app, streamId);
+					streamProxyService.del(param.getApp(), param.getStream());
 					String url = streamProxyItem.getUrl() != null?streamProxyItem.getUrl():streamProxyItem.getSrc_url();
-					logger.info("[{}/{}]<-[{}] 鎷夋祦浠g悊鏃犱汉瑙傜湅宸茬粡绉婚櫎",  app, streamId, url);
+					logger.info("[{}/{}]<-[{}] 鎷夋祦浠g悊鏃犱汉瑙傜湅宸茬粡绉婚櫎",  param.getApp(), param.getStream(), url);
 				}else if (streamProxyItem.isEnable_disable_none_reader()) {
 					// 鏃犱汉瑙傜湅鍋滅敤
 					ret.put("close", true);
 					// 淇敼鏁版嵁
-					streamProxyService.stop(app, streamId);
+					streamProxyService.stop(param.getApp(), param.getStream());
 				}else {
 					ret.put("close", false);
 				}
@@ -660,35 +526,33 @@
 	 */
 	@ResponseBody
 	@PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8")
-	public JSONObject onStreamNotFound(@RequestBody JSONObject json){
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_stream_not_found API璋冪敤锛屽弬鏁帮細" + json.toString());
-		}
-		String mediaServerId = json.getString("mediaServerId");
-		MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
-		if (userSetting.isAutoApplyPlay() && mediaInfo != null) {
-			String app = json.getString("app");
-			String streamId = json.getString("stream");
-			if ("rtp".equals(app)) {
-				if (mediaInfo.isRtpEnable()) {
-					String[] s = streamId.split("_");
-					if (s.length == 2) {
-						String deviceId = s[0];
-						String channelId = s[1];
-						Device device = redisCatchStorage.getDevice(deviceId);
-						if (device != null) {
-							playService.play(mediaInfo,deviceId, channelId, null, null, null);
+	public JSONObject onStreamNotFound(@RequestBody OnStreamNotFoundHookParam param){
+		logger.info("[ZLM HOOK] 娴佹湭鎵惧埌锛歿}->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
+		taskExecutor.execute(()->{
+			MediaServerItem mediaInfo = mediaServerService.getOne(param.getMediaServerId());
+			if (userSetting.isAutoApplyPlay() && mediaInfo != null) {
+				if ("rtp".equals(param.getApp())) {
+					if (mediaInfo.isRtpEnable()) {
+						String[] s = param.getStream().split("_");
+						if (s.length == 2) {
+							String deviceId = s[0];
+							String channelId = s[1];
+							Device device = redisCatchStorage.getDevice(deviceId);
+							if (device != null) {
+								playService.play(mediaInfo,deviceId, channelId, null, null, null);
+							}
 						}
 					}
-				}
-			}else {
-				// 鎷夋祦浠g悊
-				StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(app, streamId);
-				if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnable_disable_none_reader()) {
-					streamProxyService.start(app, streamId);
+				}else {
+					// 鎷夋祦浠g悊
+					StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
+					if (streamProxyByAppAndStream != null && streamProxyByAppAndStream.isEnable_disable_none_reader()) {
+						streamProxyService.start(param.getApp(), param.getStream());
+					}
 				}
 			}
-		}
+		});
+
 
 		JSONObject ret = new JSONObject();
 		ret.put("code", 0);
@@ -704,22 +568,20 @@
 	@PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8")
 	public JSONObject onServerStarted(HttpServletRequest request, @RequestBody JSONObject jsonObject){
 
-		if (logger.isDebugEnabled()) {
-			logger.debug("[ ZLM HOOK ]on_server_started API璋冪敤锛屽弬鏁帮細" + jsonObject.toString());
-		}
-		String remoteAddr = request.getRemoteAddr();
-		jsonObject.put("ip", remoteAddr);
-		List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started);
-		if (subscribes != null  && subscribes.size() > 0) {
-			for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
-				subscribe.response(null, jsonObject);
+		jsonObject.put("ip", request.getRemoteAddr());
+		ZLMServerConfig zlmServerConfig = JSON.to(ZLMServerConfig.class, jsonObject);
+		zlmServerConfig.setIp(request.getRemoteAddr());
+		logger.info("[ZLM HOOK] zlm 鍚姩 " + zlmServerConfig.getGeneralMediaServerId());
+		taskExecutor.execute(()->{
+			List<ZlmHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(HookType.on_server_started);
+			if (subscribes != null  && subscribes.size() > 0) {
+				for (ZlmHttpHookSubscribe.Event subscribe : subscribes) {
+					subscribe.response(null, jsonObject);
+				}
 			}
-		}
-
-		ZLMServerConfig zlmServerConfig = jsonObject.to(ZLMServerConfig.class);
-		if (zlmServerConfig !=null ) {
 			mediaServerService.zlmServerOnline(zlmServerConfig);
-		}
+		});
+
 		JSONObject ret = new JSONObject();
 		ret.put("code", 0);
 		ret.put("msg", "success");
@@ -731,33 +593,33 @@
 	 */
 	@ResponseBody
 	@PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8")
-	public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody JSONObject jsonObject){
+	public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param){
 
-		logger.info("[ ZLM HOOK ]on_send_rtp_stopped API璋冪敤锛屽弬鏁帮細" + jsonObject);
+		logger.info("[ZLM HOOK] 鍙戦�乺tp琚姩鍏抽棴锛歿}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
 
 		JSONObject ret = new JSONObject();
 		ret.put("code", 0);
 		ret.put("msg", "success");
 
 		// 鏌ユ壘瀵瑰簲鐨勪笂绾ф帹娴侊紝鍙戦�佸仠姝�
-		String app = jsonObject.getString("app");
-		if (!"rtp".equals(app)) {
+		if (!"rtp".equals(param.getApp())) {
 			return ret;
 		}
-		String stream = jsonObject.getString("stream");
-		List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(stream);
-		if (sendRtpItems.size() > 0) {
-			for (SendRtpItem sendRtpItem : sendRtpItems) {
-				ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
-				try {
-					commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
-				} catch (SipException | InvalidArgumentException | ParseException e) {
-					logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage());
+		taskExecutor.execute(()->{
+			List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(param.getStream());
+			if (sendRtpItems.size() > 0) {
+				for (SendRtpItem sendRtpItem : sendRtpItems) {
+					ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
+					try {
+						commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
+					} catch (SipException | InvalidArgumentException | ParseException e) {
+						logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage());
+					}
+					redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
+							sendRtpItem.getCallId(), sendRtpItem.getStreamId());
 				}
-				redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
-						sendRtpItem.getCallId(), sendRtpItem.getStreamId());
 			}
-		}
+		});
 
 
 		return ret;
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
index d615980..db2beb0 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java
@@ -3,6 +3,7 @@
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
 import com.genersoft.iot.vmp.media.zlm.dto.*;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.IStreamProxyService;
 import com.genersoft.iot.vmp.service.IStreamPushService;
@@ -67,19 +68,19 @@
 
     private Map<String, ChannelOnlineEvent> channelOnPublishEvents = new ConcurrentHashMap<>();
 
-    public StreamPushItem addPush(MediaItem mediaItem) {
-        StreamPushItem transform = streamPushService.transform(mediaItem);
-        StreamPushItem pushInDb = streamPushService.getPush(mediaItem.getApp(), mediaItem.getStream());
-        transform.setPushIng(mediaItem.isRegist());
+    public StreamPushItem addPush(OnStreamChangedHookParam onStreamChangedHookParam) {
+        StreamPushItem transform = streamPushService.transform(onStreamChangedHookParam);
+        StreamPushItem pushInDb = streamPushService.getPush(onStreamChangedHookParam.getApp(), onStreamChangedHookParam.getStream());
+        transform.setPushIng(onStreamChangedHookParam.isRegist());
         transform.setUpdateTime(DateUtil.getNow());
         transform.setPushTime(DateUtil.getNow());
-        transform.setSelf(userSetting.getServerId().equals(mediaItem.getSeverId()));
+        transform.setSelf(userSetting.getServerId().equals(onStreamChangedHookParam.getSeverId()));
         if (pushInDb == null) {
             transform.setCreateTime(DateUtil.getNow());
             streamPushMapper.add(transform);
         }else {
             streamPushMapper.update(transform);
-            gbStreamMapper.updateMediaServer(mediaItem.getApp(), mediaItem.getStream(), mediaItem.getMediaServerId());
+            gbStreamMapper.updateMediaServer(onStreamChangedHookParam.getApp(), onStreamChangedHookParam.getStream(), onStreamChangedHookParam.getMediaServerId());
         }
         ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(transform.getApp(), transform.getStream());
         if ( channelOnlineEventLister != null)  {
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ServerKeepaliveData.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ServerKeepaliveData.java
new file mode 100644
index 0000000..0cc81f2
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/ServerKeepaliveData.java
@@ -0,0 +1,4 @@
+package com.genersoft.iot.vmp.media.zlm.dto;
+
+public class ServerKeepaliveData {
+}
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 36a0363..ef77225 100644
--- 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,5 +1,8 @@
 package com.genersoft.iot.vmp.media.zlm.dto;
 
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnPublishHookParam;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+
 /**
  * 娴佺殑閴存潈淇℃伅
  * @author lin
@@ -102,13 +105,13 @@
         return streamAuthorityInfo;
     }
 
-    public static StreamAuthorityInfo getInstanceByHook(MediaItem mediaItem) {
+    public static StreamAuthorityInfo getInstanceByHook(OnStreamChangedHookParam onStreamChangedHookParam) {
         StreamAuthorityInfo streamAuthorityInfo = new StreamAuthorityInfo();
-        streamAuthorityInfo.setApp(mediaItem.getApp());
-        streamAuthorityInfo.setStream(mediaItem.getStream());
-        streamAuthorityInfo.setId(mediaItem.getMediaServerId());
-        streamAuthorityInfo.setOriginType(mediaItem.getOriginType());
-        streamAuthorityInfo.setOriginTypeStr(mediaItem.getOriginTypeStr());
+        streamAuthorityInfo.setApp(onStreamChangedHookParam.getApp());
+        streamAuthorityInfo.setStream(onStreamChangedHookParam.getStream());
+        streamAuthorityInfo.setId(onStreamChangedHookParam.getMediaServerId());
+        streamAuthorityInfo.setOriginType(onStreamChangedHookParam.getOriginType());
+        streamAuthorityInfo.setOriginTypeStr(onStreamChangedHookParam.getOriginTypeStr());
         return streamAuthorityInfo;
     }
 }
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 1a73a20..ddcfbdd 100644
--- 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
@@ -1,10 +1,10 @@
 package com.genersoft.iot.vmp.media.zlm.dto;
 
 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
+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;
 import org.jetbrains.annotations.NotNull;
-import org.springframework.util.unit.DataUnit;
 
 import java.util.List;
 
@@ -59,7 +59,7 @@
      * 瀹㈡埛绔拰鏈嶅姟鍣ㄧ綉缁滀俊鎭紝鍙兘涓簄ull绫诲瀷
      */
     @Schema(description = "瀹㈡埛绔拰鏈嶅姟鍣ㄧ綉缁滀俊鎭紝鍙兘涓簄ull绫诲瀷")
-    private MediaItem.OriginSock originSock;
+    private OnStreamChangedHookParam.OriginSock originSock;
 
     /**
      * 浜х敓婧愮被鍨嬬殑瀛楃涓叉弿杩�
@@ -83,7 +83,7 @@
      * 闊宠棰戣建閬�
      */
     @Schema(description = "闊宠棰戣建閬�")
-    private List<MediaItem.MediaTrack> tracks;
+    private List<OnStreamChangedHookParam.MediaTrack> tracks;
 
     /**
      * 闊宠棰戣建閬�
@@ -223,11 +223,11 @@
         this.originType = originType;
     }
 
-    public MediaItem.OriginSock getOriginSock() {
+    public OnStreamChangedHookParam.OriginSock getOriginSock() {
         return originSock;
     }
 
-    public void setOriginSock(MediaItem.OriginSock originSock) {
+    public void setOriginSock(OnStreamChangedHookParam.OriginSock originSock) {
         this.originSock = originSock;
     }
 
@@ -256,11 +256,11 @@
         this.aliveSecond = aliveSecond;
     }
 
-    public List<MediaItem.MediaTrack> getTracks() {
+    public List<OnStreamChangedHookParam.MediaTrack> getTracks() {
         return tracks;
     }
 
-    public void setTracks(List<MediaItem.MediaTrack> tracks) {
+    public void setTracks(List<OnStreamChangedHookParam.MediaTrack> tracks) {
         this.tracks = tracks;
     }
 
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java
similarity index 85%
rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookParam.java
rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java
index 50e3723..46ccf22 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/HookParam.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/HookParam.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.zlm.dto;
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
 
 /**
  * zlm hook浜嬩欢鐨勫弬鏁�
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPlayHookParam.java
similarity index 87%
rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java
rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPlayHookParam.java
index 92ecb47..4d2c26f 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPlayHookParam.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.zlm.dto;
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
 
 /**
  * zlm hook浜嬩欢涓殑on_play浜嬩欢鐨勫弬鏁�
@@ -79,4 +79,8 @@
         this.vhost = vhost;
     }
 
+    @Override
+    public String toString() {
+        return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params);
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPublishHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java
similarity index 87%
rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPublishHookParam.java
rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java
index 354c119..e353163 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPublishHookParam.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnPublishHookParam.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.zlm.dto;
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
 
 /**
  * zlm hook浜嬩欢涓殑on_publish浜嬩欢鐨勫弬鏁�
@@ -79,4 +79,8 @@
         this.vhost = vhost;
     }
 
+    @Override
+    public String toString() {
+        return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params);
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnSendRtpStoppedHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnSendRtpStoppedHookParam.java
new file mode 100644
index 0000000..bbdada9
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnSendRtpStoppedHookParam.java
@@ -0,0 +1,27 @@
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
+
+/**
+ * zlm hook浜嬩欢涓殑on_send_rtp_stopped浜嬩欢鐨勫弬鏁�
+ * @author lin
+ */
+public class OnSendRtpStoppedHookParam extends HookParam{
+    private String app;
+    private String stream;
+
+
+    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;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnServerKeepaliveHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnServerKeepaliveHookParam.java
new file mode 100644
index 0000000..2336056
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnServerKeepaliveHookParam.java
@@ -0,0 +1,20 @@
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
+
+import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData;
+
+/**
+ * zlm hook浜嬩欢涓殑on_play浜嬩欢鐨勫弬鏁�
+ * @author lin
+ */
+public class OnServerKeepaliveHookParam extends HookParam{
+
+    private ServerKeepaliveData data;
+
+    public ServerKeepaliveData getData() {
+        return data;
+    }
+
+    public void setData(ServerKeepaliveData data) {
+        this.data = data;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
similarity index 95%
rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
index 96cbfbd..29f91c8 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamChangedHookParam.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.zlm.dto;
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
 
 import com.genersoft.iot.vmp.common.StreamInfo;
 
@@ -7,7 +7,7 @@
 /**
  * @author lin
  */
-public class MediaItem {
+public class OnStreamChangedHookParam extends HookParam{
 
     /**
      * 娉ㄥ唽/娉ㄩ攢
@@ -67,11 +67,6 @@
      * 浜х敓婧愮殑url
      */
     private String originUrl;
-
-    /**
-     * 娴佸獟浣撴湇鍔″櫒id
-     */
-    private String mediaServerId;
 
     /**
      * 鏈嶅姟鍣╥d
@@ -410,14 +405,6 @@
 
     public void setDocker(boolean docker) {
         this.docker = docker;
-    }
-
-    public String getMediaServerId() {
-        return mediaServerId;
-    }
-
-    public void setMediaServerId(String mediaServerId) {
-        this.mediaServerId = mediaServerId;
     }
 
     public StreamInfo getStreamInfo() {
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNoneReaderHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNoneReaderHookParam.java
new file mode 100644
index 0000000..0282ee5
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNoneReaderHookParam.java
@@ -0,0 +1,41 @@
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
+
+public class OnStreamNoneReaderHookParam extends HookParam{
+
+    private String schema;
+    private String app;
+    private String stream;
+    private String vhost;
+
+    public String getSchema() {
+        return schema;
+    }
+
+    public void setSchema(String schema) {
+        this.schema = 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 String getVhost() {
+        return vhost;
+    }
+
+    public void setVhost(String vhost) {
+        this.vhost = vhost;
+    }
+}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNotFoundHookParam.java
similarity index 80%
copy from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java
copy to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNotFoundHookParam.java
index 92ecb47..20fdf82 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OnPlayHookParam.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnStreamNotFoundHookParam.java
@@ -1,10 +1,10 @@
-package com.genersoft.iot.vmp.media.zlm.dto;
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
 
 /**
- * zlm hook浜嬩欢涓殑on_play浜嬩欢鐨勫弬鏁�
+ * zlm hook浜嬩欢涓殑on_stream_not_found浜嬩欢鐨勫弬鏁�
  * @author lin
  */
-public class OnPlayHookParam extends HookParam{
+public class OnStreamNotFoundHookParam extends HookParam{
     private String id;
     private String app;
     private String stream;
@@ -79,4 +79,8 @@
         this.vhost = vhost;
     }
 
+    @Override
+    public String toString() {
+        return String.format("%s://%s:%s/%s/%s?%s", schema, ip, port, app, stream, params);
+    }
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OriginType.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OriginType.java
similarity index 89%
rename from src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OriginType.java
rename to src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OriginType.java
index 630e825..926cf4d 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/OriginType.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OriginType.java
@@ -1,4 +1,4 @@
-package com.genersoft.iot.vmp.media.zlm.dto;
+package com.genersoft.iot.vmp.media.zlm.dto.hook;
 
 public enum OriginType {
     // 涓嶅彲璋冩暣椤哄簭
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
index 1a463cf..f8d5869 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IMediaServerService.java
@@ -4,6 +4,7 @@
 import com.genersoft.iot.vmp.gb28181.bean.Device;
 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
+import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData;
 import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
@@ -86,7 +87,7 @@
 
     MediaServerItem getDefaultMediaServer();
 
-    void updateMediaServerKeepalive(String mediaServerId, JSONObject data);
+    void updateMediaServerKeepalive(String mediaServerId, ServerKeepaliveData data);
 
     boolean checkRtpServer(MediaServerItem mediaServerItem, String rtp, String stream);
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
index 4bccc3f..8885ed5 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IStreamPushService.java
@@ -1,13 +1,11 @@
 package com.genersoft.iot.vmp.service;
 
 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
-import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
 import com.genersoft.iot.vmp.service.bean.StreamPushItemFromRedis;
 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
-import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto;
 import com.github.pagehelper.PageInfo;
 
 import java.util.List;
@@ -38,7 +36,7 @@
 
     List<StreamPushItem> getPushList(String mediaSererId);
 
-    StreamPushItem transform(MediaItem item);
+    StreamPushItem transform(OnStreamChangedHookParam item);
 
     StreamPushItem getPush(String app, String streamId);
 
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
index 6634608..1f53c7f 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -10,6 +10,7 @@
 
 import com.genersoft.iot.vmp.conf.DynamicTask;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
+import com.genersoft.iot.vmp.media.zlm.dto.ServerKeepaliveData;
 import com.genersoft.iot.vmp.service.bean.MediaServerLoad;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
@@ -434,7 +435,7 @@
             if (mediaServerConfig != null && mediaServerConfig.getInteger("code") == 0) {
                 logger.info("[zlm蹇冭烦鍒版湡]锛歿}楠岃瘉鍚巣lm浠嶅湪绾匡紝鎭㈠蹇冭烦淇℃伅,璇锋鏌lm鏄惁鍙互姝e父鍚憌vp鍙戦�佸績璺�", serverItem.getId());
                 // 娣诲姞zlm淇℃伅
-                updateMediaServerKeepalive(serverItem.getId(), mediaServerConfig);
+                updateMediaServerKeepalive(serverItem.getId(), null);
             }else {
                 publisher.zlmOfflineEventPublish(serverItem.getId());
             }
@@ -526,15 +527,15 @@
         Map<String, Object> param = new HashMap<>();
         param.put("api.secret",mediaServerItem.getSecret()); // -profile:v Baseline
         param.put("hook.enable","1");
-        param.put("hook.on_flow_report",String.format("%s/on_flow_report", hookPrex));
+        param.put("hook.on_flow_report","");
         param.put("hook.on_play",String.format("%s/on_play", hookPrex));
-        param.put("hook.on_http_access",String.format("%s/on_http_access", hookPrex));
+        param.put("hook.on_http_access","");
         param.put("hook.on_publish", String.format("%s/on_publish", hookPrex));
-        param.put("hook.on_record_ts",String.format("%s/on_record_ts", hookPrex));
-        param.put("hook.on_rtsp_auth",String.format("%s/on_rtsp_auth", hookPrex));
-        param.put("hook.on_rtsp_realm",String.format("%s/on_rtsp_realm", hookPrex));
+        param.put("hook.on_record_ts","");
+        param.put("hook.on_rtsp_auth","");
+        param.put("hook.on_rtsp_realm","");
         param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrex));
-        param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex));
+        param.put("hook.on_shell_login","");
         param.put("hook.on_stream_changed",String.format("%s/on_stream_changed", hookPrex));
         param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
         param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
@@ -551,6 +552,7 @@
         // 姝ゅ弬鏁颁笉搴斿ぇ浜庢挱鏀惧櫒瓒呮椂鏃堕棿
         // 浼樺寲姝ゆ秷鎭互鏇村揩鐨勬敹鍒版祦娉ㄩ攢浜嬩欢
         param.put("general.continue_push_ms", "3000" );
+        param.put("general.publishToHls", "0" );
         // 鏈�澶氱瓑寰呮湭鍒濆鍖栫殑Track鏃堕棿锛屽崟浣嶆绉掞紝瓒呮椂涔嬪悗浼氬拷鐣ユ湭鍒濆鍖栫殑Track, 璁剧疆姝ら�夐」浼樺寲閭d簺闊抽閿欒鐨勪笉瑙勮寖娴侊紝
         // 绛墇lm鏀寔缁欐瘡涓猺tpServer璁剧疆鍏抽棴闊抽鐨勬椂鍊欏彲浠ヤ笉璁剧疆姝ら�夐」
 //        param.put("general.wait_track_ready_ms", "3000" );
@@ -645,7 +647,7 @@
     }
 
     @Override
-    public void updateMediaServerKeepalive(String mediaServerId, JSONObject data) {
+    public void updateMediaServerKeepalive(String mediaServerId, ServerKeepaliveData data) {
         MediaServerItem mediaServerItem = getOne(mediaServerId);
         if (mediaServerItem == null) {
             // 缂撳瓨涓嶅瓨鍦紝浠庢暟鎹簱鏌ヨ锛屽鏋滄暟鎹簱涓嶅瓨鍦ㄥ垯鏄敊璇殑
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 bfe8f04..e3a0018 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -7,7 +7,6 @@
 import com.genersoft.iot.vmp.conf.MediaConfig;
 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
-import com.genersoft.iot.vmp.media.zlm.dto.OnPublishHookParam;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
@@ -16,7 +15,6 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
 
 @Service
 public class MediaServiceImpl implements IMediaService {
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 d8c7f48..3183e3d 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -6,12 +6,10 @@
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.conf.exception.ControllerException;
 import com.genersoft.iot.vmp.gb28181.bean.GbStream;
-import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
-import com.genersoft.iot.vmp.gb28181.bean.TreeType;
 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
 import com.genersoft.iot.vmp.service.IGbStreamService;
@@ -27,7 +25,6 @@
 import com.genersoft.iot.vmp.utils.DateUtil;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo;
-import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
 import com.github.pagehelper.PageInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,9 +34,7 @@
 import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
 
-import java.net.InetAddress;
 import java.util.*;
 
 /**
@@ -389,18 +384,18 @@
         String type = "PULL";
 
         // 鍙戦�乺edis娑堟伅
-        List<MediaItem> mediaItems = redisCatchStorage.getStreams(mediaServerId, type);
-        if (mediaItems.size() > 0) {
-            for (MediaItem mediaItem : mediaItems) {
+        List<OnStreamChangedHookParam> onStreamChangedHookParams = redisCatchStorage.getStreams(mediaServerId, type);
+        if (onStreamChangedHookParams.size() > 0) {
+            for (OnStreamChangedHookParam onStreamChangedHookParam : onStreamChangedHookParams) {
                 JSONObject jsonObject = new JSONObject();
                 jsonObject.put("serverId", userSetting.getServerId());
-                jsonObject.put("app", mediaItem.getApp());
-                jsonObject.put("stream", mediaItem.getStream());
+                jsonObject.put("app", onStreamChangedHookParam.getApp());
+                jsonObject.put("stream", onStreamChangedHookParam.getStream());
                 jsonObject.put("register", false);
                 jsonObject.put("mediaServerId", mediaServerId);
                 redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
                 // 绉婚櫎redis鍐呮祦鐨勪俊鎭�
-                redisCatchStorage.removeStream(mediaServerId, type, mediaItem.getApp(), mediaItem.getStream());
+                redisCatchStorage.removeStream(mediaServerId, type, onStreamChangedHookParam.getApp(), onStreamChangedHookParam.getStream());
             }
         }
     }
@@ -418,7 +413,7 @@
     private void syncPullStream(String mediaServerId){
         MediaServerItem mediaServer = mediaServerService.getOne(mediaServerId);
         if (mediaServer != null) {
-            List<MediaItem> allPullStream = redisCatchStorage.getStreams(mediaServerId, "PULL");
+            List<OnStreamChangedHookParam> allPullStream = redisCatchStorage.getStreams(mediaServerId, "PULL");
             if (allPullStream.size() > 0) {
                 zlmresTfulUtils.getMediaList(mediaServer, jsonObject->{
                     Map<String, StreamInfo> stringStreamInfoMap = new HashMap<>();
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 bd2d535..ffbcb42 100644
--- 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,6 +11,8 @@
 import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
 import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
 import com.genersoft.iot.vmp.media.zlm.dto.*;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OriginType;
 import com.genersoft.iot.vmp.service.IGbStreamService;
 import com.genersoft.iot.vmp.service.IMediaServerService;
 import com.genersoft.iot.vmp.service.IStreamPushService;
@@ -29,7 +31,6 @@
 import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.util.ObjectUtils;
-import org.springframework.util.StringUtils;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -93,8 +94,8 @@
 
         Map<String, StreamPushItem> result = new HashMap<>();
 
-        List<MediaItem> mediaItems = JSON.parseObject(jsonData, new TypeReference<List<MediaItem>>() {});
-        for (MediaItem item : mediaItems) {
+        List<OnStreamChangedHookParam> onStreamChangedHookParams = JSON.parseObject(jsonData, new TypeReference<List<OnStreamChangedHookParam>>() {});
+        for (OnStreamChangedHookParam item : onStreamChangedHookParams) {
 
             // 涓嶄繚瀛樺浗鏍囨帹鐞嗕互鍙婃媺娴佷唬鐞嗙殑娴�
             if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal()
@@ -112,7 +113,7 @@
         return new ArrayList<>(result.values());
     }
     @Override
-    public StreamPushItem transform(MediaItem item) {
+    public StreamPushItem transform(OnStreamChangedHookParam item) {
         StreamPushItem streamPushItem = new StreamPushItem();
         streamPushItem.setApp(item.getApp());
         streamPushItem.setMediaServerId(item.getMediaServerId());
@@ -206,8 +207,8 @@
         List<StreamPushItem> pushList = getPushList(mediaServerId);
         Map<String, StreamPushItem> pushItemMap = new HashMap<>();
         // redis璁板綍
-        List<MediaItem> mediaItems = redisCatchStorage.getStreams(mediaServerId, "PUSH");
-        Map<String, MediaItem> streamInfoPushItemMap = new HashMap<>();
+        List<OnStreamChangedHookParam> onStreamChangedHookParams = redisCatchStorage.getStreams(mediaServerId, "PUSH");
+        Map<String, OnStreamChangedHookParam> streamInfoPushItemMap = new HashMap<>();
         if (pushList.size() > 0) {
             for (StreamPushItem streamPushItem : pushList) {
                 if (ObjectUtils.isEmpty(streamPushItem.getGbId())) {
@@ -215,9 +216,9 @@
                 }
             }
         }
-        if (mediaItems.size() > 0) {
-            for (MediaItem mediaItem : mediaItems) {
-                streamInfoPushItemMap.put(mediaItem.getApp() + mediaItem.getStream(), mediaItem);
+        if (onStreamChangedHookParams.size() > 0) {
+            for (OnStreamChangedHookParam onStreamChangedHookParam : onStreamChangedHookParams) {
+                streamInfoPushItemMap.put(onStreamChangedHookParam.getApp() + onStreamChangedHookParam.getStream(), onStreamChangedHookParam);
             }
         }
         zlmresTfulUtils.getMediaList(mediaServerItem, (mediaList ->{
@@ -258,19 +259,19 @@
                 }
 
             }
-            Collection<MediaItem> offlineMediaItemList = streamInfoPushItemMap.values();
-            if (offlineMediaItemList.size() > 0) {
+            Collection<OnStreamChangedHookParam> offlineOnStreamChangedHookParamList = streamInfoPushItemMap.values();
+            if (offlineOnStreamChangedHookParamList.size() > 0) {
                 String type = "PUSH";
-                for (MediaItem offlineMediaItem : offlineMediaItemList) {
+                for (OnStreamChangedHookParam offlineOnStreamChangedHookParam : offlineOnStreamChangedHookParamList) {
                     JSONObject jsonObject = new JSONObject();
                     jsonObject.put("serverId", userSetting.getServerId());
-                    jsonObject.put("app", offlineMediaItem.getApp());
-                    jsonObject.put("stream", offlineMediaItem.getStream());
+                    jsonObject.put("app", offlineOnStreamChangedHookParam.getApp());
+                    jsonObject.put("stream", offlineOnStreamChangedHookParam.getStream());
                     jsonObject.put("register", false);
                     jsonObject.put("mediaServerId", mediaServerId);
                     redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
                     // 绉婚櫎redis鍐呮祦鐨勪俊鎭�
-                    redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineMediaItem.getApp(), offlineMediaItem.getStream());
+                    redisCatchStorage.removeStream(mediaServerItem.getId(), "PUSH", offlineOnStreamChangedHookParam.getApp(), offlineOnStreamChangedHookParam.getStream());
                 }
             }
         }));
@@ -288,15 +289,15 @@
         // 鍙戦�佹祦鍋滄娑堟伅
         String type = "PUSH";
         // 鍙戦�乺edis娑堟伅
-        List<MediaItem> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
+        List<OnStreamChangedHookParam> streamInfoList = redisCatchStorage.getStreams(mediaServerId, type);
         if (streamInfoList.size() > 0) {
-            for (MediaItem mediaItem : streamInfoList) {
+            for (OnStreamChangedHookParam onStreamChangedHookParam : streamInfoList) {
                 // 绉婚櫎redis鍐呮祦鐨勪俊鎭�
-                redisCatchStorage.removeStream(mediaServerId, type, mediaItem.getApp(), mediaItem.getStream());
+                redisCatchStorage.removeStream(mediaServerId, type, onStreamChangedHookParam.getApp(), onStreamChangedHookParam.getStream());
                 JSONObject jsonObject = new JSONObject();
                 jsonObject.put("serverId", userSetting.getServerId());
-                jsonObject.put("app", mediaItem.getApp());
-                jsonObject.put("stream", mediaItem.getStream());
+                jsonObject.put("app", onStreamChangedHookParam.getApp());
+                jsonObject.put("stream", onStreamChangedHookParam.getStream());
                 jsonObject.put("register", false);
                 jsonObject.put("mediaServerId", mediaServerId);
                 redisCatchStorage.sendStreamChangeMsg(type, jsonObject);
diff --git a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
index d173027..3e73fc0 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisStreamMsgListener.java
@@ -5,7 +5,7 @@
 import com.genersoft.iot.vmp.conf.UserSetting;
 
 import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -66,20 +66,20 @@
                     String stream = steamMsgJson.getString("stream");
                     boolean register = steamMsgJson.getBoolean("register");
                     String mediaServerId = steamMsgJson.getString("mediaServerId");
-                    MediaItem mediaItem = new MediaItem();
-                    mediaItem.setSeverId(serverId);
-                    mediaItem.setApp(app);
-                    mediaItem.setStream(stream);
-                    mediaItem.setRegist(register);
-                    mediaItem.setMediaServerId(mediaServerId);
-                    mediaItem.setCreateStamp(System.currentTimeMillis()/1000);
-                    mediaItem.setAliveSecond(0L);
-                    mediaItem.setTotalReaderCount("0");
-                    mediaItem.setOriginType(0);
-                    mediaItem.setOriginTypeStr("0");
-                    mediaItem.setOriginTypeStr("unknown");
+                    OnStreamChangedHookParam onStreamChangedHookParam = new OnStreamChangedHookParam();
+                    onStreamChangedHookParam.setSeverId(serverId);
+                    onStreamChangedHookParam.setApp(app);
+                    onStreamChangedHookParam.setStream(stream);
+                    onStreamChangedHookParam.setRegist(register);
+                    onStreamChangedHookParam.setMediaServerId(mediaServerId);
+                    onStreamChangedHookParam.setCreateStamp(System.currentTimeMillis()/1000);
+                    onStreamChangedHookParam.setAliveSecond(0L);
+                    onStreamChangedHookParam.setTotalReaderCount("0");
+                    onStreamChangedHookParam.setOriginType(0);
+                    onStreamChangedHookParam.setOriginTypeStr("0");
+                    onStreamChangedHookParam.setOriginTypeStr("unknown");
                     if (register) {
-                        zlmMediaListManager.addPush(mediaItem);
+                        zlmMediaListManager.addPush(onStreamChangedHookParam);
                     }else {
                         zlmMediaListManager.removeMedia(app, stream);
                     }
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 81f3691..f9a223c 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java
@@ -5,9 +5,9 @@
 import com.genersoft.iot.vmp.common.SystemAllInfo;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.media.zlm.dto.*;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
 import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
-import com.genersoft.iot.vmp.service.bean.SSRCInfo;
 import com.genersoft.iot.vmp.service.bean.ThirdPartyGB;
 import com.genersoft.iot.vmp.storager.dao.dto.PlatformRegisterInfo;
 
@@ -131,7 +131,7 @@
      * @param app
      * @param streamId
      */
-    void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, MediaItem item);
+    void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, OnStreamChangedHookParam item);
 
     /**
      * 绉婚櫎娴佷俊鎭粠redis
@@ -165,7 +165,7 @@
      */
     ThirdPartyGB queryMemberNoGBId(String queryKey);
 
-    List<MediaItem> getStreams(String mediaServerId, String pull);
+    List<OnStreamChangedHookParam> getStreams(String mediaServerId, String pull);
 
     /**
      * 灏哾evice淇℃伅鍐欏叆redis
@@ -191,7 +191,7 @@
 
     void resetAllSN();
 
-    MediaItem getStreamInfo(String app, String streamId, String mediaServerId);
+    OnStreamChangedHookParam getStreamInfo(String app, String streamId, String mediaServerId);
 
     void addCpuInfo(double cpuInfo);
 
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 8fcf373..ca2e348 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java
@@ -7,7 +7,7 @@
 import com.genersoft.iot.vmp.common.VideoManagerConstants;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.gb28181.bean.*;
-import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
+import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
 import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
 import com.genersoft.iot.vmp.service.bean.GPSMsgInfo;
@@ -573,14 +573,14 @@
     }
 
     @Override
-    public void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, MediaItem mediaItem) {
+    public void addStream(MediaServerItem mediaServerItem, String type, String app, String streamId, OnStreamChangedHookParam onStreamChangedHookParam) {
         // 鏌ユ壘鏄惁浣跨敤浜哻allID
         StreamAuthorityInfo streamAuthorityInfo = getStreamAuthorityInfo(app, streamId);
         String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX  + userSetting.getServerId() + "_" + type + "_" + app + "_" + streamId + "_" + mediaServerItem.getId();
         if (streamAuthorityInfo != null) {
-            mediaItem.setCallId(streamAuthorityInfo.getCallId());
+            onStreamChangedHookParam.setCallId(streamAuthorityInfo.getCallId());
         }
-        RedisUtil.set(key, mediaItem);
+        RedisUtil.set(key, onStreamChangedHookParam);
     }
 
     @Override
@@ -638,13 +638,13 @@
     }
 
     @Override
-    public List<MediaItem> getStreams(String mediaServerId, String type) {
-        List<MediaItem> result = new ArrayList<>();
+    public List<OnStreamChangedHookParam> getStreams(String mediaServerId, String type) {
+        List<OnStreamChangedHookParam> result = new ArrayList<>();
         String key = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX + userSetting.getServerId() + "_" + type + "_*_*_" + mediaServerId;
         List<Object> streams = RedisUtil.scan(key);
         for (Object stream : streams) {
-            MediaItem mediaItem = (MediaItem)RedisUtil.get((String) stream);
-            result.add(mediaItem);
+            OnStreamChangedHookParam onStreamChangedHookParam = (OnStreamChangedHookParam)RedisUtil.get((String) stream);
+            result.add(onStreamChangedHookParam);
         }
         return result;
     }
@@ -716,14 +716,14 @@
 
 
     @Override
-    public MediaItem getStreamInfo(String app, String streamId, String mediaServerId) {
+    public OnStreamChangedHookParam getStreamInfo(String app, String streamId, String mediaServerId) {
         String scanKey = VideoManagerConstants.WVP_SERVER_STREAM_PREFIX  + userSetting.getServerId() + "_*_" + app + "_" + streamId + "_" + mediaServerId;
 
-        MediaItem result = null;
+        OnStreamChangedHookParam result = null;
         List<Object> keys = RedisUtil.scan(scanKey);
         if (keys.size() > 0) {
             String key = (String) keys.get(0);
-            result = (MediaItem)RedisUtil.get(key);
+            result = (OnStreamChangedHookParam)RedisUtil.get(key);
         }
 
         return result;
diff --git a/web_src/src/components/console/ConsoleResource.vue b/web_src/src/components/console/ConsoleResource.vue
index c76b270..64c1c49 100644
--- a/web_src/src/components/console/ConsoleResource.vue
+++ b/web_src/src/components/console/ConsoleResource.vue
@@ -1,28 +1,32 @@
 <template >
   <div id="consoleResource" style="width: 100%; height: 100%; background: #FFFFFF; text-align: center">
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="8" type="circle" :percentage="deviceInfo.online/deviceInfo.total*100" style="margin-top: 20px; font-size: 18px"></el-progress>
+      <el-progress :width="100" :stroke-width="8" type="circle" v-if="deviceInfo.total === 0" :percentage="0" style="margin-top: 20px; font-size: 18px"></el-progress>
+      <el-progress :width="100" :stroke-width="8" type="circle" v-if="deviceInfo.total > 0" :percentage="(deviceInfo.online/deviceInfo.total*100).toFixed(2)" style="margin-top: 20px; font-size: 18px"></el-progress>
       <div class="resourceInfo">
         璁惧鎬绘暟:{{deviceInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{deviceInfo.online}}
       </div>
     </div>
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="10" type="circle" :percentage="channelInfo.online/channelInfo.total*100" style="margin-top: 20px"></el-progress>
+      <el-progress :width="100" :stroke-width="10" type="circle" v-if="channelInfo.total === 0" :percentage="0" style="margin-top: 20px"></el-progress>
+      <el-progress :width="100" :stroke-width="10" type="circle" v-if="channelInfo.total > 0" :percentage="(channelInfo.online/channelInfo.total*100).toFixed(2)" style="margin-top: 20px"></el-progress>
       <div class="resourceInfo">
         閫氶亾鎬绘暟:{{channelInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{channelInfo.online}}
       </div>
     </div>
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="10" type="circle" :percentage="pushInfo.online/pushInfo.total*100" style="margin-top: 20px"></el-progress>
+      <el-progress :width="100" :stroke-width="10" type="circle" v-if="pushInfo.total === 0" :percentage="0" style="margin-top: 20px"></el-progress>
+      <el-progress :width="100" :stroke-width="10" type="circle" v-if="pushInfo.total > 0" :percentage="(pushInfo.online/pushInfo.total*100).toFixed(2)" style="margin-top: 20px"></el-progress>
       <div class="resourceInfo">
         鎺ㄦ祦鎬绘暟:{{pushInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{pushInfo.online}}
       </div>
     </div>
     <div style="width: 50%;height: 50%; float:left; ">
-      <el-progress :width="100" :stroke-width="10" type="circle" :percentage="proxyInfo.online/proxyInfo.total*100" style="margin-top: 20px"></el-progress>
+      <el-progress :width="100" :stroke-width="10" type="circle" v-if="proxyInfo.total === 0" :percentage="0" style="margin-top: 20px"></el-progress>
+      <el-progress :width="100" :stroke-width="10" type="circle" v-if="proxyInfo.total > 0" :percentage="(proxyInfo.online/proxyInfo.total*100).toFixed(2)" style="margin-top: 20px"></el-progress>
       <div class="resourceInfo">
         鎷夋祦浠g悊鎬绘暟:{{proxyInfo.total}}<br/>
         鍦ㄧ嚎鏁�:{{proxyInfo.online}}

--
Gitblit v1.8.0