| New file | 
|  |  |  | 
|---|
|  |  |  | package com.dy.pipIrrWebFile.util; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import lombok.extern.slf4j.Slf4j; | 
|---|
|  |  |  | import org.apache.commons.io.FileUtils; | 
|---|
|  |  |  | import org.jcodec.api.FrameGrab; | 
|---|
|  |  |  | import org.jcodec.common.model.Picture; | 
|---|
|  |  |  | import org.jcodec.scale.AWTUtil; | 
|---|
|  |  |  | import org.springframework.web.multipart.MultipartFile; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.imageio.ImageIO; | 
|---|
|  |  |  | import java.awt.image.BufferedImage; | 
|---|
|  |  |  | import java.io.*; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * @Author: liurunyu | 
|---|
|  |  |  | * @Date: 2025/1/13 11:22 | 
|---|
|  |  |  | * @Description | 
|---|
|  |  |  | */ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 视频操作工具类 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Slf4j | 
|---|
|  |  |  | public class VideoUtils { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /*** 图片格式*/ | 
|---|
|  |  |  | private static final String FILE_EXT = "jpg"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /*** 帧数*/ | 
|---|
|  |  |  | private static final int THUMB_FRAME = 5; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /*** 图片格式*/ | 
|---|
|  |  |  | private String fileExt ; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /*** 帧数*/ | 
|---|
|  |  |  | private Integer thumbFrame ; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public VideoUtils(){ | 
|---|
|  |  |  | this.fileExt = FILE_EXT; | 
|---|
|  |  |  | this.thumbFrame = THUMB_FRAME; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public VideoUtils(String fileExt, int thumbFrame){ | 
|---|
|  |  |  | this.fileExt = fileExt; | 
|---|
|  |  |  | this.thumbFrame = thumbFrame; | 
|---|
|  |  |  | if(this.fileExt == null || this.fileExt.trim().equals("")){ | 
|---|
|  |  |  | this.fileExt = FILE_EXT; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(this.thumbFrame == null || this.thumbFrame.intValue() <= 0){ | 
|---|
|  |  |  | this.thumbFrame = THUMB_FRAME; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取指定视频的帧并保存为图片至指定目录 | 
|---|
|  |  |  | * @param videoFilePath 源视频文件路径 | 
|---|
|  |  |  | * @param frameFilePath 截取帧的图片存放路径 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void fetchFrame(String videoFilePath, String frameFilePath) throws Exception { | 
|---|
|  |  |  | File videoFile = new File(videoFilePath); | 
|---|
|  |  |  | File frameFile = new File(frameFilePath); | 
|---|
|  |  |  | getThumbnail(videoFile, frameFile); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取指定视频的帧并保存为图片至指定目录 | 
|---|
|  |  |  | * @param videoFilePath 源视频文件路径 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public BufferedImage fetchFrame(String videoFilePath) throws Exception { | 
|---|
|  |  |  | File videoFile = new File(videoFilePath); | 
|---|
|  |  |  | return getThumbnail(videoFile); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取指定视频的帧并保存为图片至指定目录 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param videoFile  源视频文件 | 
|---|
|  |  |  | * @param targetFile 截取帧的图片 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void fetchFrame(MultipartFile videoFile, File targetFile) throws Exception { | 
|---|
|  |  |  | File file = new File(videoFile.getName()); | 
|---|
|  |  |  | FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file); | 
|---|
|  |  |  | getThumbnail(file, targetFile); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取指定视频的帧并保存为图片至指定目录 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param videoFile  源视频文件 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public BufferedImage fetchFrame(MultipartFile videoFile) throws Exception { | 
|---|
|  |  |  | File file = new File(videoFile.getName()); | 
|---|
|  |  |  | FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file); | 
|---|
|  |  |  | return getThumbnail(file); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取指定视频的帧并保存为图片至指定目录 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param videoFile 源视频文件 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public File fetchFrame2(MultipartFile videoFile) { | 
|---|
|  |  |  | String originalFilename = videoFile.getOriginalFilename(); | 
|---|
|  |  |  | File file = new File(originalFilename); | 
|---|
|  |  |  | File targetFile = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | FileUtils.copyInputStreamToFile(videoFile.getInputStream(), file); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int i = originalFilename.lastIndexOf("."); | 
|---|
|  |  |  | String imageName; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (i > 0) { | 
|---|
|  |  |  | imageName = originalFilename.substring(0, i); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | imageName = UUID.randomUUID().toString().replace("-", ""); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | imageName = imageName + ".jpg"; | 
|---|
|  |  |  | targetFile = new File(imageName); | 
|---|
|  |  |  | getThumbnail(file, targetFile); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | log.error("获取视频指定帧异常:", e); | 
|---|
|  |  |  | } finally { | 
|---|
|  |  |  | if (file.exists()) { | 
|---|
|  |  |  | file.delete(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | log.debug("视频文件 - 帧截取 - 处理结束"); | 
|---|
|  |  |  | return targetFile; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | */ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取第一帧缩略图 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param videoFile  视频路径 | 
|---|
|  |  |  | * @param targetFile 缩略图目标路径 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public void getThumbnail(File videoFile, File targetFile) throws Exception { | 
|---|
|  |  |  | // 根据扩展名创建一个新文件路径 | 
|---|
|  |  |  | Picture picture = FrameGrab.getFrameFromFile(videoFile, thumbFrame); | 
|---|
|  |  |  | BufferedImage bufferedImage = AWTUtil.toBufferedImage(picture); | 
|---|
|  |  |  | ImageIO.write(bufferedImage, fileExt, targetFile); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取第一帧缩略图 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param videoFile  视频路径 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | public BufferedImage getThumbnail(File videoFile) throws Exception { | 
|---|
|  |  |  | // 根据扩展名创建一个新文件路径 | 
|---|
|  |  |  | Picture picture = FrameGrab.getFrameFromFile(videoFile, thumbFrame); | 
|---|
|  |  |  | BufferedImage bufferedImage = AWTUtil.toBufferedImage(picture); | 
|---|
|  |  |  | return bufferedImage; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | public static void main(String[] args) { | 
|---|
|  |  |  | VideoUtils util = new VideoUtils(); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | long startTime = System.currentTimeMillis(); | 
|---|
|  |  |  | util.getThumbnail(new File("D:\\mp4\\test.mp4"), new File("D:\\mp4\\test.jpg")); | 
|---|
|  |  |  | System.out.println("截取图片耗时:" + (System.currentTimeMillis() - startTime)); | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|