From e55bd2aea57a24f0a58b9bde758a601f4859c1e8 Mon Sep 17 00:00:00 2001 From: shikong <919411476@qq.com> Date: Tue, 17 Oct 2023 23:20:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20proxy-media-url=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9B=BF=E6=8D=A2=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84=20url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gb28181/wvp/config/ProxySipConfig.java | 6 ++ .../gb28181/Gb28181DownloadService.java | 59 ++++++++++++++----- .../src/main/resources/application-local.yml | 3 +- .../src/main/resources/application.yml | 4 +- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/config/ProxySipConfig.java b/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/config/ProxySipConfig.java index 10d11eb..7584986 100644 --- a/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/config/ProxySipConfig.java +++ b/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/config/ProxySipConfig.java @@ -37,6 +37,12 @@ public class ProxySipConfig { */ private boolean usePlaybackToDownload = false; + /** + * 代理 zlm 地址, 用于 /video/device/video.mp4 替换返回值地址 + *

例: http://127.0.0.1:5080

+ */ + private String proxyMediaUrl = ""; + @Bean public SipConfig sipConfig(){ SipConfig sipConfig = new SipConfig(); diff --git a/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/gb28181/Gb28181DownloadService.java b/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/gb28181/Gb28181DownloadService.java index 8d9c3ac..0ad3c4b 100644 --- a/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/gb28181/Gb28181DownloadService.java +++ b/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/gb28181/Gb28181DownloadService.java @@ -80,6 +80,7 @@ public class Gb28181DownloadService { private final VideoService videoService; private final WvpProxyConfig wvpProxyConfig; private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + private final ConcurrentMap>> requestMap = new ConcurrentHashMap<>(); @NoArgsConstructor @AllArgsConstructor @@ -185,22 +186,50 @@ public class Gb28181DownloadService { result.setResult(JsonResponse.error("设备(通道)不存在")); return result; } - download(deviceCode, startTime, endTime).whenComplete((videoInfo, e)->{ - String cacheKey = CacheUtil.getKey(docking.getGbDeviceId(), device.getGbDeviceChannelId()); - String existCallId = RedisUtil.StringOps.get(cacheKey); - scheduledExecutorService.schedule(()->{ - log.info("到达结束时间 发送 bye 关闭 {} {}", videoInfo.getDevice(), videoInfo.getCallId()); - String deviceIp = docking.getIp(); - int devicePort = Integer.parseInt(docking.getPort()); - sender.sendRequest((provider,localIp,localPort)-> - SipRequestBuilder.createByeRequest(deviceIp, devicePort, device.getGbDeviceChannelId(), SipUtil.generateFromTag(), null, existCallId)); - RedisUtil.KeyOps.delete(cacheKey); - zlmMediaService.closeRtpServer(CloseRtpServer.builder() - .streamId(videoInfo.streamId) - .build()); - }, time, TimeUnit.MILLISECONDS); - result.setResult(JsonResponse.success(videoInfo.getUrl())); + requestMap.computeIfPresent(deviceCode,(key,requestResult)->{ + if(!requestResult.hasResult()){ + requestResult.setResult(JsonResponse.error("同一设备重复请求, 本次请求结束")); + String cacheKey = CacheUtil.getKey(docking.getGbDeviceId(), device.getGbDeviceChannelId()); + String existCallId = RedisUtil.StringOps.get(cacheKey); + if(StringUtils.isNotBlank(existCallId)){ + String deviceIp = docking.getIp(); + int devicePort = Integer.parseInt(docking.getPort()); + sender.sendRequest((provider,localIp,localPort)-> + SipRequestBuilder.createByeRequest(deviceIp, devicePort, device.getGbDeviceChannelId(), SipUtil.generateFromTag(), null, existCallId)); + RedisUtil.KeyOps.delete(cacheKey); + } + } + return null; }); + requestMap.put(deviceCode, result); + + // 间隔一定时间(200ms) 给设备足够的时间结束前次请求 + scheduledExecutorService.schedule(()->{ + download(deviceCode, startTime, endTime).whenComplete((videoInfo, e)->{ + log.info("获取媒体信息 {}", videoInfo); + String cacheKey = CacheUtil.getKey(docking.getGbDeviceId(), device.getGbDeviceChannelId()); + String existCallId = RedisUtil.StringOps.get(cacheKey); + // 到达时间后主动结束, 防止某些设备不会主动结束 + scheduledExecutorService.schedule(()->{ + log.info("到达结束时间 发送 bye 关闭 {} {}", videoInfo.getDevice(), videoInfo.getCallId()); + String deviceIp = docking.getIp(); + int devicePort = Integer.parseInt(docking.getPort()); + if(StringUtils.isNotBlank(existCallId)) { + sender.sendRequest((provider, localIp, localPort) -> + SipRequestBuilder.createByeRequest(deviceIp, devicePort, device.getGbDeviceChannelId(), SipUtil.generateFromTag(), null, existCallId)); + } + RedisUtil.KeyOps.delete(cacheKey); + zlmMediaService.closeRtpServer(CloseRtpServer.builder() + .streamId(videoInfo.streamId) + .build()); + }, time, TimeUnit.MILLISECONDS); + + String url = StringUtils.isNotBlank(proxySipConfig.getProxyMediaUrl()) ? + StringUtils.replace(videoInfo.getUrl(), zlmMediaConfig.getUrl(), proxySipConfig.getProxyMediaUrl()): + videoInfo.getUrl(); + result.setResult(JsonResponse.success(url)); + }); + }, 200, TimeUnit.MILLISECONDS); return result; } diff --git a/gb28181-wvp-proxy-starter/src/main/resources/application-local.yml b/gb28181-wvp-proxy-starter/src/main/resources/application-local.yml index 307b31d..725b26f 100644 --- a/gb28181-wvp-proxy-starter/src/main/resources/application-local.yml +++ b/gb28181-wvp-proxy-starter/src/main/resources/application-local.yml @@ -35,7 +35,7 @@ spring: media: ip: 10.10.10.200 - url: 'http://10.10.10.200:5081' + url: 'https://10.10.10.200:5444' # url: 'http://10.10.10.200:12580/anything/' id: amrWMKmbKqoBjRQ9 # secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc @@ -58,6 +58,7 @@ proxy: - 10.10.10.20 stream-mode: udp use-playback-to-download: true + proxy-media-url: 'http://10.10.10.200/media' # - 192.168.1.241 ffmpeg-support: ffmpeg: D:\Soft\Captura\ffmpeg\ffmpeg.exe diff --git a/gb28181-wvp-proxy-starter/src/main/resources/application.yml b/gb28181-wvp-proxy-starter/src/main/resources/application.yml index b886aed..48b8211 100644 --- a/gb28181-wvp-proxy-starter/src/main/resources/application.yml +++ b/gb28181-wvp-proxy-starter/src/main/resources/application.yml @@ -65,7 +65,9 @@ proxy: # - 192.168.3.10 # - 192.168.1.241 stream-mode: tcp_passive - use-playback-to-download: true + use-playback-to-download: false + # 用于替换 返回的 url 值, 可用 nginx 或 caddy 代理 zlm + # proxy-media-url: 'http://10.10.10.200/media' device-api: offset: forward: 30s