| | |
| | | package com.genersoft.iot.vmp.media.zlm; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.HookType; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.IHookSubscribe; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.time.Instant; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * @description:针对 ZLMediaServer的hook事件订阅 |
| | |
| | | @Component |
| | | public class ZLMHttpHookSubscribe { |
| | | |
| | | public enum HookType{ |
| | | on_flow_report, |
| | | on_http_access, |
| | | on_play, |
| | | on_publish, |
| | | on_record_mp4, |
| | | on_rtsp_auth, |
| | | on_rtsp_realm, |
| | | on_shell_login, |
| | | on_stream_changed, |
| | | on_stream_none_reader, |
| | | on_stream_not_found, |
| | | on_server_started, |
| | | on_server_keepalive |
| | | } |
| | | |
| | | @FunctionalInterface |
| | | public interface Event{ |
| | | void response(MediaServerItem mediaServerItem, JSONObject response); |
| | | } |
| | | |
| | | private Map<HookType, Map<JSONObject, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); |
| | | private Map<HookType, Map<IHookSubscribe, ZLMHttpHookSubscribe.Event>> allSubscribes = new ConcurrentHashMap<>(); |
| | | |
| | | public void addSubscribe(HookType type, JSONObject hookResponse, ZLMHttpHookSubscribe.Event event) { |
| | | allSubscribes.computeIfAbsent(type, k -> new ConcurrentHashMap<>()).put(hookResponse, event); |
| | | public void addSubscribe(IHookSubscribe hookSubscribe, ZLMHttpHookSubscribe.Event event) { |
| | | if (hookSubscribe.getExpires() == null) { |
| | | // 默认5分钟过期 |
| | | Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(5)); |
| | | hookSubscribe.setExpires(expiresInstant); |
| | | } |
| | | allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event); |
| | | } |
| | | |
| | | public ZLMHttpHookSubscribe.Event getSubscribe(HookType type, JSONObject hookResponse) { |
| | | public ZLMHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) { |
| | | ZLMHttpHookSubscribe.Event event= null; |
| | | Map<JSONObject, Event> eventMap = allSubscribes.get(type); |
| | | Map<IHookSubscribe, Event> eventMap = allSubscribes.get(type); |
| | | if (eventMap == null) { |
| | | return null; |
| | | } |
| | | for (JSONObject key : eventMap.keySet()) { |
| | | for (IHookSubscribe key : eventMap.keySet()) { |
| | | Boolean result = null; |
| | | for (String s : key.keySet()) { |
| | | for (String s : key.getContent().keySet()) { |
| | | if (result == null) { |
| | | result = key.getString(s).equals(hookResponse.getString(s)); |
| | | result = key.getContent().getString(s).equals(hookResponse.getString(s)); |
| | | }else { |
| | | if (key.getString(s) == null) { |
| | | if (key.getContent().getString(s) == null) { |
| | | continue; |
| | | } |
| | | result = result && key.getString(s).equals(hookResponse.getString(s)); |
| | | result = result && key.getContent().getString(s).equals(hookResponse.getString(s)); |
| | | } |
| | | |
| | | } |
| | |
| | | return event; |
| | | } |
| | | |
| | | public void removeSubscribe(HookType type, JSONObject hookResponse) { |
| | | Map<JSONObject, Event> eventMap = allSubscribes.get(type); |
| | | public void removeSubscribe(IHookSubscribe hookSubscribe) { |
| | | Map<IHookSubscribe, Event> eventMap = allSubscribes.get(hookSubscribe.getHookType()); |
| | | if (eventMap == null) { |
| | | return; |
| | | } |
| | | |
| | | Set<Map.Entry<JSONObject, Event>> entries = eventMap.entrySet(); |
| | | Set<Map.Entry<IHookSubscribe, Event>> entries = eventMap.entrySet(); |
| | | if (entries.size() > 0) { |
| | | List<Map.Entry<JSONObject, ZLMHttpHookSubscribe.Event>> entriesToRemove = new ArrayList<>(); |
| | | for (Map.Entry<JSONObject, ZLMHttpHookSubscribe.Event> entry : entries) { |
| | | JSONObject key = entry.getKey(); |
| | | List<Map.Entry<IHookSubscribe, ZLMHttpHookSubscribe.Event>> entriesToRemove = new ArrayList<>(); |
| | | for (Map.Entry<IHookSubscribe, ZLMHttpHookSubscribe.Event> entry : entries) { |
| | | JSONObject content = entry.getKey().getContent(); |
| | | if (content == null || content.size() == 0) { |
| | | entriesToRemove.add(entry); |
| | | continue; |
| | | } |
| | | Boolean result = null; |
| | | for (String s : key.keySet()) { |
| | | for (String s : content.keySet()) { |
| | | if (result == null) { |
| | | result = key.getString(s).equals(hookResponse.getString(s)); |
| | | result = content.getString(s).equals(hookSubscribe.getContent().getString(s)); |
| | | }else { |
| | | if (key.getString(s) == null) { |
| | | if (content.getString(s) == null) { |
| | | continue; |
| | | } |
| | | result = result && key.getString(s).equals(hookResponse.getString(s)); |
| | | result = result && content.getString(s).equals(hookSubscribe.getContent().getString(s)); |
| | | } |
| | | } |
| | | if (null != result && result){ |
| | |
| | | } |
| | | |
| | | if (!CollectionUtils.isEmpty(entriesToRemove)) { |
| | | for (Map.Entry<JSONObject, ZLMHttpHookSubscribe.Event> entry : entriesToRemove) { |
| | | for (Map.Entry<IHookSubscribe, ZLMHttpHookSubscribe.Event> entry : entriesToRemove) { |
| | | entries.remove(entry); |
| | | } |
| | | } |
| | |
| | | * @return |
| | | */ |
| | | public List<ZLMHttpHookSubscribe.Event> getSubscribes(HookType type) { |
| | | // ZLMHttpHookSubscribe.Event event= null; |
| | | Map<JSONObject, Event> eventMap = allSubscribes.get(type); |
| | | Map<IHookSubscribe, Event> eventMap = allSubscribes.get(type); |
| | | if (eventMap == null) { |
| | | return null; |
| | | } |
| | | List<ZLMHttpHookSubscribe.Event> result = new ArrayList<>(); |
| | | for (JSONObject key : eventMap.keySet()) { |
| | | for (IHookSubscribe key : eventMap.keySet()) { |
| | | result.add(eventMap.get(key)); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public List<IHookSubscribe> getAll(){ |
| | | ArrayList<IHookSubscribe> result = new ArrayList<>(); |
| | | Collection<Map<IHookSubscribe, Event>> values = allSubscribes.values(); |
| | | for (Map<IHookSubscribe, Event> value : values) { |
| | | result.addAll(value.keySet()); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | } |