Java处理视频文件,生成打标视频

import org.apache.commons.lang3.StringUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author Mr.superbeyone
 * @project 
 * @className FfmpegUtil2
 * @description
 * @date 2023-10-20 15:15
 **/

public class FfmpegUtil2 {


    private static Logger logger = LoggerFactory.getLogger(FfmpegUtil2.class);


    /**
     * 生成标注后的视频文件
     *
     * @param srcVideoPath 源视频文件路径
     * @param frameRate    跳帧请求RPC的步数
     * @param extName      生成的文件扩展名 如: mp4  flv
     * @return 标注后的视频文件路径
     */
    public static String generateTagVideo(String srcVideoPath, int frameRate, String extName) {
        return generateTagVideo(srcVideoPath, null, frameRate, extName);
    }

    public static String generateTagVideo(String srcVideoPath, String targetVideoPath, int frameRate, String extName) {
        long start = System.currentTimeMillis();
        //视频文件路径
        File srcVideoFile = new File(srcVideoPath);
        if (!srcVideoFile.exists() || !srcVideoFile.isFile()) {
            logger.info("generateTagVideo srcVideoPath is not video file {}", srcVideoPath);
            return "";
        }
        if (StringUtils.isBlank(targetVideoPath)) {
            targetVideoPath = srcVideoFile.getParentFile() + File.separator + StringUtils.substringBeforeLast(srcVideoFile.getName(), ".") + "_tag." + extName;
        }
        String targetVideo = doGenerateTagVideo(srcVideoPath, targetVideoPath, frameRate, extName);
        logger.info("generateTagVideo 耗时 {}", (System.currentTimeMillis() - start));
        logger.info("generateTagVideo srcVideo {} targetVideo {}", srcVideoPath, targetVideo);
        return targetVideo;
    }

    public static String doGenerateTagVideo(String srcVideoPath, String targetVideoPath, int frameRate, String extName) {
        FFmpegFrameGrabber grabber = null;
        FFmpegFrameRecorder recorder = null;
        try {
            grabber = FFmpegFrameGrabber.createDefault(new File(srcVideoPath));
            grabber.setFormat(StringUtils.substringAfterLast(srcVideoPath, ".").toLowerCase());
            grabber.start();

            int imageHeight = grabber.getImageHeight();
            int imageWidth = grabber.getImageWidth();
            recorder = FFmpegFrameRecorder.createDefault(new File(targetVideoPath), imageWidth, imageHeight);

            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
            recorder.setFormat(extName);

            recorder.setVideoBitrate(10000);//数值越大,存储空间越大
            recorder.setVideoOption("preset", "ultrafast");//究极快
            recorder.start();

            Java2DFrameConverter converter = new Java2DFrameConverter();

            int index = 0, x = 0, y = 0, width = 0, height = 0;
            Frame frame;
            while ((frame = grabber.grabImage()) != null) {
                if (null == frame.image) {
                    continue;
                }
                index++;
                
                BufferedImage image = converter.getBufferedImage(frame);
                if (frameRate > 0 && index % frameRate == 0) {
                    Map<String, Integer> location = rpcFindLocation(image);
                    x = location.get("x");
                    y = location.get("y");
                    width = location.get("w");
                    height = location.get("h");
                }
                
                Graphics graphics = image.getGraphics();
                graphics.setColor(Color.RED);
                graphics.drawRect(x, y, width, height);
                Frame drawFrame = converter.convert(image);
                recorder.record(drawFrame);
            }
            recorder.close();
            grabber.close();
        } catch (Exception e) {
            logger.error("doGenerateTagVideo exception ", e);
        } finally {
            if (grabber != null) {
                try {
                    grabber.close();
                } catch (Exception ex) {
                    logger.error("close grabber error", ex);
                }
            }
            if (recorder != null) {
                try {
                    recorder.close();
                } catch (Exception ex) {
                    logger.error("close recorder error", ex);
                }
            }
        }

        return targetVideoPath;
    }

    /**
     * 对图片文件RPC调用
     *
     * @param image 图片文件
     * @return x, y, w, h
     */
    private static Map<String, Integer> rpcFindLocation(BufferedImage image) {
        Map<String, Integer> location = new HashMap<>(8);
        Random random = new Random();
        location.put("x", 800 + random.nextInt(100));
        location.put("y", 750 + random.nextInt(50));
        location.put("w", 50 + random.nextInt(10));
        location.put("h", 50 + random.nextInt(10));
        return location;
    }


    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String srcPath = "D:\\WorkSpace\\video\\src\\b.mp4";
        String destPath = "D:\\WorkSpace\\video\\src\\test\\" + System.currentTimeMillis() + ".flv";
        generateTagVideo(srcPath, destPath, 10, "flv");
        System.out.println(destPath + "耗时\t" + (System.currentTimeMillis() - start) + "毫秒");
    }
}

参考

你可能感兴趣的:(工具类,java,音视频,开发语言)