javacv 切割视频

背景

  • 要做一个预览视频的功能,把整个视频截取一段出来。没有直接使用FFmpeg,而是使用了javacpp的库。

代码

  • 依赖的jar包
 <properties>
        <javacv>1.4.3</javacv>
        <ffmpeg-platform>4.0.2-1.4.3</ffmpeg-platform>
        <hutool.version>5.8.5</hutool.version>
 </properties>
  <dependencies>
 <dependency>
     <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
   
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
         
        </dependency>
   </dependencies>
  • 代码实现
   
 
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrSplitter;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.bytedeco.javacpp.avcodec;

/**
 * @author Zhou Zhongqing
 * @ClassName PreviewVideoUtils
 * @description: 预览视频
 * @date 2023-03-03 14:58
 */
public class PreviewVideoUtils {


    /**
     * 生成预览视频
     *
     * @param sourcePath
     * @param targetPath
     */
    public static void generatePreviewVideo(String sourcePath, String targetPath) {
        try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(sourcePath);
             FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(targetPath, grabber.getImageWidth(), grabber.getImageHeight(), 2)) {
            grabber.start();
            // 重新设置 宽高
            recorder.setImageWidth(grabber.getImageWidth());
            recorder.setImageHeight(grabber.getImageHeight());

            // 解决生成的视频无法播放的问题
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(grabber.getFrameRate());
            recorder.setSampleRate(grabber.getSampleRate());
            recorder.setAudioChannels(grabber.getAudioChannels());
            recorder.setFrameRate(grabber.getFrameRate());

            grabber.setTimestamp(20 * 1000000);

            Map<String, Object> filter = MapUtil.filter(BeanUtil.beanToMap(grabber));

            BeanUtil.copyProperties(filter, recorder);

            recorder.start();

            Frame inFrame;
            int count = 0;
            while ((inFrame = grabber.grab()) != null) {
                // System.out.println(inFrame.timestamp);
//                if (inFrame.timestamp >= 50 * 1000 * 1000) {
//                    break;
//                }
                if (count > 1000) {
                    break;
                }
                count++;
                recorder.record(inFrame);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }


    public static void main(String[] args) {
        String inFile = "C:\\Users\\Windows3\\Videos\\test\\trailer.mp4";   //读取的视频
        String outFile = "C:\\Users\\Windows3\\Videos\\test\\2.mp4";  //将要生成的剪切视频
        generatePreviewVideo(inFile, outFile);
//        test();
    }
}

效果

在这里插入图片描述

  • 原视频大约50几秒,转成了只有10几秒的预览视频
    在这里插入图片描述

在这里插入图片描述

遇到的问题

  • No video output stream (Is imageWidth > 0 && imageHeight > 0 and has start() been called?)

增加int imageWidth, int imageHeight,参数
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(“C:\Users\Windows3\Videos\2.mp4”, 1280, 720, 2)

参考

  • https://segmentfault.com/a/1190000039782685?sort=newest
  • https://www.cnblogs.com/wuxun1997/p/12936311.html
  • https://my.oschina.net/110NotFound/blog/5336500
  • https://juejin.cn/post/6988733165258932261

posted on 2023-03-05 14:41  愤怒的苹果ext  阅读(227)  评论(0编辑  收藏  举报  来源

导航