From dcadab885677e68b69831b588932afafdb6e92a6 Mon Sep 17 00:00:00 2001 From: liurunyu <lry9898@163.com> Date: 星期一, 13 一月 2025 14:52:17 +0800 Subject: [PATCH] 增加视频文件生成缩略图功能 --- pipIrr-platform/pom.xml | 22 ++++ pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/ZipImg.java | 18 +++ pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/VideoUtils.java | 172 ++++++++++++++++++++++++++++++++++ pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/files/FileCtrl.java | 57 ++++++++++ pipIrr-platform/pipIrr-web/pom.xml | 17 +++ 5 files changed, 283 insertions(+), 3 deletions(-) diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/files/FileCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/files/FileCtrl.java index f8e6734..62f19d8 100644 --- a/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/files/FileCtrl.java +++ b/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/files/FileCtrl.java @@ -9,8 +9,9 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import java.io.File; -import java.io.InputStream; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; /** * web鏂囦欢涓婁紶, 鍐呴儴璋冪敤锛屽嵆鐢卞叾浠栧瓙妯″潡璋冪敤锛� @@ -24,6 +25,9 @@ @Value("${dy.photoZipWidth}") private String photoZipWidthStr ; + + private static final String VideoZipPicFileType = "jpg"; + private static final Integer VideoZipPicFromFrame = 5 ; /** * web鍒嗗竷寮忔枃浠剁郴缁熶繚瀛樼収鐗囨枃浠� @@ -65,7 +69,7 @@ String zipFilePath1 = filePath.substring(0, index) ; String zipFilePath2 = filePath.substring(index) ; String zipFilePath = zipFilePath1 + "_" + zipFilePath2 ; - InputStream zipFileInput = null ; + InputStream zipFileInput ; if(zipFilePath2.equalsIgnoreCase(".png")){ zipFileInput = ZipImg.zipToPng(fPic, photoZipWidth, photoZipWidth) ; }else{ @@ -152,6 +156,26 @@ String filePath = absolutePath + fileRelativePath ; if(!fUtil.saveFile(filePath, input)){ fileRelativePath = null ; + }else { + //瀛樺偍鎴愬姛, 鐢熸垚缂╃暐鍥� + BufferedImage bufImg = new VideoUtils(VideoZipPicFileType, VideoZipPicFromFrame).fetchFrame(file) ; + int index = filePath.lastIndexOf(".") ; + String basePath = filePath.substring(0, index) ; + Integer photoZipWidth = 400 ; + if(photoZipWidthStr != null && NumUtil.isPlusIntNumber(photoZipWidthStr)){ + photoZipWidth = Integer.parseInt(photoZipWidthStr) ; + } + String zipFilePath = basePath + "_." + VideoZipPicFileType ; + InputStream zipFileInput = ZipImg.zipToJpg(bufImg, photoZipWidth, photoZipWidth) ; + if(zipFileInput.available() > 0){ + new FileUtil().saveFile(zipFilePath, zipFileInput) ; + }else{ + //濡傛灉鍘嬬缉鏂囦欢涓嶅瓨鍦ㄦ垨鐢熸垚澶辫触锛屽垯澶嶅埗婧愭枃浠� + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageIO.write(bufImg, VideoZipPicFileType, os); + InputStream in = new ByteArrayInputStream(os.toByteArray()); + new FileUtil().saveFile(zipFilePath, in) ; + } } } } @@ -199,4 +223,31 @@ return fileRelativePath ; } + + public static void main(String[] args) throws Exception{ + String photoZipWidthStr = "400" ; + String VideoZipPicFileType = "jpg"; + //瀛樺偍鎴愬姛, 鐢熸垚缂╃暐鍥� + String filePath = "D:\\mp4\\test.mp4" ; + BufferedImage bufImg = new VideoUtils("jpg", 0).fetchFrame(filePath) ; + int index = filePath.lastIndexOf(".") ; + String basePath = filePath.substring(0, index) ; + Integer photoZipWidth = 400 ; + if(photoZipWidthStr != null && NumUtil.isPlusIntNumber(photoZipWidthStr)){ + photoZipWidth = Integer.parseInt(photoZipWidthStr) ; + } + String zipFilePath = basePath + "_." + VideoZipPicFileType ; + InputStream zipFileInput = null ; + zipFileInput = ZipImg.zipToJpg(bufImg, photoZipWidth, photoZipWidth) ; + if(zipFileInput.available() > 0){ + new FileUtil().saveFile(zipFilePath, zipFileInput) ; + }else{ + //濡傛灉鍘嬬缉鏂囦欢涓嶅瓨鍦ㄦ垨鐢熸垚澶辫触锛屽垯澶嶅埗婧愭枃浠� + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageIO.write(bufImg, VideoZipPicFileType, os); + InputStream in = new ByteArrayInputStream(os.toByteArray()); + new FileUtil().saveFile(zipFilePath, in) ; + } + } + } diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/VideoUtils.java b/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/VideoUtils.java new file mode 100644 index 0000000..1258861 --- /dev/null +++ b/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/VideoUtils.java @@ -0,0 +1,172 @@ +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(); + } + } + +} diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/ZipImg.java b/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/ZipImg.java index 180ca61..fecc46f 100644 --- a/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/ZipImg.java +++ b/pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/java/com/dy/pipIrrWebFile/util/ZipImg.java @@ -18,8 +18,16 @@ return zip(file, "jpg", xSize, ySize) ; } + public static InputStream zipToJpg(BufferedImage buf, int xSize, int ySize) throws Exception{ + return zip(buf, "jpg", xSize, ySize) ; + } + public static InputStream zipToPng(File file, int xSize, int ySize) throws Exception{ return zip(file, "png", xSize, ySize) ; + } + + public static InputStream zipToPng(BufferedImage buf, int xSize, int ySize) throws Exception{ + return zip(buf, "png", xSize, ySize) ; } public static void zipToFile(File file, File toFile, int xSize, int ySize) throws Exception{ @@ -36,6 +44,16 @@ os = null ; return in ; } + + private static InputStream zip(BufferedImage buf, String type, int xSize, int ySize) throws Exception{ + BufferedImage bi = Thumbnails.of(buf).size(xSize, ySize).outputQuality(1f).asBufferedImage(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ImageIO.write(bi, type, os); + InputStream in = new ByteArrayInputStream(os.toByteArray()); + bi = null ; + os = null ; + return in ; + } public static void main(String[] args){ File f = new File("D:/test.jpg") ; diff --git a/pipIrr-platform/pipIrr-web/pom.xml b/pipIrr-platform/pipIrr-web/pom.xml index 9f2da8a..4998d97 100644 --- a/pipIrr-platform/pipIrr-web/pom.xml +++ b/pipIrr-platform/pipIrr-web/pom.xml @@ -226,6 +226,23 @@ </exclusions> </dependency> + <!-- java瑙嗛澶勭悊 --> + <dependency> + <groupId>org.jcodec</groupId> + <artifactId>jcodec</artifactId> + <version>0.2.5</version> + </dependency> + <dependency> + <groupId>org.jcodec</groupId> + <artifactId>jcodec-javase</artifactId> + <version>0.2.5</version> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.18.0</version> + </dependency> + <!-- 娴嬭瘯 --> <dependency> <groupId>org.springframework.boot</groupId> diff --git a/pipIrr-platform/pom.xml b/pipIrr-platform/pom.xml index a7955fc..97dc779 100644 --- a/pipIrr-platform/pom.xml +++ b/pipIrr-platform/pom.xml @@ -303,6 +303,28 @@ <scope>import</scope> </dependency> + <!-- java瑙嗛澶勭悊 --> + <dependency> + <groupId>org.jcodec</groupId> + <artifactId>jcodec</artifactId> + <version>0.2.5</version> + <type>pom</type> + <scope>import</scope> + </dependency> + <dependency> + <groupId>org.jcodec</groupId> + <artifactId>jcodec-javase</artifactId> + <version>0.2.5</version> + <type>pom</type> + <scope>import</scope> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.18.0</version> + <type>pom</type> + <scope>import</scope> + </dependency> <!-- 娴嬭瘯 --> <dependency> <groupId>org.springframework.boot</groupId> -- Gitblit v1.8.0