From 33b75be71a7b7b324e652d3a4be62b0f03b5d46b Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期一, 01 四月 2024 18:21:38 +0800
Subject: [PATCH] 支持abl hook

---
 src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java |  410 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 410 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java
new file mode 100755
index 0000000..e892e6d
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLHttpHookListener.java
@@ -0,0 +1,410 @@
+package com.genersoft.iot.vmp.media.abl;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.genersoft.iot.vmp.conf.UserSetting;
+import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
+import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
+import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
+import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
+import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
+import com.genersoft.iot.vmp.media.abl.bean.hook.*;
+import com.genersoft.iot.vmp.media.abl.event.HookAblServerKeepaliveEvent;
+import com.genersoft.iot.vmp.media.abl.event.HookAblServerStartEvent;
+import com.genersoft.iot.vmp.media.bean.MediaServer;
+import com.genersoft.iot.vmp.media.bean.ResultForOnPublish;
+import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
+import com.genersoft.iot.vmp.media.event.media.*;
+import com.genersoft.iot.vmp.media.event.mediaServer.MediaSendRtpStoppedEvent;
+import com.genersoft.iot.vmp.media.service.IMediaServerService;
+import com.genersoft.iot.vmp.media.zlm.ZLMMediaListManager;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ABL 鐨刪ook浜嬩欢鐩戝惉
+ */
+@RestController
+@RequestMapping("/index/hook/abl")
+public class ABLHttpHookListener {
+
+    private final static Logger logger = LoggerFactory.getLogger(ABLHttpHookListener.class);
+
+    @Autowired
+    private ABLRESTfulUtils ablresTfulUtils;
+
+    @Autowired
+    private ISIPCommanderForPlatform commanderFroPlatform;
+
+    @Autowired
+    private AudioBroadcastManager audioBroadcastManager;
+
+    @Autowired
+    private IPlayService playService;
+
+    @Autowired
+    private IVideoManagerStorage storager;
+
+    @Autowired
+    private IRedisCatchStorage redisCatchStorage;
+
+    @Autowired
+    private IInviteStreamService inviteStreamService;
+
+    @Autowired
+    private IDeviceService deviceService;
+
+    @Autowired
+    private IMediaServerService mediaServerService;
+
+    @Autowired
+    private IStreamProxyService streamProxyService;
+
+    @Autowired
+    private DeferredResultHolder resultHolder;
+
+    @Autowired
+    private IMediaService mediaService;
+
+    @Autowired
+    private EventPublisher eventPublisher;
+
+    @Autowired
+    private ZLMMediaListManager zlmMediaListManager;
+
+    @Autowired
+    private HookSubscribe subscribe;
+
+    @Autowired
+    private UserSetting userSetting;
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private ICloudRecordService cloudRecordService;
+
+    @Autowired
+    private VideoStreamSessionManager sessionManager;
+
+    @Autowired
+    private SSRCFactory ssrcFactory;
+
+    @Qualifier("taskExecutor")
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+    @Autowired
+    private RedisTemplate<Object, Object> redisTemplate;
+
+    @Autowired
+    private ApplicationEventPublisher applicationEventPublisher;
+
+    /**
+     * 鏈嶅姟鍣ㄥ畾鏃朵笂鎶ユ椂闂达紝涓婃姤闂撮殧鍙厤缃紝榛樿10s涓婃姤涓�娆�
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_server_keepalive", produces = "application/json;charset=UTF-8")
+    public HookResult onServerKeepalive(@RequestBody OnServerKeepaliveABLHookParam param) {
+        try {
+            HookAblServerKeepaliveEvent event = new HookAblServerKeepaliveEvent(this);
+            MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+            if (mediaServerItem != null) {
+                event.setMediaServerItem(mediaServerItem);
+                applicationEventPublisher.publishEvent(event);
+            }
+        }catch (Exception e) {
+            logger.info("[ZLM-HOOK-蹇冭烦] 鍙戦�侀�氱煡澶辫触 ", e);
+        }
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * 鎾斁鍣ㄩ壌鏉冧簨浠讹紝rtsp/rtmp/http-flv/ws-flv/hls鐨勬挱鏀鹃兘灏嗚Е鍙戞閴存潈浜嬩欢銆�
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_play", produces = "application/json;charset=UTF-8")
+    public HookResult onPlay(@RequestBody OnPlayABLHookParam param) {
+
+        MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
+        if (mediaServer == null) {
+            return new HookResultForOnPublish(0, "success");
+        }
+
+        Map<String, String> paramMap = urlParamToMap(param.getParams());
+        // 瀵逛簬鎾斁娴佽繘琛岄壌鏉�
+        boolean authenticateResult = mediaService.authenticatePlay(param.getApp(), param.getStream(), paramMap.get("callId"));
+        if (!authenticateResult) {
+            logger.info("[ABL HOOK] 鎾斁閴存潈 澶辫触锛歿}->{}", param.getMediaServerId(), param);
+            ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream());
+
+        }
+        logger.info("[ABL HOOK] 鎾斁閴存潈鎴愬姛锛歿}->{}", param.getMediaServerId(), param);
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * rtsp/rtmp/rtp鎺ㄦ祦閴存潈浜嬩欢銆�
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_publish", produces = "application/json;charset=UTF-8")
+    public HookResult onPublish(@RequestBody OnPublishABLHookParam param) {
+
+
+        logger.info("[ABL HOOK]鎺ㄦ祦閴存潈锛歿}->{}", param.getMediaServerId(), param);
+        // TODO 鍔犲揩澶勭悊閫熷害
+
+        MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
+        if (mediaServer == null) {
+            return new HookResultForOnPublish(0, "success");
+        }
+
+        ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams());
+        if (resultForOnPublish == null) {
+            logger.info("[ABL HOOK]鎺ㄦ祦閴存潈 鎷掔粷 鍝嶅簲锛歿}->{}", param.getMediaServerId(), param);
+            ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream());
+        }
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * 濡傛灉鏌愪竴涓爜娴佽繘琛孧P4褰曞儚锛坋nable_mp4=1锛夛紝浼氳Е鍙戝綍鍍忚繘搴﹂�氱煡浜嬩欢
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_record_progress", produces = "application/json;charset=UTF-8")
+    public HookResult onRecordProgress(@RequestBody OnRecordProgressABLHookParam param) {
+
+
+        logger.info("[ABL HOOK] 褰曞儚杩涘害閫氱煡锛歿}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration());
+
+        // TODO 杩欓噷鐢ㄦ潵鍋氬綍鍍忚繘搴�
+//        MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
+//        if (mediaServer == null) {
+//            return new HookResultForOnPublish(0, "success");
+//        }
+//
+//        ResultForOnPublish resultForOnPublish = mediaService.authenticatePublish(mediaServer, param.getApp(), param.getStream(), param.getParams());
+//        if (resultForOnPublish == null) {
+//            logger.info("[ABL HOOK]鎺ㄦ祦閴存潈 鎷掔粷 鍝嶅簲锛歿}->{}", param.getMediaServerId(), param);
+//            ablresTfulUtils.closeStreams(mediaServer, param.getApp(), param.getStream());
+//        }
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * 褰撲唬鐞嗘媺娴併�佸浗鏍囨帴鍏ョ瓑绛� 鐮佹祦涓嶅埌杈炬椂浼氬彂鍑� 鐮佹祦涓嶅埌杈剧殑浜嬩欢閫氱煡
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_stream_not_arrive", produces = "application/json;charset=UTF-8")
+    public HookResult onStreamNotArrive(@RequestBody ABLHookParam param) {
+
+
+        logger.info("[ABL HOOK] 鐮佹祦涓嶅埌杈鹃�氱煡锛歿}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration());
+        try {
+            if ("rtp".equals(param.getApp())) {
+                return HookResult.SUCCESS();
+            }
+            MediaRtpServerTimeoutEvent event = new MediaRtpServerTimeoutEvent(this);
+            MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+            if (mediaServerItem != null) {
+                event.setMediaServer(mediaServerItem);
+                event.setApp("rtp");
+                applicationEventPublisher.publishEvent(event);
+            }
+        }catch (Exception e) {
+            logger.info("[ABL-HOOK-鐮佹祦涓嶅埌杈鹃�氱煡] 鍙戦�侀�氱煡澶辫触 ", e);
+        }
+
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * 濡傛灉鏌愪竴涓爜娴佽繘琛孧P4褰曞儚锛坋nable_mp4=1锛夛紝褰撴煇涓狹P4鏂囦欢琚垹闄や細瑙﹀彂璇ヤ簨浠堕�氱煡
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_delete_record_mp4", produces = "application/json;charset=UTF-8")
+    public HookResult onDeleteRecordMp4(@RequestBody OnRecordMp4ABLHookParam param) {
+
+
+        logger.info("[ABL HOOK] MP4鏂囦欢琚垹闄ら�氱煡锛歿}->{}/{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream(), param.getCurrentFileDuration(), param.getTotalVideoDuration());
+
+
+        return HookResult.SUCCESS();
+    }
+
+
+    /**
+     * rtsp/rtmp娴佹敞鍐屾垨娉ㄩ攢鏃惰Е鍙戞浜嬩欢锛涙浜嬩欢瀵瑰洖澶嶄笉鏁忔劅銆�
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_stream_arrive", produces = "application/json;charset=UTF-8")
+    public HookResult onStreamArrive(@RequestBody OnStreamArriveABLHookParam param) {
+
+        MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
+        if (mediaServer == null) {
+            return HookResult.SUCCESS();
+        }
+
+        logger.info("[ABL HOOK] 鐮佹祦鍒拌揪, {}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
+        MediaArrivalEvent mediaArrivalEvent = MediaArrivalEvent.getInstance(this, param, mediaServer);
+        applicationEventPublisher.publishEvent(mediaArrivalEvent);
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * 娴佹棤浜鸿鐪嬫椂浜嬩欢锛岀敤鎴峰彲浠ラ�氳繃姝や簨浠堕�夋嫨鏄惁鍏抽棴鏃犱汉鐪嬬殑娴併��
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8")
+    public JSONObject onStreamNoneReader(@RequestBody ABLHookParam param) {
+
+        logger.info("[ZLM HOOK]娴佹棤浜鸿鐪嬶細{}->{}/{}", param.getMediaServerId(),
+                param.getApp(), param.getStream());
+        JSONObject ret = new JSONObject();
+
+        boolean close = mediaService.closeStreamOnNoneReader(param.getMediaServerId(), param.getApp(), param.getStream(), null);
+        ret.put("code", close);
+        return ret;
+    }
+
+    /**
+     * 褰撴挱鏀句竴涓猽rl锛屽鏋滀笉瀛樺湪鏃讹紝浼氬彂鍑轰竴涓秷鎭�氱煡
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_stream_not_found", produces = "application/json;charset=UTF-8")
+    public HookResult onStreamNotFound(@RequestBody ABLHookParam param) {
+        logger.info("[ABL HOOK] 娴佹湭鎵惧埌锛歿}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
+
+
+        MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
+        if (!userSetting.isAutoApplyPlay() || mediaServer == null) {
+            return HookResult.SUCCESS();
+        }
+        MediaNotFoundEvent mediaNotFoundEvent = MediaNotFoundEvent.getInstance(this, param, mediaServer);
+        applicationEventPublisher.publishEvent(mediaNotFoundEvent);
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * ABLMediaServer鍚姩鏃朵細鍙戦�佷笂绾块�氱煡
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_server_started", produces = "application/json;charset=UTF-8")
+    public HookResult onServerStarted(HttpServletRequest request, @RequestBody OnServerStaredABLHookParam param) {
+
+        logger.info("[ABL HOOK] 鍚姩 " + param.getMediaServerId());
+        try {
+            HookAblServerStartEvent event = new HookAblServerStartEvent(this);
+            MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+            if (mediaServerItem != null) {
+                event.setMediaServerItem(mediaServerItem);
+                applicationEventPublisher.publishEvent(event);
+            }
+        }catch (Exception e) {
+            logger.info("[ABL-HOOK-鍚姩] 鍙戦�侀�氱煡澶辫触 ", e);
+        }
+
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * TODO 鍙戦�乺tp(startSendRtp)琚姩鍏抽棴鏃跺洖璋�
+     */
+//    @ResponseBody
+//    @PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8")
+//    public HookResult onSendRtpStopped(HttpServletRequest request, @RequestBody OnSendRtpStoppedHookParam param) {
+//
+//        logger.info("[ZLM HOOK] rtp鍙戦�佸叧闂細{}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
+//
+//        // 鏌ユ壘瀵瑰簲鐨勪笂绾ф帹娴侊紝鍙戦�佸仠姝�
+//        if (!"rtp".equals(param.getApp())) {
+//            return HookResult.SUCCESS();
+//        }
+//        try {
+//            MediaSendRtpStoppedEvent event = new MediaSendRtpStoppedEvent(this);
+//            MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+//            if (mediaServerItem != null) {
+//                event.setMediaServer(mediaServerItem);
+//                applicationEventPublisher.publishEvent(event);
+//            }
+//        }catch (Exception e) {
+//            logger.info("[ZLM-HOOK-rtp鍙戦�佸叧闂璢 鍙戦�侀�氱煡澶辫触 ", e);
+//        }
+//
+//        return HookResult.SUCCESS();
+//    }
+
+    /**
+     * TODO 褰曞儚瀹屾垚浜嬩欢
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8")
+    public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4ABLHookParam param) {
+        logger.info("[ABL HOOK] 褰曞儚瀹屾垚浜嬩欢锛歿}->{}", param.getMediaServerId(), param.getFileName());
+
+//        try {
+//            MediaServer mediaServerItem = mediaServerService.getOne(param.getMediaServerId());
+//            if (mediaServerItem != null) {
+//                MediaRecordMp4Event event = MediaRecordMp4Event.getInstance(this, param, mediaServerItem);
+//                event.setMediaServer(mediaServerItem);
+//                applicationEventPublisher.publishEvent(event);
+//            }
+//        }catch (Exception e) {
+//            logger.info("[ZLM-HOOK-rtpServer鏀舵祦瓒呮椂] 鍙戦�侀�氱煡澶辫触 ", e);
+//        }
+
+        return HookResult.SUCCESS();
+    }
+
+    /**
+     * 褰撴煇涓�璺爜娴佹柇寮�鏃朵細鍙戦�侀�氱煡
+     */
+    @ResponseBody
+    @PostMapping(value = "/on_stream_disconnect", produces = "application/json;charset=UTF-8")
+    public HookResult onRecordMp4(HttpServletRequest request, @RequestBody ABLHookParam param) {
+        logger.info("[ABL HOOK] 鐮佹祦鏂紑浜嬩欢, {}->{}/{}", param.getMediaServerId(), param.getApp(), param.getStream());
+
+        MediaServer mediaServer = mediaServerService.getOne(param.getMediaServerId());
+        if (mediaServer == null) {
+            return HookResult.SUCCESS();
+        }
+
+        MediaDepartureEvent mediaDepartureEvent = MediaDepartureEvent.getInstance(this, param, mediaServer);
+        applicationEventPublisher.publishEvent(mediaDepartureEvent);
+
+        return HookResult.SUCCESS();
+    }
+
+    private Map<String, String> urlParamToMap(String params) {
+        HashMap<String, String> map = new HashMap<>();
+        if (ObjectUtils.isEmpty(params)) {
+            return map;
+        }
+        String[] paramsArray = params.split("&");
+        if (paramsArray.length == 0) {
+            return map;
+        }
+        for (String param : paramsArray) {
+            String[] paramArray = param.split("=");
+            if (paramArray.length == 2) {
+                map.put(paramArray[0], paramArray[1]);
+            }
+        }
+        return map;
+    }
+}

--
Gitblit v1.8.0