From a42dda2bd3cc1cf8c20cc61e7ad9211eadecbaf3 Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期四, 24 二月 2022 16:55:06 +0800 Subject: [PATCH] 规范数据库,添加必要约束,优化通道批量导入功能 --- src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 252 +++++++++++++++++++++++++++++++++++++------------- 1 files changed, 186 insertions(+), 66 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 b7aebf4..4f45813 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 @@ -1,20 +1,22 @@ package com.genersoft.iot.vmp.media.zlm; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaConfig; import com.genersoft.iot.vmp.conf.UserSetup; import com.genersoft.iot.vmp.gb28181.bean.Device; -import com.genersoft.iot.vmp.media.zlm.dto.IMediaServerItem; -import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; -import com.genersoft.iot.vmp.service.IMediaServerService; +import com.genersoft.iot.vmp.gb28181.bean.GbStream; +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.dto.*; +import com.genersoft.iot.vmp.service.*; +import com.genersoft.iot.vmp.service.bean.SSRCInfo; import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorager; -import com.genersoft.iot.vmp.service.IPlayService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,7 +34,7 @@ import javax.servlet.http.HttpServletRequest; /** - * @Description:閽堝 ZLMediaServer鐨刪ook浜嬩欢鐩戝惉 + * @description:閽堝 ZLMediaServer鐨刪ook浜嬩欢鐩戝惉 * @author: swwheihei * @date: 2020骞�5鏈�8鏃� 涓婂崍10:46:48 */ @@ -41,7 +43,6 @@ public class ZLMHttpHookListener { private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class); - @Autowired private SIPCommander cmder; @@ -59,7 +60,16 @@ private IMediaServerService mediaServerService; @Autowired - private ZLMRESTfulUtils zlmresTfulUtils; + private IStreamProxyService streamProxyService; + + @Autowired + private IStreamPushService streamPushService; + + @Autowired + private IMediaService mediaService; + + @Autowired + private EventPublisher eventPublisher; @Autowired private ZLMMediaListManager zlmMediaListManager; @@ -74,6 +84,32 @@ private MediaConfig mediaConfig; /** + * 鏈嶅姟鍣ㄥ畾鏃朵笂鎶ユ椂闂达紝涓婃姤闂撮殧鍙厤缃紝榛樿10s涓婃姤涓�娆� + * + */ + @ResponseBody + @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8") + public ResponseEntity<String> onServerKeepalive(@RequestBody JSONObject json){ + + if (logger.isDebugEnabled()) { + logger.debug("[ ZLM HOOK ]on_server_keepalive API璋冪敤锛屽弬鏁帮細" + json.toString()); + } + String mediaServerId = json.getString("mediaServerId"); + + List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_keepalive); + if (subscribes != null && subscribes.size() > 0) { + for (ZLMHttpHookSubscribe.Event subscribe : subscribes) { + subscribe.response(null, json); + } + } + + JSONObject ret = new JSONObject(); + ret.put("code", 0); + ret.put("msg", "success"); + return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); + } + + /** * 娴侀噺缁熻浜嬩欢锛屾挱鏀惧櫒鎴栨帹娴佸櫒鏂紑鏃跺苟涓旇�楃敤娴侀噺瓒呰繃鐗瑰畾闃堝�兼椂浼氳Е鍙戞浜嬩欢锛岄槇鍊奸�氳繃閰嶇疆鏂囦欢general.flowThreshold閰嶇疆锛涙浜嬩欢瀵瑰洖澶嶄笉鏁忔劅銆� * */ @@ -82,7 +118,7 @@ public ResponseEntity<String> onFlowReport(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_flow_report API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_flow_report API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); JSONObject ret = new JSONObject(); @@ -100,7 +136,7 @@ public ResponseEntity<String> onHttpAccess(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_http_access API 璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_http_access API 璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); JSONObject ret = new JSONObject(); @@ -120,12 +156,12 @@ public ResponseEntity<String> onPlay(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_play API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_play API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_play, json); if (subscribe != null ) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } @@ -145,22 +181,38 @@ @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8") public ResponseEntity<String> onPublish(@RequestBody JSONObject json) { - logger.debug("ZLM HOOK on_publish API璋冪敤锛屽弬鏁帮細" + json.toString()); - - String mediaServerId = json.getString("mediaServerId"); - ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); - if (subscribe != null) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); - if (mediaInfo != null) { - subscribe.response(mediaInfo, json); - } - } + logger.debug("[ ZLM HOOK ]on_publish API璋冪敤锛屽弬鏁帮細" + json.toString()); JSONObject ret = new JSONObject(); ret.put("code", 0); ret.put("msg", "success"); ret.put("enableHls", true); - ret.put("enableMP4", userSetup.isRecordPushLive()); - ret.put("enableRtxp", true); + String mediaServerId = json.getString("mediaServerId"); + ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_publish, json); + if (subscribe != null) { + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + if (mediaInfo != null) { + subscribe.response(mediaInfo, json); + }else { + ret.put("code", 1); + ret.put("msg", "zlm not register"); + } + } + String app = json.getString("app"); + String stream = json.getString("stream"); + if ("rtp".equals(app)) { + ret.put("enableMP4", userSetup.getRecordSip()); + }else { + ret.put("enableMP4", userSetup.isRecordPushLive()); + } + StreamInfo streamInfo = redisCatchStorage.queryPlaybackByStreamId(stream); + + // 褰曞儚鍥炴斁鏃朵笉杩涜褰曞儚涓嬭浇 + if (streamInfo != null) { + ret.put("enableMP4", false); + }else { + ret.put("enableMP4", userSetup.isRecordPushLive()); + } + return new ResponseEntity<String>(ret.toString(), HttpStatus.OK); } @@ -173,7 +225,7 @@ public ResponseEntity<String> onRecordMp4(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_record_mp4 API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_record_mp4 API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); JSONObject ret = new JSONObject(); @@ -191,7 +243,7 @@ public ResponseEntity<String> onRtspRealm(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_rtsp_realm API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_rtsp_realm API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); JSONObject ret = new JSONObject(); @@ -210,7 +262,7 @@ public ResponseEntity<String> onRtspAuth(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_rtsp_auth API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_rtsp_auth API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); JSONObject ret = new JSONObject(); @@ -229,7 +281,7 @@ public ResponseEntity<String> onShellLogin(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_shell_login API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_shell_login API璋冪敤锛屽弬鏁帮細" + json.toString()); } // TODO 濡傛灉鏄甫鏈塺tpstream鍒欏紑鍚寜闇�鎷夋祦 // String app = json.getString("app"); @@ -237,7 +289,7 @@ String mediaServerId = json.getString("mediaServerId"); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_shell_login, json); if (subscribe != null ) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } @@ -256,35 +308,38 @@ */ @ResponseBody @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8") - public ResponseEntity<String> onStreamChanged(@RequestBody JSONObject json){ - + public ResponseEntity<String> onStreamChanged(@RequestBody MediaItem item){ + if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_stream_changed API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_stream_changed API璋冪敤锛屽弬鏁帮細" + JSONObject.toJSONString(item)); } - String mediaServerId = json.getString("mediaServerId"); + String mediaServerId = item.getMediaServerId(); + JSONObject json = (JSONObject) JSON.toJSON(item); ZLMHttpHookSubscribe.Event subscribe = this.subscribe.getSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, json); if (subscribe != null ) { - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (mediaInfo != null) { subscribe.response(mediaInfo, json); } } - // 娴佹秷澶辩Щ闄edis play - String app = json.getString("app"); - String streamId = json.getString("stream"); - String schema = json.getString("schema"); - JSONArray tracks = json.getJSONArray("tracks"); - boolean regist = json.getBoolean("regist"); - if (tracks != null) { - logger.info("[stream: " + streamId + "] on_stream_changed->>" + schema); - } + String app = item.getApp(); + String streamId = item.getStream(); + String schema = item.getSchema(); + List<MediaItem.MediaTrack> tracks = item.getTracks(); + boolean regist = item.isRegist(); if ("rtmp".equals(schema)){ + logger.info("on_stream_changed锛氭敞鍐�->{}, app->{}, stream->{}", regist, app, streamId); 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, streamId); } if ("rtp".equals(app) && !regist ) { StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); @@ -296,12 +351,56 @@ redisCatchStorage.stopPlayback(streamInfo); } }else { - if (!"rtp".equals(app) ){ - IMediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); - if (regist) { - zlmMediaListManager.addMedia(mediaServerItem, app, streamId); - }else { - zlmMediaListManager.removeMedia( app, streamId); + if (!"rtp".equals(app)){ + String type = OriginType.values()[item.getOriginType()].getType(); + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + + if (mediaServerItem != null){ + if (regist) { + StreamPushItem streamPushItem = null; + redisCatchStorage.addStream(mediaServerItem, type, app, streamId, item); + if (item.getOriginType() == OriginType.RTSP_PUSH.ordinal() + || item.getOriginType() == OriginType.RTMP_PUSH.ordinal() + || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { + streamPushItem = zlmMediaListManager.addPush(item); + } + + List<GbStream> gbStreams = new ArrayList<>(); + if (streamPushItem == null || streamPushItem.getGbId() == null) { + GbStream gbStream = storager.getGbStream(app, streamId); + gbStreams.add(gbStream); + }else { + if (streamPushItem.getGbId() != null) { + gbStreams.add(streamPushItem); + } + } + if (gbStreams.size() > 0) { + eventPublisher.catalogEventPublishForStream(null, gbStreams.toArray(new GbStream[0]), CatalogEvent.ON); + } + + }else { + // 鍏煎娴佹敞閿�鏃剁被鍨嬩粠redis璁板綍鑾峰彇 + MediaItem mediaItem = redisCatchStorage.getStreamInfo(app, streamId, mediaServerId); + if (mediaItem != null) { + type = OriginType.values()[mediaItem.getOriginType()].getType(); + redisCatchStorage.removeStream(mediaServerItem.getId(), type, app, streamId); + } + GbStream gbStream = storager.getGbStream(app, streamId); + if (gbStream != null) { + eventPublisher.catalogEventPublishForStream(null, gbStream, CatalogEvent.OFF); + } + zlmMediaListManager.removeMedia(app, streamId); + } + if (type != null) { + // 鍙戦�佹祦鍙樺寲redis娑堟伅 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("serverId", userSetup.getServerId()); + jsonObject.put("app", app); + jsonObject.put("stream", streamId); + jsonObject.put("register", regist); + jsonObject.put("mediaServerId", mediaServerId); + redisCatchStorage.sendStreamChangeMsg(type, jsonObject); + } } } } @@ -322,18 +421,18 @@ public ResponseEntity<String> onStreamNoneReader(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_stream_none_reader API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_stream_none_reader API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); String streamId = json.getString("stream"); String app = json.getString("app"); - + JSONObject ret = new JSONObject(); + ret.put("code", 0); if ("rtp".equals(app)){ - JSONObject ret = new JSONObject(); - ret.put("code", 0); ret.put("close", true); StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(streamId); if (streamInfoForPlayCatch != null) { + // 濡傛灉鍦ㄧ粰涓婄骇鎺ㄦ祦锛屼篃涓嶅仠姝€�� if (redisCatchStorage.isChannelSendingRTP(streamInfoForPlayCatch.getChannelId())) { ret.put("close", false); } else { @@ -346,16 +445,31 @@ if (streamInfoForPlayBackCatch != null) { cmder.streamByeCmd(streamInfoForPlayBackCatch.getDeviceID(), streamInfoForPlayBackCatch.getChannelId()); redisCatchStorage.stopPlayback(streamInfoForPlayBackCatch); + }else { + StreamInfo streamInfoForDownload = redisCatchStorage.queryDownloadByStreamId(streamId); + // 杩涜褰曞儚涓嬭浇鏃舵棤浜鸿鐪嬩笉鏂祦 + if (streamInfoForDownload != null) { + ret.put("close", false); + } } + } + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId); + if (mediaServerItem != null && "-1".equals(mediaServerItem.getStreamNoneReaderDelayMS())) { + ret.put("close", false); } return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); }else { - JSONObject ret = new JSONObject(); - ret.put("code", 0); - ret.put("close", false); + StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, streamId); + if (streamProxyItem != null && streamProxyItem.isEnable_remove_none_reader()) { + ret.put("close", true); + streamProxyService.del(app, streamId); + String url = streamProxyItem.getUrl() != null?streamProxyItem.getUrl():streamProxyItem.getSrc_url(); + logger.info("[{}/{}]<-[{}] 鎷夋祦浠g悊鏃犱汉瑙傜湅宸茬粡绉婚櫎", app, streamId, url); + }else { + ret.put("close", false); + } return new ResponseEntity<String>(ret.toString(),HttpStatus.OK); } - } /** @@ -366,22 +480,28 @@ @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8") public ResponseEntity<String> onStreamNotFound(@RequestBody JSONObject json){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_stream_not_found API璋冪敤锛屽弬鏁帮細" + json.toString()); + logger.debug("[ ZLM HOOK ]on_stream_not_found API璋冪敤锛屽弬鏁帮細" + json.toString()); } String mediaServerId = json.getString("mediaServerId"); - IMediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); + MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId); if (userSetup.isAutoApplyPlay() && mediaInfo != null) { String app = json.getString("app"); String streamId = json.getString("stream"); - if ("rtp".equals(app) && streamId.contains("gb_play") ) { + if ("rtp".equals(app)) { String[] s = streamId.split("_"); - if (s.length == 4) { - String deviceId = s[2]; - String channelId = s[3]; - Device device = storager.queryVideoDevice(deviceId); + if (s.length == 2) { + String deviceId = s[0]; + String channelId = s[1]; + Device device = redisCatchStorage.getDevice(deviceId); if (device != null) { UUID uuid = UUID.randomUUID(); - cmder.playStreamCmd(mediaInfo, device, channelId, (IMediaServerItem mediaServerItemInuse, JSONObject response) -> { + SSRCInfo ssrcInfo; + String streamId2 = null; + if (mediaInfo.isRtpEnable()) { + streamId2 = String.format("%s_%s", device.getDeviceId(), channelId); + } + ssrcInfo = mediaServerService.openRTPServer(mediaInfo, streamId2); + cmder.playStreamCmd(mediaInfo, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> { logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString()); playService.onPublishHandlerForPlay(mediaServerItemInuse, response, deviceId, channelId, uuid.toString()); }, null); @@ -407,7 +527,7 @@ public ResponseEntity<String> onServerStarted(HttpServletRequest request, @RequestBody JSONObject jsonObject){ if (logger.isDebugEnabled()) { - logger.debug("ZLM HOOK on_server_started API璋冪敤锛屽弬鏁帮細" + jsonObject.toString()); + logger.debug("[ ZLM HOOK ]on_server_started API璋冪敤锛屽弬鏁帮細" + jsonObject.toString()); } String remoteAddr = request.getRemoteAddr(); jsonObject.put("ip", remoteAddr); -- Gitblit v1.8.0