浏览代码

视频指定时间抽帧

xueyiming 1 月之前
父节点
当前提交
59c01f7c35

+ 26 - 0
tencent-ad-server/src/main/java/com/tzld/piaoquan/tencentad/controller/FfmpegUtilController.java

@@ -0,0 +1,26 @@
+package com.tzld.piaoquan.tencentad.controller;
+
+import com.tzld.piaoquan.tencentad.common.base.CommonResponse;
+import com.tzld.piaoquan.tencentad.model.po.FetchKeyFramesParam;
+import com.tzld.piaoquan.tencentad.model.vo.AdVideoVo;
+import com.tzld.piaoquan.tencentad.service.FfmpegUtilService;
+import com.tzld.piaoquan.tencentad.utils.page.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/ffmpeg")
+public class FfmpegUtilController {
+
+    @Autowired
+    private FfmpegUtilService ffmpegUtilService;
+
+    @PostMapping("/fetchKeyFrames")
+    public CommonResponse<String> fetchKeyFrames(@RequestBody FetchKeyFramesParam fetchKeyFramesParam) {
+        return ffmpegUtilService.fetchKeyFrames(fetchKeyFramesParam);
+    }
+
+}

+ 14 - 0
tencent-ad-server/src/main/java/com/tzld/piaoquan/tencentad/model/po/FetchKeyFramesParam.java

@@ -0,0 +1,14 @@
+package com.tzld.piaoquan.tencentad.model.po;
+
+import lombok.Data;
+import lombok.ToString;
+
+@Data
+@ToString
+public class FetchKeyFramesParam {
+
+    private String url;
+
+    private String timestamp;
+
+}

+ 8 - 0
tencent-ad-server/src/main/java/com/tzld/piaoquan/tencentad/service/FfmpegUtilService.java

@@ -0,0 +1,8 @@
+package com.tzld.piaoquan.tencentad.service;
+
+import com.tzld.piaoquan.tencentad.common.base.CommonResponse;
+import com.tzld.piaoquan.tencentad.model.po.FetchKeyFramesParam;
+
+public interface FfmpegUtilService {
+    CommonResponse<String> fetchKeyFrames(FetchKeyFramesParam fetchKeyFramesParam);
+}

+ 65 - 0
tencent-ad-server/src/main/java/com/tzld/piaoquan/tencentad/service/impl/FfmpegUtilServiceImpl.java

@@ -0,0 +1,65 @@
+package com.tzld.piaoquan.tencentad.service.impl;
+
+import com.tzld.piaoquan.tencentad.common.base.CommonResponse;
+import com.tzld.piaoquan.tencentad.common.enums.AdVideoStatusEnum;
+import com.tzld.piaoquan.tencentad.model.po.AdVideo;
+import com.tzld.piaoquan.tencentad.model.po.FetchKeyFramesParam;
+import com.tzld.piaoquan.tencentad.service.FfmpegUtilService;
+import com.tzld.piaoquan.tencentad.utils.FfmpegUtil;
+import com.tzld.piaoquan.tencentad.utils.OSSUploader;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.UUID;
+
+@Slf4j
+@Service
+public class FfmpegUtilServiceImpl implements FfmpegUtilService {
+
+    @Value("${image_path}")
+    private String imagePath;
+
+    @Override
+    public CommonResponse<String> fetchKeyFrames(FetchKeyFramesParam fetchKeyFramesParam) {
+        if (fetchKeyFramesParam == null || StringUtils.isEmpty(fetchKeyFramesParam.getUrl())
+                || StringUtils.isEmpty(fetchKeyFramesParam.getTimestamp())) {
+            return CommonResponse.create(500, "参数错误");
+        }
+        String imageFolder = imagePath + "/" + "timeTarget";
+        File dir = new File(imageFolder);
+        if (!dir.exists()) {
+            boolean mkdir = dir.mkdir();
+            if (!mkdir) {
+                return CommonResponse.create(500, "服务异常,请重试");
+
+            }
+        }
+        String imagePath = imageFolder + "/" + UUID.randomUUID() + ".jpg";
+        String target = "long_articles/image";
+
+        FfmpegUtil.getTargetTimeThumbnail(fetchKeyFramesParam.getUrl(), imagePath, fetchKeyFramesParam.getTimestamp());
+        String imageUrl = OSSUploader.uploadToOSS(target, imagePath);
+        Path pathToDelete = Paths.get(imagePath);
+        try {
+            // 使用 Files.walkFileTree 删除文件夹及其内容
+            Files.walkFileTree(pathToDelete, new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                    Files.delete(file); // 删除文件
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        } catch (IOException e) {
+            log.error("del imageFolder error {}", e.getMessage());
+        }
+        return CommonResponse.create(imageUrl);
+    }
+
+
+}

+ 31 - 0
tencent-ad-server/src/main/java/com/tzld/piaoquan/tencentad/utils/FfmpegUtil.java

@@ -45,6 +45,37 @@ public class FfmpegUtil {
         return true;
     }
 
+    public static void main(String[] args) {
+        String url = "https://rescdn.yishihui.com/long_articles/video/8b4b2e6a-e556-4d06-8b4e-65a25654ebce";
+        String targetPath = "/Users/shimeng/Desktop/img" + "/" + "%04d.jpg";
+        String timestamp = "00:01:30.500";
+        System.out.println(getTargetTimeThumbnail(url, targetPath, timestamp));
+    }
+
+
+    public static boolean getTargetTimeThumbnail(String url, String targetPath, String timestamp) {
+        try {
+            try (ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor()) {
+                ffmpeg.addArgument("-ss");
+                ffmpeg.addArgument(timestamp);
+                ffmpeg.addArgument("-i");
+                ffmpeg.addArgument(url);
+                ffmpeg.addArgument("-vframes");
+                ffmpeg.addArgument("1");
+                ffmpeg.addArgument(targetPath);
+                ffmpeg.execute();
+                try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
+                    blockFfmpeg(br);
+                }
+            }
+        } catch (IOException e) {
+            System.out.println(e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+
     /**
      * 等待命令执行成功,退出
      *

+ 21 - 1
tencent-ad-server/src/main/java/com/tzld/piaoquan/tencentad/utils/OSSUploader.java

@@ -25,7 +25,27 @@ public class OSSUploader {
             PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, ossVideoKey, new File(localVideoPath));
             // 上传文件
             ossClient.putObject(putObjectRequest);
-            return "http://rescdn.yishihui.com/" + ossVideoKey;
+            return "https://rescdn.yishihui.com/" + ossVideoKey;
+        } catch (Exception e) {
+            return null;
+        } finally {
+            // 关闭 OSSClient
+            ossClient.shutdown();
+        }
+    }
+
+    public static String uploadToOSS(String target, String localVideoPath) {
+        String ossVideoKey = String.format("%s/%s", target, UUID.randomUUID());
+
+        // 创建 OSSClient 实例
+        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
+
+        try {
+            // 创建上传请求
+            PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, ossVideoKey, new File(localVideoPath));
+            // 上传文件
+            ossClient.putObject(putObjectRequest);
+            return ossVideoKey;
         } catch (Exception e) {
             return null;
         } finally {