javacv截取视频预览图

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

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

1、javacv0.8版本

       
            org.bytedeco
            javacv
            0.8
        

先上代码

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两个版本都有。依赖有所变化:

        
        
            org.bytedeco
            javacpp
            1.4.1
        
        
            org.bytedeco
            javacv
            1.4.1
        
        
            org.bytedeco.javacpp-presets
            opencv-platform
            3.4.1-1.4.1
        
        
            org.bytedeco.javacpp-presets
            ffmpeg-platform
            3.4.2-1.4.1
        
        

代码:

    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:
            org.bytedeco.javacpp-presets
            opencv-platform
            3.4.1-1.4.1
       
仅仅出图片是可以不要这个的。

转载于:https://my.oschina.net/u/3763771/blog/1852685

你可能感兴趣的:(javacv截取视频预览图)