package org.jeecg.modules.opencv.utils;

import cn.com.ctop.common.module.utils.LoadFileUtil;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacv.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

import static org.bytedeco.javacpp.opencv_imgcodecs.cvLoadImage;

/**
 * 视频截帧处理
 */
public class VideoProcessing {
    /**
     * 将视频文件帧处理并以“jpg”格式进行存储。
     * 依赖FrameToBufferedImage方法：将frame转换为bufferedImage对象
     * 视频帧拆分
     * @param videoFileName
     */
    public static String grabberVideoFramer(String videoFileName, String filePackageName) {
        //最后获取到的视频的图片的路径
        String videPicture = "";
        //Frame对象
        Frame frame = null;
        //标识
        int flag = 0;
        try {

            /*获取视频文件*/
            FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(videoFileName);
            fFmpegFrameGrabber.start();

            //获取视频总帧数
            int ftp = fFmpegFrameGrabber.getLengthInFrames();
            LoadFileUtil.checkFile(filePackageName);
            while (flag <= ftp) {
                frame = fFmpegFrameGrabber.grabImage();
                /*对视频的第五帧进行处理*/
                if (frame != null) {
                    //文件绝对路径+名字
                    String fileName = filePackageName + String.valueOf(flag) + ".jpg";
                    //文件储存对象
                    File outPut = new File(fileName);
                    ImageIO.write(FrameToBufferedImage(frame), "jpg", outPut);
                }
                flag++;
            }
            fFmpegFrameGrabber.stop();
            fFmpegFrameGrabber.close();
        } catch (Exception E) {
            E.printStackTrace();
        }
        return videPicture;
    }

    public static void videoMerge(String videoFileName, String imagePackage) throws FrameRecorder.Exception {
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFileName, 720, 1280);
        // 28
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
        recorder.setFrameRate(25);
        // yuv420p
        recorder.setPixelFormat(Avutils.AV_PIX_FMT_YUV422P);
        recorder.start();
        //
        OpenCVFrameConverter.ToIplImage conveter = new OpenCVFrameConverter.ToIplImage();
        // 列出目录中所有的图片，都是jpg的，以1.jpg,2.jpg的方式，方便操作
        File file = new File(imagePackage);
        File[] flist = file.listFiles();
        // 循环所有图片
        for (int i = 1; i <= flist.length; i++) {
            String fname = imagePackage + i + ".jpg";
            // 非常吃内存！！
            opencv_core.IplImage image = cvLoadImage(fname);
            recorder.record(conveter.convert(image));
            // 释放内存？ cvLoadImage(fname); // 非常吃内存！！
            opencv_core.cvReleaseImage(image);
        }
        recorder.stop();
        recorder.release();
    }

    public static BufferedImage FrameToBufferedImage(Frame frame) {
        //创建BufferedImage对象
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bufferedImage = converter.getBufferedImage(frame);
        return bufferedImage;
    }

    public static void main(String[] args) {
        try {
            videoMerge("D:\\data\\merge.mp4", "D:\\data\\video\\");
        } catch (FrameRecorder.Exception e) {
            e.printStackTrace();
        }
    }
}
