调整为异步 context
This commit is contained in:
parent
111d44b187
commit
c1e9ce147f
@ -1,6 +1,8 @@
|
|||||||
package cn.skcks.docking.gb28181.wvp.api.video;
|
package cn.skcks.docking.gb28181.wvp.api.video;
|
||||||
|
|
||||||
import cn.skcks.docking.gb28181.wvp.service.video.RecordService;
|
import cn.skcks.docking.gb28181.wvp.service.video.RecordService;
|
||||||
|
import jakarta.servlet.AsyncContext;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -19,7 +21,7 @@ public class RecordController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public void record(HttpServletResponse response, @RequestParam String url,@RequestParam long time){
|
public void record(HttpServletRequest request, HttpServletResponse response, @RequestParam String url, @RequestParam long time){
|
||||||
recordService.record(response,url,time);
|
recordService.record(request, response,url,time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,17 @@ package cn.skcks.docking.gb28181.wvp.service.video;
|
|||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.skcks.docking.gb28181.wvp.executor.DefaultVideoExecutor;
|
||||||
|
import jakarta.servlet.AsyncContext;
|
||||||
|
import jakarta.servlet.ServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.bytedeco.ffmpeg.global.avcodec;
|
import org.bytedeco.ffmpeg.global.avcodec;
|
||||||
import org.bytedeco.ffmpeg.global.avutil;
|
import org.bytedeco.ffmpeg.global.avutil;
|
||||||
import org.bytedeco.javacv.*;
|
import org.bytedeco.javacv.*;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -27,19 +32,27 @@ public class RecordService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public void record(HttpServletResponse response, String url, long timeout){
|
public void record(HttpServletRequest request, HttpServletResponse response, String url, long timeout) {
|
||||||
response.reset();
|
AsyncContext asyncContext = request.startAsync();
|
||||||
// response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
asyncContext.start(() -> {
|
||||||
header(response);
|
header(response);
|
||||||
|
record(asyncContext.getResponse(), url, timeout);
|
||||||
|
log.info("record 结束");
|
||||||
|
asyncContext.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public void record(ServletResponse response, String url, long timeout) {
|
||||||
|
// response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
Path tmp = Path.of(System.getProperty("java.io.tmpdir"), IdUtil.getSnowflakeNextIdStr()).toAbsolutePath();
|
Path tmp = Path.of(System.getProperty("java.io.tmpdir"), IdUtil.getSnowflakeNextIdStr()).toAbsolutePath();
|
||||||
File file = new File(tmp + ".mp4");
|
File file = new File(tmp + ".mp4");
|
||||||
log.info("创建文件 {}, {}", file, file.createNewFile());
|
log.info("创建文件 {}, {}", file, file.createNewFile());
|
||||||
|
|
||||||
log.info("url {}", url);
|
log.info("url {}", url);
|
||||||
try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(url)) {
|
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(url);
|
||||||
grabber.start();
|
grabber.start();
|
||||||
try(FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(file, grabber.getImageWidth(), grabber.getImageHeight(),grabber.getAudioChannels())){
|
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(file, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());
|
||||||
recorder.start();
|
recorder.start();
|
||||||
log.info("开始录像");
|
log.info("开始录像");
|
||||||
log.info("{}", file);
|
log.info("{}", file);
|
||||||
@ -61,21 +74,22 @@ public class RecordService {
|
|||||||
while (record.get() && (frame = grabber.grab()) != null) {
|
while (record.get() && (frame = grabber.grab()) != null) {
|
||||||
recorder.record(frame);
|
recorder.record(frame);
|
||||||
}
|
}
|
||||||
grabber.stop();
|
grabber.close();
|
||||||
recorder.stop();
|
recorder.close();
|
||||||
} catch (FFmpegFrameRecorder.Exception | FrameGrabber.Exception e) {
|
} catch (FFmpegFrameRecorder.Exception | FrameGrabber.Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
log.info("结束录制");
|
log.info("结束录制");
|
||||||
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||||
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
|
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
|
||||||
try {
|
try {
|
||||||
IoUtil.copy(inputStream, outputStream);
|
IoUtil.copy(inputStream, outputStream);
|
||||||
} catch (Exception ignore){}
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
log.info("临时文件 {} 写入 响应 完成", file);
|
log.info("临时文件 {} 写入 响应 完成", file);
|
||||||
log.info("删除临时文件 {} {}", file, file.delete());
|
log.info("删除临时文件 {} {}", file, file.delete());
|
||||||
}
|
outputStream.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user