ffmpeg 转换视频流 试水, 未完

This commit is contained in:
shikong 2023-09-06 03:42:11 +08:00
parent af0229ac55
commit 6266f0c7d1
5 changed files with 180 additions and 11 deletions

View File

@ -1,6 +1,8 @@
package cn.skcks.docking.gb28181.wvp.api;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.skcks.docking.gb28181.media.config.ZlmMediaConfig;
import cn.skcks.docking.gb28181.wvp.config.SwaggerConfig;
import cn.skcks.docking.gb28181.wvp.proxy.ZlmProxyClient;
import feign.Response;
@ -8,24 +10,34 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Path;
import static org.bytedeco.ffmpeg.global.avutil.AVMEDIA_TYPE_VIDEO;
@Slf4j
@Tag(name = "视频api")
@Controller
@RequestMapping("/video")
@RequiredArgsConstructor
public class VideoController {
private final ZlmProxyClient zlmProxyClient;
private final ZlmMediaConfig config;
@Bean
public GroupedOpenApi videoApi() {
@ -35,9 +47,9 @@ public class VideoController {
@Operation(summary = "获取视频")
@GetMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public void video(HttpServletResponse response) {
public ResponseEntity<File> video(HttpServletResponse response) throws IOException {
response.reset();
// response.setHeader("Content-Type","video/mp4");
response.setContentType("video/mp4");
// File f = new File("E:\\#Camera\\DCIM\\100MEDIA\\20230818\\NORM0003.MP4");
// try (
// BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(f));
@ -45,12 +57,89 @@ public class VideoController {
// IoUtil.copy(inputStream, outputStream);
// }
// try{
Path tmp = Path.of(System.getProperty("java.io.tmpdir"),IdUtil.getSnowflakeNextIdStr()).toAbsolutePath();
File file = new File(tmp +".mp4");
log.info("创建文件 {}, {}",file, file.createNewFile());
try (Response live = zlmProxyClient.live("live", "test.live.mp4")) {
InputStream inputStream = live.body().asInputStream();
OutputStream outputStream = response.getOutputStream();
IoUtil.copy(inputStream, outputStream);
// FFmpegLogCallback.set();
// live.body()
// FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(live.body().asInputStream());
String url = StringUtils.joinWith("/",config.getUrl(), "live","test.live.mp4");
log.info("url {}",url);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(url);
grabber.start();
try(FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(file,1920,1080,0)){
recorder.start();
log.info("开始录像");
log.info("{}",file);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
// recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); //视频源数据yuv
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); //设置音频压缩方式
recorder.setFormat("mp4");
recorder.setVideoOption("threads", String.valueOf(Runtime.getRuntime().availableProcessors())); //解码线程数
try (Java2DFrameConverter converter = new Java2DFrameConverter()){
// 建议在线程中使用该方法
Frame frame;
// 此处仅为本地预览
// CanvasFrame cframe = new CanvasFrame("欢迎来到直播间", CanvasFrame.getDefaultGamma() /
// grabber.getGamma());
// cframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 窗口关闭则程序关闭
// cframe.setAlwaysOnTop(true);
while ((frame = grabber.grab()) != null) {
if(frame.streamIndex == AVMEDIA_TYPE_VIDEO){
// BufferedImage bufferedImage = converter.getBufferedImage(frame);
// frame.image = converter.getFrame(bufferedImage).image;
recorder.record(frame);
}
// cframe.showImage(frame);
}
grabber.stop();
grabber.release();
recorder.stop();
} catch (FFmpegFrameRecorder.Exception | FrameGrabber.Exception e) {
throw new RuntimeException(e);
}
}
log.info("录像结束");
// response.getOutputStream().close();
// } finally {
// log.info("临时文件 {} 写入完成",file);
// FileInputStream fileInputStream = new FileInputStream(file);
// OutputStream outputStream = response.getOutputStream();
// IoUtil.copy(fileInputStream, outputStream);
// log.info("临时文件 {} 写入 响应 完成",file);
// fileInputStream.close();
return ResponseEntity.ok().body(file);
// InputStream inputStream = live.body().asInputStream();
// Path tmp = Path.of(System.getProperty("java.io.tmpdir"),IdUtil.getSnowflakeNextIdStr()).toAbsolutePath();
// File file = File.createTempFile(tmp.toString(),".mp4");
// log.info("临时文件 {}", file);
// FileOutputStream fileOutputStream = new FileOutputStream(file);
// BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
// IoUtil.copy(inputStream, bufferedOutputStream);
// log.info("临时文件 {} 写入完成",file);
// FileInputStream fileInputStream = new FileInputStream(file);
// BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
// OutputStream outputStream = response.getOutputStream();
// IoUtil.copy(bufferedInputStream, outputStream);
// log.info("临时文件 {} 写入 响应 完成",file);
// fileInputStream.close();
// file.delete();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
file.deleteOnExit();
}
// return ResponseEntity.noContent().build();
}
}

View File

@ -64,6 +64,27 @@
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>javacv-platform</artifactId>-->
<!-- <version>1.5.6</version>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco/ffmpeg-platform -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.4-1.5.6</version>
</dependency>
</dependencies>
<build>
@ -87,4 +108,4 @@
</testResource>
</testResources>
</build>
</project>
</project>

View File

@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableFeignClients(basePackages = {
"cn.skcks.docking.gb28181.media",
@ -14,9 +15,11 @@ import org.springframework.context.annotation.ComponentScan;
"cn.skcks.docking.gb28181.annotation",
"cn.skcks.docking.gb28181.common",
"cn.skcks.docking.gb28181.wvp",
"cn.skcks.docking.gb28181.media",
})
@EnableAsync
public class Gb28181WvpProxyStarter {
public static void main(String[] args) {
SpringApplication.run(Gb28181WvpProxyStarter.class, args);
}
}
}

View File

@ -0,0 +1,47 @@
server:
port: 18186
project:
version: @project.version@
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
config:
activate:
on-profile: local
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

View File

@ -4,6 +4,7 @@ server:
project:
version: @project.version@
spring:
data:
redis:
@ -24,6 +25,14 @@ spring:
username: root
password: 123456a
url: jdbc:mysql://192.168.1.241:3306/gb28181_docking_platform?createDatabaseIfNotExist=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
profiles:
active: local
cloud:
openfeign:
httpclient:
connection-timeout: 0
ok-http:
read-timeout: 0
media:
ip: 192.168.1.241
@ -37,4 +46,4 @@ proxy:
wvp:
url: http://192.168.3.13:18978
user: admin
passwd: admin
passwd: admin