Search code examples
javaffmpeg

How do I extract all the frames from a video in Java?


I'm trying to grab the frames from a video and put them into a collection of BufferedImage so I can use the images later. I tried to use the code in the second answer for this question, but it wasn't really helpful because the code they provided only grabs the first frame. How would I extract all the frames and put them into a collection?


Solution

  • So, a little bit of Googling (and reading the source code), I was able to hobble together this basic concept.

    The "obvious" solution was to loop over the frames in the video and extract them, the "un-obvious" solution was "how"?!

    The two methods you need are FFmpegFrameGrabber#getLengthInFrames and FFmpegFrameGrabber#setFrameNumber, from there it's just a simple method of converting the current frame and writing it to a file (which has already been demonstrated from the previous question)

    File videoFile = new File("Storm - 106630.mp4");
    FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoFile.getAbsoluteFile());
    frameGrabber.start();
    Java2DFrameConverter c = new Java2DFrameConverter();
    int frameCount = frameGrabber.getLengthInFrames();
    for (int frameNumber = 0; frameNumber < frameCount; frameNumber++) {
        System.out.println("Extracting " + String.format("%04d", frameNumber) + " of " + String.format("%04d", frameCount) + " frames");
        frameGrabber.setFrameNumber(frameNumber);
        Frame f = frameGrabber.grab();
        BufferedImage bi = c.convert(f);
        ImageIO.write(bi, "png", new File("Frame " + String.format("%04d", frameNumber) + "-" + String.format("%04d", frameCount) + ".png"));
    }
    frameGrabber.stop();
    

    Now, obviously, you could store the images into some kind of List in memory, just beware, depending on the size and length of the original video, this might run you into memory issues.