package shop.alien.util.common;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import shop.alien.util.system.OSUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 命令行调用FFMpeg截取图片
 *
 * @author ssk
 * @version 1.0
 * @date 2024/12/24 10:13
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class VideoUtils {

    /**
     * 视频截取图片
     *
     * @param videoFilePath 视频媒体文件
     */
    public String getImg(String videoFilePath) {
        log.info("VideoUtils.getImg videoFilePath={}", videoFilePath);
        String[] file = videoFilePath.split("\\.");
        log.info("VideoUtils.getImg file={}", (Object) file);
        // 截图保存位置
        String imgFilePath = file[0] + ".jpg";
        log.info("VideoUtils.getImg imgFilePath={}", imgFilePath);
        ProcessBuilder processBuilder = new ProcessBuilder();
        // 重定向错误流,防阻塞
        processBuilder.redirectErrorStream(true);

        // 如果为本地测试，ffmpegPath地址需求修改为本地安装程序的地址（环境变量不好用）
        String ffmpegPath = "ffmpeg";
        if ("windows".equals(OSUtil.getOsName())) {
            // ffmpegPath = "C:/Program Files (x86)/ffmpeg-6.0/bin/ffmpeg.exe";
            ffmpegPath = "C:/project/ext/ffmpeg-6.0/bin/ffmpeg.exe";
        }

        // 调用ffmpeg 执行截取命令,需要服务器中安装了ffmpeg并配置了环境变量
//        processBuilder.command(ffmpegPath, "-i", videoFilePath, "-ss", "00:00:00", "-vframes", "1", imgFilePath);
        // 核心修改1：调整-ss位置到-i前面，补充-y（覆盖文件）和-f image2（格式兼容）
        processBuilder.command(
                ffmpegPath,
                "-ss", "00:00:00",    // 先定位到0秒（第一帧），再读视频，提升精准度
                "-i", videoFilePath,  // 输入视频文件
                "-vframes", "1",      // 只截取1帧
                "-f", "image2",       // 显式指定图片格式，兼容更多视频类型
                "-y",                 // 覆盖已存在的图片文件，避免进程阻塞
                imgFilePath           // 输出图片路径
        );
        try {
            Process process = processBuilder.start();
            // 获取流信息
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            System.out.println(process.waitFor());
            if (0 == process.waitFor()) {
                return imgFilePath;
            }
            return "";
        } catch (IOException | InterruptedException e) {
            log.error("VideoUtils.generateCover ERROR Msg={}", e.getMessage());
            return "";
        }
    }

    /**
     * 视频截取第一帧作为封面
     *
     * @param videoFilePath 视频媒体文件路径
     * @return 封面图片文件路径
     */
    public String getFirstFrame(String videoFilePath) {
        log.info("VideoUtils.getFirstFrame videoFilePath={}", videoFilePath);
        // 验证参数
        if (videoFilePath == null || videoFilePath.isEmpty()) {
            log.error("VideoUtils.getFirstFrame ERROR: videoFilePath is null or empty");
            return "";
        }
        
        String[] file = videoFilePath.split("\\.");
        log.info("VideoUtils.getFirstFrame file={}", (Object) file);
        // 截图保存位置
        String imgFilePath = file[0] + ".jpg";
        log.info("VideoUtils.getFirstFrame imgFilePath={}", imgFilePath);
        
        ProcessBuilder processBuilder = new ProcessBuilder();
        // 重定向错误流,防阻塞
        processBuilder.redirectErrorStream(true);

        // 如果为本地测试，ffmpegPath地址需求修改为本地安装程序的地址（环境变量不好用）
        String ffmpegPath = "ffmpeg";
        if ("windows".equals(OSUtil.getOsName())) {
            // ffmpegPath = "C:/Program Files (x86)/ffmpeg-6.0/bin/ffmpeg.exe";
            ffmpegPath = "C:/project/ext/ffmpeg-6.0/bin/ffmpeg.exe";
        }

        // 调用ffmpeg 执行截取命令,截取第一帧（00:00:00）,需要服务器中安装了ffmpeg并配置了环境变量
        processBuilder.command(ffmpegPath, "-i", videoFilePath, "-ss", "00:00:00", "-vframes", "1", imgFilePath);
        try {
            Process process = processBuilder.start();
            // 获取流信息
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                log.debug("VideoUtils.getFirstFrame ffmpeg output: {}", line);
            }
            int exitCode = process.waitFor();
            log.info("VideoUtils.getFirstFrame ffmpeg exit code: {}", exitCode);
            if (0 == exitCode) {
                return imgFilePath;
            }
            log.error("VideoUtils.getFirstFrame ERROR: ffmpeg exit code is not 0");
            return "";
        } catch (IOException | InterruptedException e) {
            log.error("VideoUtils.getFirstFrame ERROR Msg={}", e.getMessage(), e);
            return "";
        }
    }

    /**
     * FFMpeg视频截取图片
     *
     * @param videoFilePath 视频媒体文件
     */
    public String getVideoTime(String videoFilePath) {
        log.info("CommandUtil.getVideoTime videoFilePath={}", videoFilePath);
        // 截图保存位置
        ProcessBuilder processBuilder = new ProcessBuilder();
        // 重定向错误流,防阻塞
        processBuilder.redirectErrorStream(true);
        // 调用ffmpeg 执行截取命令,需要服务器中安装了ffmpeg并配置了环境变量
        //ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 2497682.mp4
        processBuilder.command("ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", videoFilePath);
        try {
            Process process = processBuilder.start();
            // 获取流信息
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            System.out.println(process.waitFor());
            if (0 == process.waitFor()) {
                return line;
            }
            return "";
        } catch (IOException | InterruptedException e) {
            log.error("CommandUtil.captureImage ERROR Msg={}", e.getMessage());
            return "";
        }
    }
}
