package com.dji.sample.common.util;


import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.service.impl.OssServiceContext;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * @author hqjiang
 * @version 1.0
 * @date 2024/7/10
 */

@Slf4j
@Component
public class ThumbnailatorUtil {

    private static final String MP4 = ".MP4";

//    public static BufferedImage getThumbnail(String objectKey, int width, int height) {
//        try {
//            OssServiceContext ossService = SpringBeanUtilsTest.getBean(OssServiceContext.class);
//            InputStream inputStream = ossService.getObject(OssConfiguration.bucket, objectKey);
//            if(!objectKey.endsWith(MP4)) {
//                return Thumbnails.of(inputStream)
//                        .size(width, height)
//                        .outputQuality(0.75f)
//                        .outputFormat("JPEG")
//                        .asBufferedImage();
//            } else {
//                return getVedioImg(inputStream,objectKey,width,height);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }

    public static BufferedImage getThumbnail(String objectKey, URL url,int width, int height) {
        try {
            if(!objectKey.endsWith(MP4)) {
                return Thumbnails.of(url)
                        .size(width, height)
                        .outputQuality(0.75f)
                        .outputFormat("JPEG")
                        .asBufferedImage();
            } else {
                return getVedioImg(url,width,height);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取视频图片
     *
     * @throws
     * @Title: gainVedioImg
     * @param: filePath  文件夹路径
     * @return: void
     */
    public static BufferedImage getVedioImg(URL url, int width, int height) {
        try {
        BufferedImage bImage =  getImage(url, 20);
        return Thumbnails.of(bImage)
                .size(width, height)
                .outputQuality(0.75f)
                .outputFormat("JPEG")
                .asBufferedImage();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        getImage(null,10);
    }


    private static BufferedImage getImage(URL url, int second) {
        try {
            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(url);
            grabber.start();
            int ftp = grabber.getLengthInFrames();
            int flag = 0;
            Frame frame = null;
            while (flag <= ftp) {
                //获取帧
                frame = grabber.grabImage();
                //过滤前 second 帧，避免出现全黑图片
                if ((flag > second) && (frame != null)) {
                    break;
                }
                flag++;
            }
            String rotate = grabber.getVideoMetadata("rotate");
            //创建BufferedImage对象
            Java2DFrameConverter converter = new Java2DFrameConverter();
            BufferedImage bufferedImage = converter.getBufferedImage(frame);
            if (rotate != null) {
                //旋转图片
                bufferedImage = rotate(bufferedImage, Integer.parseInt(rotate));
            }

            grabber.close();
            grabber.stop();
            grabber.release();

            log.debug("截取视频截图结束：" + System.currentTimeMillis());

            // 保存图片
//            String outputFolderPath = "D:\\temp\\img"; // 替换为您的输出文件夹路径
//            File outputFolder = new File(outputFolderPath);
//            outputFolder.mkdirs();
//            String outputFilePath = outputFolderPath + File.separator + "frame_" + second + ".jpg";
//            File outputFile = new File(outputFilePath);
//            ImageIO.write(bufferedImage, "jpg", outputFile);

            return bufferedImage;
        } catch (Exception e) {
            log.error("获取视频图片失败！", e);
        }
        return null;
    }

    /**
     * 旋转 根据视频旋转度来调整图片
     * @param src
     * @param angel
     * @return
     */
    private static BufferedImage rotate(BufferedImage src, int angel) {
        int src_width = src.getWidth(null);
        int src_height = src.getHeight(null);
        int type = src.getColorModel().getTransparency();
        Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
        BufferedImage bufferedImage = new BufferedImage(rect_des.width, rect_des.height, type);
        Graphics2D graphics2D = bufferedImage.createGraphics();
        graphics2D.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
        graphics2D.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
        graphics2D.drawImage(src, 0, 0, null);
        graphics2D.dispose();
        return bufferedImage;
    }

    /**
     * 计算图片旋转大小
     * @param src
     * @param angel
     * @return
     */
    private static Rectangle calcRotatedSize(Rectangle src, int angel) {
        if (angel >= 90) {
            if (angel / 90 % 2 == 1) {
                int temp = src.height;
                src.height = src.width;
                src.width = temp;
            }
            angel = angel % 90;
        }
        double totalSqrt = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
        double totalLen = 2 * Math.sin(Math.toRadians(angel) / 2) * totalSqrt;
        double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
        double angel_dalta_width = Math.atan((double) src.height / src.width);
        double angel_dalta_height = Math.atan((double) src.width / src.height);
        int len_width = (int) (totalLen * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
        int len_height = (int) (totalLen * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
        int des_width = src.width + len_width * 2;
        int des_height = src.height + len_height * 2;
        return new Rectangle(new Dimension(des_width, des_height));
    }
}
