javaCV学习-1-环境搭建及测试多张图片合成一个mp4的视频

最近在自学用java语言如何进行处理音视频。

学习时,在网上找了一段代码,测试多张图片合成一个mp4的视频。

代码是:

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FrameRecorder;
import org.bytedeco.javacv.Java2DFrameConverter;

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

/**
 * Description:
 *
 * @author 诸葛小猿
 * @date 2020-10-24
 */
public class Test {

    public static void main(String[] args) throws Exception {
        //合成的MP4
        String mp4SavePath = "C:\\Users\\WuXiaoLong\\Desktop\\img\\img.mp4";
        //图片地址 这里面放了22张图片
        String img = "C:\\Users\\WuXiaoLong\\Desktop\\img";
        int width = 1600;
        int height = 900;
        //读取所有图片
        File file = new File(img);
        File[] files = file.listFiles();
        Map<Integer, File> imgMap = new HashMap<Integer, File>();
        int num = 0;
        for (File imgFile : files) {
            imgMap.put(num, imgFile);
            num++;
        }
        createMp4(mp4SavePath, imgMap, width, height);
    }

    private static void createMp4(String mp4SavePath, Map<Integer, File> imgMap, int width, int height) throws FrameRecorder.Exception {
        //视频宽高最好是按照常见的视频的宽高  16:9  或者 9:16
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(mp4SavePath, width, height);
        //设置视频编码层模式
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //设置视频为25帧每秒
        recorder.setFrameRate(25);
        //设置视频图像数据格式
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        recorder.setFormat("mp4");
        try {
            recorder.start();
            Java2DFrameConverter converter = new Java2DFrameConverter();
            //录制一个22秒的视频
            for (int i = 0; i < 22; i++) {
                BufferedImage read = ImageIO.read(imgMap.get(i));
                //一秒是25帧 所以要记录25次
                for (int j = 0; j < 25; j++) {
                    recorder.record(converter.getFrame(read));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //最后一定要结束并释放资源
            recorder.stop();
            recorder.release();
        }
    }

}

按照博客的介绍,各种骚操作,始终是跑不通。连续看了几篇博客,都是给一段代码,给一个jar包,一测试都是各种翻车。

学习javaVC的都知道,javaVC相关的资料在网上很少,很多写博客的也都不是专业做计算机视觉处理的,写的博客要么很简单,要么copy一段代码,参考性都不大。

这让我想起了一句话:最好的学习地址是官方的git仓库,没有之一。

那就扒出来官方git看看吧:https://github.com/bytedeco/javacv

按照官方的指导,引入maven依赖就可以了。

  <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.4</version>
  </dependency>

实际测试时,很打脸:

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.ffmpeg.global.avutil
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at org.bytedeco.javacpp.Loader.load(Loader.java:1190)
	at org.bytedeco.javacpp.Loader.load(Loader.java:1123)
	at org.bytedeco.ffmpeg.avformat.Write_packet_Pointer_BytePointer_int.<clinit>(Write_packet_Pointer_BytePointer_int.java:21)
	at org.bytedeco.javacv.FFmpegFrameRecorder.<clinit>(FFmpegFrameRecorder.java:329)
	at com.wuxl.Image2Mp4.createMp4(Image2Mp4.java:48)
	at com.wuxl.Image2Mp4.main(Image2Mp4.java:43)

关键是我打开这个ffmpeg.jar看,是org.bytedeco.ffmpeg.global.avutil是存在的。头大。

我猜测是因为:这个jar包太大,下载不全,于是删除了本地maven仓库中的org.bytedeco的jar文件,准备重新下载一次。

bytedeco仓库

下载时打开这个目录一直盯着,好家伙,这么多依赖的jar包。同时关注IDEA的下载速度。

image-20201024151036734

大概半个小时后,下载停止了。代码也没有了报错提示。于是有急忙再运行一下,结果还是’Could not initialize class org.bytedeco.ffmpeg.global.avutil’。what the F。。。。。

卡住了,进行不下去了,怎么办,官方指导也不顶用吗???算了,这么难搞,不搞了。默默的点了一根烟。

不搞出来,感觉难受,这就放弃了不符合程序员该有的探索精神。。。一根烟抽完,继续。

虽然还是报错,我依然坚信还是javaCV的环境哪里有问题。于是又到github上去找答案。

image-20201024152322682

看到github上有编译好的zip,决定使用zip包中的jar直接导入到项目中,不再使用maven坐标引入。

image-20201024152354773

于是下载了这个755M的zip包,然后解压,删除原有的maven坐标,手动导入zip包中的所有jar包:

image-20201024152806324

看到上面的6,即表示导入完成。

让后再一次运行,结果。。。。哈哈哈哈哈哈哈,成功了。欧耶!!!!

给大家看一下图片合成的mp4的结果,视频有颜色不太好,有时再做相关的调优吧。

javaCV将图片合成视频

上面是导入了zip包中的所有jar包,其实并不需要所有的,可以根据具体的开发平台(windows/linux/mac)及操作系统的位数(32/64)选择部分包导入即可。

最后,看到网上有篇博客,感觉说的很对,分享一下部分内容:

网上很多关于javacv的搭建环境的教程,然后都是大同小异先教你搭建opencv的环境,然后给你一个实例让你测试自己的opencv环境是否成功搭建。说到这里我就想骂人了,那些教需要在电脑上搭建opencv环境的,你不知道javacv0.8版本之后就不用再搭建opencv的环境了吗?麻烦你知道了就快点把博客内容改改吧,不要再耽误我们这些java开发人员的时间了好吗?我看了你们的教程可是关搭建opencv的环境就浪费了两天时间…

有问题可以关注公众号交流。

完成,收工!

传播知识,共享价值】,感谢小伙伴们的关注和支持,我是【诸葛小猿】,一个彷徨中奋斗的互联网民工。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
好的,我可以帮你写这个JavaCV代码,可以基于FFmpeg合成两个视频。以下是JavaCV的示例代码: ``` import org.bytedeco.ffmpeg.global.avcodec; import org.bytedeco.ffmpeg.global.avformat; import org.bytedeco.ffmpeg.global.avutil; import org.bytedeco.javacpp.*; import org.bytedeco.javacv.*; public class VideoMergeExample { public static void main(String[] args) { // 定义第一个视频文件 String video1Path = "/path/to/video1.mp4"; OpenCVFrameGrabber grabber1 = new OpenCVFrameGrabber(video1Path); try { grabber1.start(); } catch (FrameGrabber.Exception e) { e.printStackTrace(); } // 定义第二个视频文件 String video2Path = "/path/to/video2.mp4"; OpenCVFrameGrabber grabber2 = new OpenCVFrameGrabber(video2Path); try { grabber2.start(); } catch (FrameGrabber.Exception e) { e.printStackTrace(); } // 定义输出视频文件 FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("/path/to/output.mp4", grabber1.getImageWidth(), grabber1.getImageHeight(), grabber1.getAudioChannels()); recorder.setFormat("mp4"); recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); recorder.setFrameRate(grabber1.getFrameRate()); recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // 必须设置像素格式 try { recorder.start(); } catch (FrameRecorder.Exception e) { e.printStackTrace(); } // 读取第一个视频并写入输出视频中 Frame frame1 = null; try { while ((frame1 = grabber1.grab()) != null) { recorder.record(frame1); } } catch (FrameGrabber.Exception e) { e.printStackTrace(); } catch (FrameRecorder.Exception e) { e.printStackTrace(); } // 读取第二个视频并写入输出视频中 Frame frame2 = null; try { while ((frame2 = grabber2.grab()) != null) { recorder.record(frame2); } } catch (FrameGrabber.Exception e) { e.printStackTrace(); } catch (FrameRecorder.Exception e) { e.printStackTrace(); } // 释放资源 try { recorder.stop(); grabber1.stop(); grabber2.stop(); } catch (FrameRecorder.Exception e) { e.printStackTrace(); } catch (FrameGrabber.Exception e) { e.printStackTrace(); } } } ``` 请注意替换视频路径和输出路径。如果有任何疑问,请随时与我联系。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值