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