系统需要做一个用户自己对视频资源截取视频关键帧并保存为图片的功能,页面如下:
之前用的是在程序里调用ffmpeg.exe截图,之前是部署在windows系统上,最近公司要求把系统部署到linux系统上,觉得用这个还要考虑兼容,javacv虽然比直接调用exe执行要慢一点,但还能接受,所以换了这个。
依赖如下:
<!-- 视频关键帧截图 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.0.2-1.4.3</version>
</dependency>
接口代码:
/**
* 视频关键帧截图
* @param videoPath 视频路径
* @param secs 需要截取关键帧的视频时间
* @return
*/
public String generateImage(String videoPath, String secs){
String picName = UUID.randomUUID().toString().replaceAll("-", "") + ".jpg";
File tempFileDir = new File(uploadFilePath);
if(!tempFileDir.exists()){
tempFileDir.mkdirs();
}
String imagePath = uploadFilePath + picName;
try {
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videoPath);
ff.start();
Frame f = null;
//传入的参数是秒,这里需要处理的时间戳是按微秒走的,需要转换一下
Double d = Double.parseDouble(secs);
long targetFrameNum = (long) (d * 1000 * 1000);
ff.setTimestamp(targetFrameNum);
//根据传入的时间戳,抓取指定时间的视频关键帧
f = ff.grabImage();
if (f != null) {
//处理并生成图片
int owidth = f.imageWidth;
int oheight = f.imageHeight;
// 对截取的帧进行等比例缩放
int width = 800;
int height = (int) (((double) width / owidth) * oheight);
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage fecthedImage = converter.getBufferedImage(f);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bi.getGraphics().drawImage(fecthedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH),
0, 0, null);
ImageIO.write(bi, "jpg", new File(imagePath));
}
ff.stop();
} catch (IOException e) {
e.printStackTrace();
}
return picName;
}
参数样式: