一、通过JavaCV
引入依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.7</version>
</dependency>
工具类
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
public class JavaCvUtil {
/**
* @param videoFilePath 视频文件路径
* @param outFramePath 输出帧的路径
* @param frameNum 帧序号,从1开始
* @return 返回真图片对应的File对象
*/
public static File getFrameFile(String videoFilePath, String outFramePath, int frameNum) {
try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(videoFilePath)) {
grabber.start();
// 获取帧
Frame frame = null;
while (frameNum > 0) {
frame = grabber.grabImage();
frameNum--;
}
// 转换为BufferedImage
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage image = converter.getBufferedImage(frame);
// 保存为图片
ImageIO.write(image, "jpg", new File(outFramePath));
System.out.println("帧已保存到: " + outFramePath);
return new File(outFramePath);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
二、通过ffmpeg命令
首先要下载ffmpeg,配置环境变量,可参考:FFmpeg 超级详细安装与配置教程(Windows 系统)_windows安装ffmpeg-CSDN博客
工具类
import java.io.File;
import java.io.IOException;
public class FfmpegUtil {
/**
* @param videoFilePath 视频文件路径
* @param outFramePath 输出帧的路径
* @param frameNum 帧序号,从1开始
* @return 返回真图片对应的File对象
*/
public static File getFrameFile(String videoFilePath, String outFramePath, int frameNum) {
try {
ProcessBuilder pb = new ProcessBuilder(
"ffmpeg",
"-i", videoFilePath,
"-vframes", "1",
// 由于ffmpeg的参数select的参数n是0开始,所以这里减1
"-vf","select=eq(n\\,%d)".formatted(frameNum - 1),
"-q:v", "2",
outFramePath
);
Process process = pb.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("帧已保存到: " + outFramePath);
} else {
System.out.println("截取帧失败");
}
return new File(outFramePath);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
}