javacv截取视频预览图

原创
2018/07/14 20:49
阅读数 9.7K

关于处理视频,谈谈自己的经验。

找到相关的资料,两种最多最常用。一个是ffmpeg工具,安装好了引用即可。这种暂时没尝试,不知道怎么样。那另外一种就是javacv了,关于这个遇到了一些坑,所以有必要总结一下。javacv尝试了两个版本:

1、javacv0.8版本

       <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>0.8</version>
        </dependency>

先上代码

public String fetchFrame(String videofile, String framefile)
        throws Exception {
    long start = System.currentTimeMillis();
    File targetFile = new File(framefile);
    FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile); 
    ff.start();
    int lenght = ff.getLengthInFrames();
    int i = 0;
    Frame f = null;
    while (i < lenght) {
        // 过滤前1帧,避免出现全黑的图片,依自己情况而定
        f = ff.grabFrame();
        if ((i > 1) && (f.image != null)) {
            break;
        }
        i++;
    }
    IplImage img = f.image;
    int owidth = img.width();
    int oheight = img.height();
    // 对截取的帧进行等比例缩放
    int width = 800;
    int height = (int) (((double) width / owidth) * oheight);
    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
    bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),
            0, 0, null);
    ImageIO.write(bi, "jpg", targetFile);
    //ff.flush();
    ff.stop();
    System.out.println(System.currentTimeMillis() - start);
    return 
}

这个是首次尝试获取视频预览图,效果不错,一次成功。但是,还有但是。。。在Linux环境下就不行了,找不到类路径,java.lang.UnsatisfiedLinkError:no jniavcodec in java.library.path,然后具体的报错是NotClassFound这个类FFmpegFrameGrabber。在windows不会出现。然后,怎么办?正式上线可都是Linux系统环境。那就不得不说,接下来的第二种方法了。

2、javacv1.4.1,其实就是升级了

强大到 Android, Linux, MacOS 和 Windows都可以,而且是 x86 和 x64两个版本都有。依赖有所变化:

        <!-- javacv start -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>3.4.2-1.4.1</version>
        </dependency>
        <!-- javacv end -->

代码:

    public String getTempPath() {
        String tempPath="    ";//保存的目标路径
        File targetFile = new File(tempPath);
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        try{
             File file2 = new File("/data/photo/tempFile.mp4");
             if (file2.exists()) {
                log.info("文件存在,路径正确!");
                FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file2);
                ff.start();
                int ftp = ff.getLengthInFrames();
                int flag=0;
                Frame frame = null;
                while (flag <= ftp) {
                    //获取帧
                    frame = ff.grabImage();
                    //过滤前3帧,避免出现全黑图片
                    if ((flag>3)&&(frame != null)) {
                        break;
                    }
                    flag++;
                }
                ImageIO.write(FrameToBufferedImage(frame), "jpg", targetFile);
                ff.close();
                ff.stop();
             }
        }catch(Exception e){
           log.error("获取预览图失败",e)
        }
    }
    private RenderedImage FrameToBufferedImage(Frame frame) {
        //创建BufferedImage对象
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bufferedImage = converter.getBufferedImage(frame);
        return bufferedImage;
    }

好了,问题解决!

ps:<dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>仅仅出图片是可以不要这个的。

展开阅读全文
打赏
2
0 收藏
分享
加载中
你好,我采用你在上面提供的方法,在windows开发环境出现 java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.javacpp.avutil 这样的异常,在Linux环境出现 java.lang.NoClassDefFoundError: org/bytedeco/javacv/FFmpegFrameGrabber 这样的异常,不知道问题出在哪里?
2018/08/22 16:26
回复
举报
你好,我在windows中没有遇到问题,但是在linux服务器上也是 java.lang.NoClassDefFoundError: org/bytedeco/javacv/FFmpegFrameGrabber 这样的异常,请问你解决了么?请教一下
2020/09/21 11:36
回复
举报
更多评论
打赏
2 评论
0 收藏
2
分享
返回顶部
顶部