Toggle navigation
技术博客
首页
Java
Spring
DB
服务器
JS
软件
微语
留言
登录
当前位置:
首页
Spring
获取视频文件的封面图片
获取视频文件的封面图片
2022-11-16 17:40:32
字数:7856
682
次
Spring
基于SpringBoot实现上传视频并获取视频文件的第一帧作为视频文件的封面图片 ##### 引入依赖 ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--视频截图依赖--> <!-- 视频处理需要的4个jar --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacpp</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv-platform</artifactId> <version>3.4.1-1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>ffmpeg-platform</artifactId> <version>3.4.2-1.4.1</version> </dependency> <!--视频截图依赖--> ``` ##### 文件对象 ``` @Getter @Setter public class FileResult { private String id; private String oldFileName; //原文件名 private String filePath;//文件路径 private String realFilePath; // 文件路径 private String fileSize; //文件大小 private String newFileName; //文件大小 private String suffixName;//扩展名 private String coverImage; // 封面图片 private String insertDate; // } ``` ##### 文件上传类 ``` // 文件上传保存路径 @Value("${uploadPath}") private String uploadPath; // 文件读取路径 @Value("${readPath}") private String readPath; /** * 上传多个附件 */ @RequestMapping(value = "/uploadFiles") public List<FileResult> uploadFiles(@RequestParam("attachments") MultipartFile[] attachments, HttpServletRequest request) throws Exception { List<FileResult> list = CommonHelper.uploadFiles( attachments, uploadPath, readPath ); return list; } ``` ##### 文件上传 ``` public static List<FileResult> uploadFiles(MultipartFile[] attachments, String uploadPath, String readPath) throws Exception { List<FileResult> list = new ArrayList<>(); for (MultipartFile multipartFile : attachments) { // 获取原始名字 String oldFileName = multipartFile.getOriginalFilename(); // 获取后缀名 String suffixName = oldFileName.substring(Objects.requireNonNull(oldFileName).lastIndexOf(".")); // 文件重命名,防止重复 String fileName = UUID.randomUUID().toString(); String newFileName = fileName + suffixName; // 文件上传路径 String realPath = new String(uploadPath.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8) + newFileName; String finalFilePath = uploadPath+fileName+".jpg"; String readFilePath = readPath + newFileName; File dest = new File(realPath); // 判断路径是否存在,如果不存在则创建 if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); } // 保存到服务器中 multipartFile.transferTo(dest); FileResult attachmentParams = new FileResult(); // 获取文件大小 String fileSize = changeFileSize(multipartFile.getSize(), "M"); attachmentParams.setOldFileName(oldFileName); //原文件名 attachmentParams.setFilePath(readFilePath); attachmentParams.setRealFilePath(realPath); attachmentParams.setFileSize(fileSize);//文件大小 attachmentParams.setNewFileName(newFileName); attachmentParams.setSuffixName(suffixName);//扩展名 if (isVideo(suffixName)) { String coverImageName = VideoHelper.fetchFirstPicFromVideo(readFilePath,finalFilePath); String coverImage = readPath+coverImageName; attachmentParams.setCoverImage(coverImage); } else { // 压缩图片 ImageZipUtil.zipImageFile(dest, dest, 1.2f); } list.add(attachmentParams); } return list; } /** * 转换上传文件大小 * * @param len 文件长度 * @param unit 转换单位(B,K,M,G) * @return */ public static String changeFileSize(Long len, String unit) { double fileSize = 0; if ("B".equals(unit.toUpperCase())) { fileSize = (double) len; } else if ("K".equals(unit.toUpperCase())) { fileSize = (double) len / 1024; } else if ("M".equals(unit.toUpperCase())) { fileSize = (double) len / 1048576; } else if ("G".equals(unit.toUpperCase())) { fileSize = (double) len / 1073741824; } DecimalFormat df = new DecimalFormat("#.00"); return df.format(fileSize) + unit.toUpperCase(); } //判断是否是视频 public static Boolean isVideo(String suffix) { String suffixName = suffix.toUpperCase(); return suffixName.contains("MP4") || suffixName.contains("AVI") || suffixName.contains("WMV") || suffixName.contains("SWF"); } ``` ##### 图片压缩类 `ImageZipUtil` ``` /** * 根据设置的宽高等比例压缩图片文件<br> 先保存原文件,再压缩、上传 * @param oldFile 要进行压缩的文件 * @param newFile 新文件 * @param width 宽度 //设置宽度时(高度传入0,等比例缩放) * @param height 高度 //设置高度时(宽度传入0,等比例缩放) * @param quality 质量 * @return 返回压缩后的文件的全路径 */ public static String zipImageFile(File oldFile,File newFile,float quality) { if (oldFile == null) { return null; } try { /** 对服务器上的临时文件进行处理 */ Image srcFile = ImageIO.read(oldFile); int width = ((BufferedImage) srcFile).getWidth(); int height = ((BufferedImage) srcFile).getHeight(); String srcImgPath = newFile.getAbsoluteFile().toString(); System.out.println(srcImgPath); String subfix = "jpg"; subfix = srcImgPath.substring(srcImgPath.lastIndexOf(".")+1,srcImgPath.length()); BufferedImage buffImg = null; if(subfix.equals("png")){ buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); }else{ buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); } Graphics2D graphics = buffImg.createGraphics(); graphics.setBackground(new Color(255,255,255)); graphics.setColor(new Color(255,255,255)); graphics.fillRect(0, 0, width, height); graphics.drawImage(srcFile.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null); ImageIO.write(buffImg, subfix, new File(srcImgPath)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return newFile.getAbsolutePath(); } ``` ##### 获取视频封面方法 ``` import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; /** * @date 2022/10/19 10:31 * @decrption */ public class VideoHelper { /** * 将截取的帧生成文件 * @param frame * @return */ private static String getPicFromFrame(Frame frame, File targetFile) throws IOException { String imgFormat = "jpg"; Java2DFrameConverter converter = new Java2DFrameConverter(); BufferedImage srcBi = converter.getBufferedImage(frame); // 可以选择对截取的帧进行等比例缩放 int owidth = srcBi.getWidth(); int oheight = srcBi.getHeight(); int width = srcBi.getWidth(); int height = (int) (((double) width / owidth) * oheight); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); bi.getGraphics().drawImage(srcBi.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null); ByteArrayOutputStream output = new ByteArrayOutputStream(); // ImageIO工具类提供了将图片写成文件或者outputStream中 ImageIO.write(bi, imgFormat, targetFile); return targetFile.getName(); } /** * 获取视频的首帧并保存为图片 * * @param fileUrl 源视频文件Url路径 * @return 返回截取的帧 * @throws Exception */ public static String fetchFirstPicFromVideo(String fileUrl,String readFilePath) throws Exception { FFmpegFrameGrabber ff = new FFmpegFrameGrabber(fileUrl); ff.start(); Frame frame = ff.grabImage(); File targetFile = new File(readFilePath); if(targetFile.exists()){ targetFile.mkdirs(); } return getPicFromFrame(frame,targetFile); } ```
给我留言吧
昵称*
提交评论
留言板
目录
微信
分类
Nginx
系统
文学
生活
历史
地理
学习网站
nginx资源站
runoob学习网
redis学习网
vue中文网
dubbo
返回顶部
×
登录/注册
用户名
昵称
密码
确认密码
提交
没有账号?
马上注册
提交
已有账号?
去登录