Search code examples
javaffmpegvideo-processingjcodec

Create a video preview image like youtube or whatsapp from a Video file (.mp4) using JAVA Code


Issue 1. When I use FFmpeg Java api, program doesn't run and print anything after grabber.start(). No preview generated.

Code Sample :

public static boolean generatePreviewImage(String filePath, String previewFileName ) throws IOException {
        boolean isPreviewGenerated = false;
        System.out.println("Request received to generate thumbnail for video.");
        System.out.println("VideoFilePath : "+filePath);
        System.out.println("ResultFileName : "+previewFileName);
        try {

            FFmpegFrameGrabber fGrabber = new FFmpegFrameGrabber(filePath);
            System.out.println("FrameGrabber found "+fGrabber);
            fGrabber.start();
            System.out.println("Frame started..");
            ImageIO.write(fGrabber.grab().getBufferedImage(), "jpg", new File(previewFileName));
            System.out.println("Image written successfully as "+previewFileName);
            isPreviewGenerated = true;
            fGrabber.stop();
            System.out.println("FrameGrabber stopped.. "+fGrabber);

        } catch(Exception e){
            System.out.println("Exception while creating video thumbnail : "+previewFileName+" - exception - "+e);
            e.printStackTrace();
        }
        System.out.println("Image written successfully? "+previewFileName);
        return isPreviewGenerated;
    }   

Result : Request received to generate thumbnail for video. VideoFilePath : /root/appdir/VIDEO20171124143855.mp4 ResultFileName : /root/appdir/vdthumb_0.jpg FrameGrabber found org.bytedeco.javacv.FFmpegFrameGrabber@3529360e

Nothing happens and gets printed after above statement..


Additional Information : I installed FFmpeg on Linux VPS as well and able to generate preview using command line root@vps19984[~/usr/appdir]#ffmpeg -i /root/appdir/.VIDEO20171123165555.mp4 -r 1 -f image2 image-%2d.png (above command ffmpeg generates preview successfully on linux box but I want to generate it via Java program)


Issue 2. When I use JCodec api, program generates a black image but NOT an image from video file. Code Sample :

public static boolean generatePreviewImage(String filePath, String previewFileName ) throws IOException, JCodecException {
    logger.info("Request received to generate thumbnail for video. VideoFilePath : "+filePath+", resultFileName "+previewFileName);
    boolean isPreviewGenerated = false;
    Picture framePic = FrameGrab.getNativeFrame(new File(filePath),20);
    logger.info("Frame grabbed successfully..");
    Transform transform = ColorUtil.getTransform(framePic.getColor(), ColorSpace.RGB);
    Picture rgb = Picture.create(framePic.getWidth(), framePic.getHeight(), ColorSpace.RGB);
    transform.transform(framePic, rgb);
    logger.info("Frame transformed successfully to RGB..");
    BufferedImage dst = new BufferedImage(rgb.getCroppedWidth(), rgb.getCroppedHeight(),
            BufferedImage.TYPE_INT_RGB);
    ImageIO.write(dst, "jpg", new File(previewFileName));
    isPreviewGenerated = true;
    logger.info("Is preview generated.."+isPreviewGenerated);

}

Result : Request received to generate thumbnail for video. VideoFilePath : /usr/appdir/VIDEO20171123165555.mp4, resultFileName /usr/appdir/vdthumb_0.jpg Frame grabbed successfully.. Frame transformed successfully to RGB.. Is preview generated..true

Issue : A black jpg image of 5 KB gets generated by JCodec


Solution

  • Check this code, as it successfully creates the file. Have made a few changes.This is the solution for Issue1. If you are unable to see the logs, then the issue is with the logger. You can paste the logger you are using or google the issue with your logger.

    public static boolean generatePreviewImage(String filePath,
            String previewFileName) throws IOException, Exception {
        logger.info("Request received to generate thumbnail for video. VideoFilePath : "
                + filePath + ", resultFileName " + previewFileName);
        boolean isPreviewGenerated = false;
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filePath);
        logger.info("FrameGrabber found " + grabber);
        grabber.start();
        logger.info("FrameGrabber started.. " + grabber);
        for (int i = 20; i < 22; i++) {
            logger.info("Reading first 2 images..");
            ImageIO.write(grabber.grab().getBufferedImage(), "jpg", new File(
                    previewFileName + "_" + i));
            logger.info(i + " image written successfully as " + previewFileName
                    + "_" + i + ".jpg");
            isPreviewGenerated = true;
        }
        grabber.stop();
        logger.info("Is preview generated.." + isPreviewGenerated);
        return isPreviewGenerated;
    
    }