Переглянути джерело

feat: 视频转图片接口搞定

WANGKANG 10 місяців тому
батько
коміт
a80b04c348

+ 27 - 1
taais-modules/taais-biz/src/main/java/com/taais/biz/controller/Video2imageController.java

@@ -1,5 +1,6 @@
 package com.taais.biz.controller;
 
+import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -16,6 +17,10 @@ import com.taais.common.core.utils.StringUtils;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import com.taais.common.core.core.domain.CommonResult;
@@ -82,11 +87,22 @@ public class Video2imageController extends BaseController {
     @Log(title = "视频转图片", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping
-    public CommonResult<Void> add(@Validated @RequestBody Video2imageBo video2imageBo) {
+    public CommonResult add(@Validated @RequestBody Video2imageBo video2imageBo) {
         Video2imageBo newVideo2imageBo = new Video2imageBo();
         if (StringUtils.isEmpty(video2imageBo.getFileId())) {
             return CommonResult.fail("请上传视频文件!");
         }
+
+        Path filePath = Paths.get(UPLOAD_DIR, video2imageBo.getFileId());
+        File file = new File(filePath.toString());
+        if (!file.exists() || !file.isFile()) {
+            return CommonResult.fail("视频文件不存在!");
+        }
+        //
+        // if (video2imageBo.getFps() >= 60 || video2imageBo.getFps() <= 0) {
+        //     return CommonResult.fail("fps值必须在0-60之间!");
+        // }
+
         newVideo2imageBo.setName(video2imageBo.getName());
         newVideo2imageBo.setFileId(video2imageBo.getFileId());
         newVideo2imageBo.setFps(video2imageBo.getFps());
@@ -160,6 +176,7 @@ public class Video2imageController extends BaseController {
             return CommonResult.success("上传失败");
         }
     }
+
     @GetMapping("/start/{id}")
     public CommonResult startToImage(@PathVariable("id") Long id) {
         /**
@@ -172,4 +189,13 @@ public class Video2imageController extends BaseController {
             return CommonResult.fail("操作失败!");
         }
     }
+
+
+    @GetMapping("/zip/{id}")
+    public ResponseEntity<org.springframework.core.io.Resource> zipFolder(@PathVariable("id") Long id) throws IOException {
+        /**
+         * 传VideoImage的ID
+         */
+        return video2imageService.zipImages(id);
+    }
 }

+ 2 - 0
taais-modules/taais-biz/src/main/java/com/taais/biz/domain/bo/Video2imageBo.java

@@ -85,6 +85,8 @@ public class Video2imageBo extends BaseEntity{
      * 切割帧率,默认1
      */
     @NotNull(message = "切割帧率,默认1不能为空")
+    @Min(value = 1, message = "切割帧率,最小值为1")
+    @Max(value = 60, message = "切割帧率,最大值为60")
     private Long fps;
 
     /**

+ 4 - 1
taais-modules/taais-biz/src/main/java/com/taais/biz/service/IVideo2imageService.java

@@ -3,9 +3,10 @@ package com.taais.biz.service;
 import com.taais.biz.domain.Video2image;
 import com.taais.biz.domain.bo.Video2imageBo;
 import com.taais.biz.domain.vo.Video2imageVo;
-import com.taais.common.core.core.domain.CommonResult;
 import com.taais.common.core.core.page.PageResult;
 import com.taais.common.orm.core.service.IBaseService;
+import org.springframework.core.io.Resource;
+import org.springframework.http.ResponseEntity;
 
 import java.util.List;
 
@@ -65,4 +66,6 @@ public interface IVideo2imageService extends IBaseService<Video2image> {
     boolean deleteByIds(Long[] ids);
 
     boolean startToImage(Long id);
+
+    ResponseEntity<Resource> zipImages(Long id);
 }

+ 68 - 19
taais-modules/taais-biz/src/main/java/com/taais/biz/service/impl/Video2imageServiceImpl.java

@@ -1,5 +1,8 @@
 package com.taais.biz.service.impl;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
@@ -12,12 +15,16 @@ import com.taais.biz.domain.bo.Video2imageBo;
 import com.taais.biz.domain.vo.Video2imageVo;
 import com.taais.biz.mapper.Video2imageMapper;
 import com.taais.biz.service.IVideo2imageService;
-import com.taais.biz.utils.VideoCapture;
 import com.taais.common.core.utils.MapstructUtils;
 import com.taais.common.orm.core.page.PageQuery;
 import com.taais.common.core.core.page.PageResult;
 import com.taais.common.orm.core.service.impl.BaseServiceImpl;
-import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -25,6 +32,9 @@ import static com.taais.biz.constant.BizConstant.VideoStatus.END;
 import static com.taais.biz.constant.BizConstant.VideoStatus.RUNNING;
 import static com.taais.biz.domain.table.Video2imageTableDef.VIDEO2IMAGE;
 
+import com.taais.biz.utils.VideoCapture;
+import com.taais.biz.utils.ZipUtils;
+
 /**
  * 视频转图片 Service业务层处理
  *
@@ -32,9 +42,8 @@ import static com.taais.biz.domain.table.Video2imageTableDef.VIDEO2IMAGE;
  * 2024-08-16
  */
 @Service
+@Slf4j
 public class Video2imageServiceImpl extends BaseServiceImpl<Video2imageMapper, Video2image> implements IVideo2imageService {
-    @Resource
-    private Video2imageMapper video2imageMapper;
 
     @Override
     public QueryWrapper query() {
@@ -154,45 +163,85 @@ public class Video2imageServiceImpl extends BaseServiceImpl<Video2imageMapper, V
         video2image.setCostSecond((video2image.getEndTime().getTime() - video2image.getStartTime().getTime()) / 1000);
         this.updateById(video2image);
     }
+
     @Override
     public boolean startToImage(Long id) {
         Video2image video2image = this.getById(id);
         if (ObjectUtil.isNull(video2image)) {
-            System.out.println("ObjectUtil.isNotNull(video2image)...");
+            log.info("ObjectUtil.isNotNull(video2image)...");
             return false;
         }
-        System.out.println("开始截取图片...");
+        log.info("开始截取图片...");
 
         String videoPath = video2image.getPath();
         String outPath = video2image.getOutPath();
         Long fps = video2image.getFps();
 
-        System.out.println("videoPath: " + videoPath);
-        System.out.println("outPath: " + outPath);
-        System.out.println("fps: " + fps);
+        log.info("videoPath: " + videoPath);
+        log.info("outPath: " + outPath);
+        log.info("fps: " + fps);
+
+        File file = new File(videoPath);
+        if (!file.exists() || !file.isFile()) {
+            log.error("文件不存在...");
+            return false;
+        }
 
         video2image.setStatus(RUNNING);
         video2image.setStartTime(new Date());
         this.updateById(video2image);
 
-        System.out.println("开始截取图片子线程...");
-
         new Thread(() -> {
-            String log = "开始截取图片...\n";
-            System.out.println("开始截取图片...");
+            String log_str = "";
+            log.info("开始截取图片子线程...");
+            log.info("开始截取图片...");
+
+            log_str += "开始截取图片子线程...\n";
+            log_str += "开始截取图片...\n";
             try {
                 VideoCapture.startCaputre(videoPath, outPath, fps);
-                System.out.println("视频转图片结束...");
-                log += "视频转图片结束...\n";
+                log.info("视频转图片结束...");
+                log_str += "视频转图片结束...\n";
+
+                log.info("开始压缩图片...");
+                log_str += "开始压缩图片...\n";
+                String zipFilePath = Paths.get(outPath).resolveSibling(video2image.getName() + ".zip").toString();
+                ZipUtils.zipFolderFiles(outPath, zipFilePath);
+
+                log_str += "压缩图片成功...\n";
+                log.info("压缩图片成功...");
             } catch (Exception e) {
                 e.printStackTrace();
-                log += "视频转图片出现位置错误...\n";
-                log += e.getMessage();
+                log_str += "视频转图片出现位置错误...\n" + e.getMessage() + "\n";
+                log.error("视频转图片出现位置错误...", e);
             }
-            updateStatusToEnd(id, log);
-            System.out.println("视频转图片子线程结束...");
+            updateStatusToEnd(id, log_str);
+            log.info("视频转图片子线程结束...");
         }).start();
 
         return true;
     }
+
+    @Override
+    public ResponseEntity<Resource> zipImages(Long id) {
+        Video2image video2image = this.getById(id);
+        if (ObjectUtil.isNull(video2image)) {
+            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
+        }
+
+        String sourceFolderPath = video2image.getOutPath();
+        String zipFilePath = Paths.get(sourceFolderPath).resolveSibling(video2image.getName() + ".zip").toString();
+
+        File file = new File(zipFilePath);
+
+        if (!file.exists() || !file.isFile()) {
+            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
+        }
+
+        org.springframework.core.io.Resource resource = new FileSystemResource(file);
+        return ResponseEntity.ok()
+            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
+            .header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
+            .body(resource);
+    }
 }

+ 53 - 0
taais-modules/taais-biz/src/main/java/com/taais/biz/utils/ZipUtils.java

@@ -0,0 +1,53 @@
+package com.taais.biz.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ZipUtils {
+
+    /**
+     * 压缩指定文件夹中的所有文件
+     *
+     * @param sourceFolderPath 源文件夹路径
+     * @param zipFilePath      生成的ZIP文件路径
+     * @throws IOException 如果发生I/O错误
+     */
+    public static void zipFolderFiles(String sourceFolderPath, String zipFilePath) throws IOException {
+        File sourceFolder = new File(sourceFolderPath);
+        if (!sourceFolder.exists() || !sourceFolder.isDirectory()) {
+            throw new IllegalArgumentException(
+                    "Source folder does not exist or is not a directory: " + sourceFolderPath);
+        }
+
+        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
+                ZipOutputStream zos = new ZipOutputStream(fos)) {
+
+            File[] files = sourceFolder.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    if (file.isFile()) {
+                        zipFile(file, file.getName(), zos);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void zipFile(File file, String fileName, ZipOutputStream zos) throws IOException {
+        try (FileInputStream fis = new FileInputStream(file)) {
+            ZipEntry zipEntry = new ZipEntry(fileName);
+            zos.putNextEntry(zipEntry);
+
+            byte[] buffer = new byte[1024];
+            int len;
+            while ((len = fis.read(buffer)) > 0) {
+                zos.write(buffer, 0, len);
+            }
+            zos.closeEntry();
+        }
+    }
+}