通过javacv对视频每隔1秒钟截取1张图片
阅读原文时间:2023年07月15日阅读:1

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.bytedeco.javacpp.avutil
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:274)
at org.bytedeco.javacpp.Loader.load(Loader.java:385)
at org.bytedeco.javacpp.Loader.load(Loader.java:353)
at org.bytedeco.javacpp.avformat$AVFormatContext.(avformat.java:2249)
at org.bytedeco.javacv.FFmpegFrameGrabber.startUnsafe(FFmpegFrameGrabber.java:346)
at org.bytedeco.javacv.FFmpegFrameGrabber.start(FFmpegFrameGrabber.java:340)

http://stackoverflow.com/questions/27733142/could-not-initialize-class-org-bytedeco-javacpp-avutil-on-os-x-along-with-maven

org.bytedeco javacv 1.0

FFmpegFrameGrabber g = new FFmpegFrameGrabber("textures/video/anim.mp4");
g.start();

for (int i = 0 ; i < 50 ; i++) {
ImageIO.write(g.grab().getBufferedImage(), "png", new File("frame-dump/video-frame-" + System.currentTimeMillis() + ".png"));
}

g.stop();

http://stackoverflow.com/questions/15735716/how-can-i-get-a-frame-sample-jpeg-from-a-video-mov

https://github.com/bytedeco/javacv/

JavaCV 随机获取视频中的某些帧的图片

package com.egova.ffmpeg.java;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.imageio.ImageIO;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber.Exception;
import org.bytedeco.javacv.Java2DFrameConverter;

public abstract class FrameGrabberKit {

public static void main(String\[\] args) throws Exception {  
    randomGrabberFFmpegImage("F:/CodeSpace/java/ffmpeg\_java/resource/月赋情长.mp4", "./target", "月赋情长", 10);  
}

public static void randomGrabberFFmpegImage(String filePath, String targerFilePath, String targetFileName, int randomSize)  
        throws Exception {  
    FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);  
    ff.start();  
    int ffLength = ff.getLengthInFrames();  
    List<Integer> randomGrab = random(ffLength, randomSize);  
    int maxRandomGrab = randomGrab.get(randomGrab.size() - 1);  
    Frame f;  
    int i = 0;  
    while (i < ffLength) {  
        f = ff.grabImage();  
        if (randomGrab.contains(i)) {  
            doExecuteFrame(f, targerFilePath, targetFileName, i);  
        }  
        if (i >= maxRandomGrab) {  
            break;  
        }  
        i++;  
    }  
    ff.stop();  
}

public static void doExecuteFrame(Frame f, String targerFilePath, String targetFileName, int index) {  
    if (null == f || null == f.image) {  
        return;  
    }

    Java2DFrameConverter converter = new Java2DFrameConverter();

    String imageMat = "jpg";  
    String FileName = targerFilePath + File.separator + targetFileName + "\_" + index + "." + imageMat;  
    BufferedImage bi = converter.getBufferedImage(f);  
    File output = new File(FileName);  
    try {  
        ImageIO.write(bi, imageMat, output);  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  
}

public static List<Integer> random(int baseNum, int length) {

    List<Integer> list = new ArrayList<>(length);  
    while (list.size() < length) {  
        Integer next = (int) (Math.random() \* baseNum);  
        if (list.contains(next)) {  
            continue;  
        }  
        list.add(next);  
    }  
    Collections.sort(list);  
    return list;  
}  

}

之前每一秒钟截取一张图片,发现有些图片报了“[mpeg4 @ 05938aa0] warning: first frame is no keyframe”这个警告,而且截出的图片都是灰屏,根本没有图片。后来在网上找了很久,终于弄明白了,原来是ffmpeg它有“关键帧”这个说法,所以如果设置的帧的位置不是关键帧的位置的话,就可能截出的图片有问题。后来经过改进,终于搞定了。

public static void main(String\[\] args) {  
    System.out.println(System.getProperty("java.library.path"));  

// System.out.println("Welcome to OpenCV " + Core.VERSION);
// System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
// System.out.println("m = " + m.dump());

    // 加载本地的OpenCV库,这样就可以用它来调用Java API  
    System.loadLibrary(Core.NATIVE\_LIBRARY\_NAME);  
    Test t = new Test();  

// t.test();
// t.run();
// t.run2();
t.run3();
// System.out.println(t.CmpPic("d:/img/219.jpg"));
}

public void run3() {  
    CvCapture capture = opencv\_highgui.cvCreateFileCapture("D:/085402.crf");

    //帧率  
    int fps = (int) opencv\_highgui.cvGetCaptureProperty(capture, opencv\_highgui.CV\_CAP\_PROP\_FPS);  
    System.out.println("帧率:"+fps);

    IplImage frame = null;  
    double pos1 = 0;

    int rootCount = 0;

    while (true) {

        //读取关键帧  
        frame = opencv\_highgui.cvQueryFrame(capture);

        rootCount = fps;  
        while(rootCount > 0 ){  
            //这一段的目的是跳过每一秒钟的帧数,也就是说fps是帧率(一秒钟有多少帧),在读取一帧后,跳过fps数量的帧就相当于跳过了1秒钟。  
            frame = opencv\_highgui.cvQueryFrame(capture);  
            rootCount--;  
        }

        //获取当前帧的位置  
        pos1 = opencv\_highgui.cvGetCaptureProperty(capture,opencv\_highgui.CV\_CAP\_PROP\_POS\_FRAMES);  
        System.out.println(pos1);

        if (null == frame)  
            break;

        opencv\_highgui.cvSaveImage("d:/img/" + pos1 + ".jpg",frame);

    }

    opencv\_highgui.cvReleaseCapture(capture);  
}

http://www.voidcn.com/blog/kouwoo/article/p-4830734.html

http://stackoverflow.com/questions/33319899/java-lang-unsatisfiedlinkerror-no-opencv-java300-in-java-library-path-only-whil

http://git.oschina.net/leixiaohua1020/simplest_video_website

https://ffmpeg.zeranoe.com/builds/

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章