diff --git a/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/download/DownloadController.java b/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/download/DownloadController.java
new file mode 100644
index 0000000..ea712c6
--- /dev/null
+++ b/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/download/DownloadController.java
@@ -0,0 +1,37 @@
+package cn.skcks.docking.gb28181.wvp.api.download;
+
+import cn.skcks.docking.gb28181.wvp.config.SwaggerConfig;
+import cn.skcks.docking.gb28181.wvp.service.download.DownloadService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springdoc.core.models.GroupedOpenApi;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.bind.annotation.*;
+
+@RequiredArgsConstructor
+@Tag(name = "下载")
+@RestController
+@RequestMapping("/download")
+public class DownloadController {
+ private final DownloadService downloadService;
+
+ @Bean
+ public GroupedOpenApi downloadApi() {
+ return SwaggerConfig.api("DownloadApi", "/download");
+ }
+
+ @Operation(summary = "下载代理")
+ @RequestMapping(method = RequestMethod.HEAD, value = "/proxy")
+ public void downloadProxyHeader(HttpServletRequest request, HttpServletResponse response, @RequestParam String url) {
+ downloadService.header(request, response, url);
+ }
+
+ @Operation(summary = "下载代理")
+ @GetMapping("/proxy")
+ public void downloadProxy(HttpServletRequest request, HttpServletResponse response, @RequestParam String url) {
+ downloadService.download(request, response, url);
+ }
+}
diff --git a/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/video/VideoController.java b/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/video/VideoController.java
index 2444c00..aff32f2 100644
--- a/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/video/VideoController.java
+++ b/gb28181-wvp-proxy-api/src/main/java/cn/skcks/docking/gb28181/wvp/api/video/VideoController.java
@@ -2,6 +2,7 @@ package cn.skcks.docking.gb28181.wvp.api.video;
import cn.skcks.docking.gb28181.media.config.ZlmMediaConfig;
import cn.skcks.docking.gb28181.wvp.config.SwaggerConfig;
+import cn.skcks.docking.gb28181.wvp.service.download.DownloadService;
import cn.skcks.docking.gb28181.wvp.service.video.RecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -9,7 +10,6 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
@@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
public class VideoController {
private final ZlmMediaConfig config;
private final RecordService recordService;
+ private final DownloadService downloadService;
@Bean
public GroupedOpenApi videoApi() {
@@ -36,8 +37,9 @@ public class VideoController {
@GetMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public void video(HttpServletRequest request, HttpServletResponse response) {
- String url = StringUtils.joinWith("/", config.getUrl(), "live", "test.live.flv");
- log.info("url {}", url);
- recordService.record(request,response,url,15);
+// String url = StringUtils.joinWith("/", config.getUrl(), "live", "test.live.flv");
+// log.info("url {}", url);
+// recordService.record(request,response,url,15);
+ downloadService.download(request,response,"http://192.168.1.241:18979/download/recordTemp/0490d767d94ce20aedce57c862b6bfe9/rtp/59777645.mp4");
}
}
diff --git a/gb28181-wvp-proxy-service/pom.xml b/gb28181-wvp-proxy-service/pom.xml
index 84e8fdb..e60eb0b 100644
--- a/gb28181-wvp-proxy-service/pom.xml
+++ b/gb28181-wvp-proxy-service/pom.xml
@@ -168,6 +168,15 @@
+
+
+ org.apache.httpcomponents.client5
+ httpclient5
+
+
+ io.github.openfeign
+ feign-httpclient
+
diff --git a/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/download/DownloadService.java b/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/download/DownloadService.java
new file mode 100644
index 0000000..3162ea8
--- /dev/null
+++ b/gb28181-wvp-proxy-service/src/main/java/cn/skcks/docking/gb28181/wvp/service/download/DownloadService.java
@@ -0,0 +1,88 @@
+package cn.skcks.docking.gb28181.wvp.service.download;
+
+import cn.hutool.core.io.IoUtil;
+import jakarta.servlet.AsyncContext;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.classic.methods.HttpHead;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.springframework.stereotype.Service;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Optional;
+
+@Slf4j
+@Service
+public class DownloadService {
+ @SneakyThrows
+ public void header(HttpServletRequest request, HttpServletResponse response, String url) {
+ AsyncContext asyncContext = request.startAsync();
+ asyncContext.setTimeout(0);
+ asyncContext.start(() -> {
+ try {
+ response.setHeader("Accept-Ranges", "none");
+ response.setHeader("Connection", "close");
+ header((HttpServletResponse) asyncContext.getResponse(), url);
+ } finally {
+ log.info("record 结束");
+ asyncContext.complete();
+ }
+ });
+ }
+
+ @SneakyThrows
+ private void header(HttpServletResponse response, String url) {
+ try (CloseableHttpClient client = HttpClients.custom().build()) {
+ HttpHead httpHead = new HttpHead(url);
+ client.execute(httpHead, resp -> {
+ setHeaderFromProxy(resp,response);
+ return null;
+ });
+ }
+ }
+
+ @SneakyThrows
+ private void setHeaderFromProxy(ClassicHttpResponse resp, HttpServletResponse response){
+ response.setContentType(resp.getEntity().getContentType());
+ Optional.ofNullable(resp.getHeader("Content-Disposition")).ifPresent((header)->{
+ response.setHeader(header.getName(), header.getValue());
+ });
+ }
+
+ @SneakyThrows
+ public void download(HttpServletRequest request, HttpServletResponse response, String url) {
+ AsyncContext asyncContext = request.startAsync();
+ asyncContext.setTimeout(0);
+ asyncContext.start(() -> {
+ try {
+ response.setHeader("Accept-Ranges", "none");
+ response.setHeader("Connection", "close");
+ download((HttpServletResponse) asyncContext.getResponse(), url);
+ } finally {
+ log.info("record 结束");
+ asyncContext.complete();
+ }
+ });
+ }
+
+ @SneakyThrows
+ private void download(HttpServletResponse response, String url) {
+ OutputStream outputStream = response.getOutputStream();
+
+ try (CloseableHttpClient client = HttpClients.custom().build()) {
+ HttpGet httpGet = new HttpGet(url);
+ client.execute(httpGet, resp -> {
+ setHeaderFromProxy(resp,response);
+ InputStream stream = resp.getEntity().getContent();
+ IoUtil.copy(stream, outputStream);
+ return stream;
+ });
+ }
+ }
+}
diff --git a/gb28181-wvp-proxy-service/src/main/resources/application.yaml b/gb28181-wvp-proxy-service/src/main/resources/application.yaml
deleted file mode 100644
index 26dfe71..0000000
--- a/gb28181-wvp-proxy-service/src/main/resources/application.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-proxy:
- wvp:
- url: http://192.168.3.13:18978
- user: admin
- passwd: admin
\ No newline at end of file
diff --git a/gb28181-wvp-proxy-service/src/main/resources/application.yml b/gb28181-wvp-proxy-service/src/main/resources/application.yml
new file mode 100644
index 0000000..5ea5ca7
--- /dev/null
+++ b/gb28181-wvp-proxy-service/src/main/resources/application.yml
@@ -0,0 +1,43 @@
+server:
+ port: 18186
+
+spring:
+ data:
+ redis:
+ # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1
+ # host: 192.168.1.241
+ host: 10.10.10.200
+ # [必须修改] 端口号
+ port: 16379
+ # [可选] 数据库 DB
+ database: 15
+ # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接
+ password: 12341234
+ # [可选] 超时时间
+ timeout: 10000
+ datasource:
+ type: com.zaxxer.hikari.HikariDataSource
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ username: root
+ password: 12341234
+ url: jdbc:mysql://10.10.10.200:3306/gb28181_docking_platform?createDatabaseIfNotExist=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+ cloud:
+ openfeign:
+ httpclient:
+ connection-timeout: 0
+ ok-http:
+ read-timeout: 0
+
+media:
+ ip: 10.10.10.200
+ url: 'http://10.10.10.200:5080'
+ # url: 'http://10.10.10.200:12580/anything/'
+ id: amrWMKmbKqoBjRQ9
+# secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
+ secret: 4155cca6-2f9f-11ee-85e6-8de4ce2e7333
+
+proxy:
+ wvp:
+ url: http://192.168.3.13:18978
+ user: admin
+ passwd: admin
diff --git a/gb28181-wvp-proxy-service/src/test/java/cn/skcks/docking/gb28181/wvp/test/WvpProxyTest.java b/gb28181-wvp-proxy-service/src/test/java/cn/skcks/docking/gb28181/wvp/test/WvpProxyTest.java
index 616f219..bc8af4b 100644
--- a/gb28181-wvp-proxy-service/src/test/java/cn/skcks/docking/gb28181/wvp/test/WvpProxyTest.java
+++ b/gb28181-wvp-proxy-service/src/test/java/cn/skcks/docking/gb28181/wvp/test/WvpProxyTest.java
@@ -1,7 +1,9 @@
package cn.skcks.docking.gb28181.wvp.test;
+import cn.hutool.core.io.IoUtil;
import cn.hutool.crypto.digest.MD5;
import cn.skcks.docking.gb28181.common.json.JsonResponse;
+import cn.skcks.docking.gb28181.wvp.WvpProxyTestApplication;
import cn.skcks.docking.gb28181.wvp.config.WvpProxyConfig;
import cn.skcks.docking.gb28181.wvp.dto.device.GetDeviceChannelsReq;
import cn.skcks.docking.gb28181.wvp.dto.device.GetDeviceChannelsResp;
@@ -11,17 +13,24 @@ import cn.skcks.docking.gb28181.wvp.dto.login.WvpLoginReq;
import cn.skcks.docking.gb28181.wvp.dto.login.WvpLoginResp;
import cn.skcks.docking.gb28181.wvp.proxy.WvpProxyClient;
import lombok.extern.slf4j.Slf4j;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.core5.io.CloseMode;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+
@Slf4j
-@SpringBootTest
-@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
+@SpringBootTest(classes = WvpProxyTestApplication.class)
@ExtendWith(SpringExtension.class)
public class WvpProxyTest {
@Autowired
@@ -55,4 +64,24 @@ public class WvpProxyTest {
log.info("{}", item);
});
}
+
+ @Test
+ void downloadTest() throws IOException {
+ final CloseableHttpClient client = HttpClients.custom()
+ .build();
+
+ String tmpDir = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
+ File file = new File(Paths.get(tmpDir,"test.mp4").toUri());
+ log.info("临时文件 路径 => {}",file.getAbsolutePath());
+ FileOutputStream outputStream = new FileOutputStream(file);
+
+ String url = "http://192.168.1.241:18979/download/recordTemp/0490d767d94ce20aedce57c862b6bfe9/rtp/59777645.mp4";
+ HttpGet httpGet = new HttpGet(url);
+ client.execute(httpGet, response -> {
+ InputStream stream = response.getEntity().getContent();
+ IoUtil.copy(stream,outputStream);
+ return stream;
+ });
+ client.close(CloseMode.GRACEFUL);
+ }
}
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 b8215c9..d0ba8ba 100644
--- a/gb28181-wvp-proxy-starter/src/main/resources/application-local.yml
+++ b/gb28181-wvp-proxy-starter/src/main/resources/application-local.yml
@@ -32,6 +32,7 @@ spring:
connection-timeout: 0
ok-http:
read-timeout: 0
+
media:
ip: 10.10.10.200
url: 'http://10.10.10.200:5080'