peng
3 天以前 dee9f245cd463669dbf707e05a2872d4466cbf9b
framework/src/main/java/cn/lili/utils/COSUtil.java
@@ -18,6 +18,11 @@
import com.tencent.cloud.cos.util.Jackson;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
//import org.bytedeco.javacv.*;
//import org.bytedeco.opencv.global.opencv_imgproc;
//import org.bytedeco.opencv.opencv_core.Mat;
//import org.bytedeco.opencv.opencv_core.Size;
//import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@@ -37,6 +42,100 @@
public class COSUtil {
    private final COSConfigProperty cosConfigProperty;
    /**
     * 从网络视频URL截取第一秒画面,返回MultipartFile类型
     * @param videoUrl 网络视频地址
     * @param width 封面宽度
     * @param height 封面高度
     * @return 封面图片的MultipartFile对象
     * @throws Exception 处理异常
     */
    public MultipartFile captureVideoCoverAsMultipart(String videoUrl, Integer width, Integer height) throws Exception {
//        // 设置默认宽高
//        int targetWidth = width != null && width > 0 ? width : 800;
//        int targetHeight = height != null && height > 0 ? height : 600;
//
//        // 生成唯一文件名(用于MultipartFile的原始文件名)
//        String fileName = UUID.randomUUID().toString() + ".jpg";
//
//        // 使用内存流处理图片,避免临时文件
//        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//        FFmpegFrameGrabber grabber = null;
//
//        try {
//            // 初始化视频抓取器
//            grabber = new FFmpegFrameGrabber(videoUrl);
//            grabber.start();
//
//            // 定位到第一秒
//            grabber.setTimestamp(1000000); // 1秒 = 1,000,000微秒
//
//            // 获取视频帧
//            Frame frame = grabber.grabImage();
//            if (frame == null) {
//                throw new RuntimeException("无法获取视频帧,可能视频格式不支持或URL无效");
//            }
//
//            // 转换为Mat并调整尺寸
//            OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
//            Mat mat = converter.convert(frame);
//            Mat resizedMat = new Mat();
//            opencv_imgproc.resize(mat, resizedMat, new Size(targetWidth, targetHeight));
//
//            // 将处理后的帧写入内存流
//            Java2DFrameConverter java2dConverter = new Java2DFrameConverter();
//            ImageIO.write(
//                    java2dConverter.getBufferedImage(converter.convert(resizedMat)),
//                    "jpg",
//                    outputStream
//            );
//
//            // 将内存流转换为MultipartFile
//            ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
//            return new MockMultipartFile(
//                    "file",          // 表单字段名(可自定义)
//                    fileName,        // 原始文件名
//                    "image/jpeg",    // 文件类型
//                    inputStream      // 文件流
//            );
//        } finally {
//            // 释放资源
//            if (grabber != null) {
//                try {
//                    grabber.stop();
//                    grabber.release();
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//            outputStream.close();
//        }
        return null;
    }
    /**
     * 从完整URL中提取COS文件key
     * @param fullUrl 完整URL
     * @return COS文件key
     */
    public String extractFileKeyFromUrl(String fullUrl) {
        // 去除协议和域名部分
        String endpoint = cosConfigProperty.getEndpoint();
        if (fullUrl.startsWith(endpoint)) {
            return fullUrl.substring(endpoint.length() + 1);
        }
        // 如果URL包含bucket名称
        String bucketUrl = "https://" + cosConfigProperty.getBucket() + "." + endpoint;
        if (fullUrl.startsWith(bucketUrl)) {
            return fullUrl.substring(bucketUrl.length() + 1);
        }
        // 如果已经是相对路径,直接返回
        return fullUrl;
    }
    /**
     * 获取sts临时访问凭证
@@ -114,6 +213,7 @@
            cosSTS.setStsEndTime(cosSTS.getStsStartTime() + cosConfigProperty.getDurationSeconds() - 30);
            cosSTS.setBucket(cosConfigProperty.getBucket());
            cosSTS.setRegion(cosConfigProperty.getRegion());
            cosSTS.setEndpoint(cosConfigProperty.getEndpoint());
            return cosSTS;
        } catch (Exception e) {
            e.printStackTrace();
@@ -224,21 +324,7 @@
     * @return
     */
    public String getPreviewUrl(String fileKey) {
        COSClient cosClient = this.initClient();
        // 设置签名过期时间(可选), 若未进行设置则默认使用 ClientConfig 中的签名过期时间(1小时)
        // 这里设置签名在半个小时后过期
        Date expirationDate = new Date(System.currentTimeMillis() + cosConfigProperty.getUrlExpireMinute() * 60 * 1000);
        // 填写本次请求的参数,需与实际请求相同,能够防止用户篡改此签名的 HTTP 请求的参数
        Map<String, String> params = new HashMap<String, String>();
        // 填写本次请求的头部,需与实际请求相同,能够防止用户篡改此签名的 HTTP 请求的头部
        Map<String, String> headers = new HashMap<String, String>();
        // 请求的 HTTP 方法,上传请求用 PUT,下载请求用 GET,删除请求用 DELETE
        HttpMethodName method = HttpMethodName.GET;
        URL url = cosClient.generatePresignedUrl(cosConfigProperty.getBucket(), fileKey, expirationDate, method, headers, params);
        System.out.println(url.toString());
        // 确认本进程不再使用 cosClient 实例之后,关闭即可
        cosClient.shutdown();
        return url.toString();
        return cosConfigProperty.getEndpoint() + "/" + fileKey;
    }