方法一:使用FFmpeg
1、下载相关工具(只需解压)
下载地址:Download FFmpeg
点击Windows EXE Files的Window builds from gyan.dev,进行下载解压
2、pom导入依赖
<!-- ffmpeg -->
<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>
3、编写测试类
//生成图片并调用上传方法
@Test
public void getVideoInfo() {
try {
File file = new File("C:\\Users\\lanys\\Desktop\\周报\\21400e3e608358da2d970bd7f69a37f1.mp4");//本地视频资源
FileInputStream fileInputStream = new FileInputStream(file);
//放入采集器
FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(fileInputStream);
//启动
fFmpegFrameGrabber.start();
//截取图片
Frame frame = fFmpegFrameGrabber.grabImage();
Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();
BufferedImage bufferedImage = java2DFrameConverter.getBufferedImage(frame);
//创建一个ByteArrayOutputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
//输出 可以不用
ImageIO.write(bufferedImage, "jpg", os);
InputStream input = new ByteArrayInputStream(os.toByteArray());
//InputStream转成MultipartFile
MultipartFile multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
s5(multipartFile);
fFmpegFrameGrabber.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
@Autowired
private OSS ossClient;
@Autowired
private AliyunConfig aliyunConfig;
//将图片上传至OSS云存储空间
public void s5(MultipartFile multipartFile){
//获取图片名称
String originalFilename = multipartFile.getOriginalFilename();;
DateTime dateTime = new DateTime();
String filePath = "uploads/dynamic/pictures/" + dateTime.toString("yyyy") + dateTime.toString("MM") + dateTime.toString("dd") + "/" + System.currentTimeMillis() +
RandomUtils.nextInt(100, 9999) + "." +
StringUtils.substringAfterLast(originalFilename, ".");
try {
ossClient.putObject(aliyunConfig.getBucket(), filePath, new
ByteArrayInputStream(multipartFile.getBytes()));
log.info("--------视频上传成功--------");
} catch (Exception e) {
e.printStackTrace();
log.info("上传失败");
}
}
方法二:使用第三方自带的截取视频帧方法
以阿里云OSS存储举例。
1、首先需要将视频上传至OSS存储空间
有关阿里云OSS的注册与使用,可以参考这个文档 阿里云OSS注册与使用_alioss-CSDN博客
2、pom引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
3、SpringBoot整合OSS视频帧
获得视频截图路径后,可以直接通过网络流上传至OSS存储空间中
获得视频截图方法getPoster()
/**
* 获取视频截图路径
*
* @param videosPath
* @return
* @throws IOException
*/
public String getPoster(String videosPath) {
// 需要的参数是视频外网访问地址
String objectName = videosPath;
//Bucket
String bucketName = "edu-lzsc";
// 截取视频5s处的内容,宽度为1080,高度为1800,图片格式:png。
String style = "video/snapshot,t_500,f_jpg,w_1080,h_1800,f_png";
// 指定过期时间为10分钟。
Date expiration = new Date(System.currentTimeMillis() + 1000 * 60 * 10);
GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
//过期时间必须设置,不然报错提示
req.setExpiration(expiration);
req.setProcess(style);
StorageConfig storageConfig = this.getStorageConfig();
OSS ossClient = new OSSClientBuilder().build(storageConfig.getEndpoint(), storageConfig.getAccessKeyId(), storageConfig.getAccessKeySecret());
//获取可视化帧数路径,有过期时间
URL signedUrl = ossClient.generatePresignedUrl(req);
System.out.println(signedUrl);
System.out.println("打印获取url的路径"+videosPath+"?x-oss-process=video/snapshot,t_7000,f_png,w_800,h_600");
//获取url的路径
String videoPicUrl=videosPath+"?x-oss-process=video/snapshot,t_7000,f_png,w_800,h_600";
// String stream = UploadNetworkStream( videosPath+"?x-oss-process=video/snapshot,t_7000,f_png,w_800,h_600");
return videoPicUrl;
}
直接上传OSS云存储
/**
* 上传网络流
* @param url
* @throws IOException
*/
public String UploadNetworkStream(String url) throws IOException {
System.out.println(url);
//随机生成一个图片名
String Path = RandomUtils.nextInt(100, 9999)+".jpg";
DateTime dateTime = new DateTime();
//生成一个真正的图片路径(用于数据库存储)
String picturePath = "uploads/dynamic/videos/" + dateTime.toString("yyyy") + dateTime.toString("MM") + dateTime.toString("dd") + "/" + System.currentTimeMillis() +"/"+Path;
// 上传网络流, url指的是生成可视化的路径,获取流
InputStream inputStream = new URL(url).openStream();
try{
//上传 OssBucketName就是yml中桶的名称,picturePath 上传的路径,inputStream流
ossClient.putObject(OssBucketName, picturePath, inputStream);
//成功返回路径
return picturePath;
}catch (Exception e){
log.info("-------图片复制失败-------");
e.printStackTrace();
}
return null;
}
这个获得截图url的方法就是直接将OSS存储的视频外网访问地址与官方文档里的内容进行拼接
具体操作请见阿里云官方文档 视频截帧方法及示例_对象存储(OSS)-阿里云帮助中心