Создайте изображение для предварительного просмотра видео, например YouTube или WhatsApp, из видеофайла (.mp4), используя код JAVA.

Проблема 1. Когда я использую FFmpeg Java api, программа не запускается и ничего не печатает после Grabber.start(). Превью не создается.

Пример кода:

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;
    }   

Результат: получен запрос на создание эскиза для видео. VideoFilePath: /root/appdir/VIDEO20171124143855.mp4 ResultFileName: /root/appdir/vdthumb_0.jpg FrameGrabber найден org.bytedeco.javacv.FFmpegFrameGrabber@3529360e

Ничего не происходит и печатается после вышеуказанного оператора.


Дополнительная информация: я также установил FFmpeg на Linux VPS и смог создать предварительный просмотр с помощью командной строки root@vps19984[~/usr/appdir]#ffmpeg -i /root/appdir/.VIDEO20171123165555.mp4 -r 1 -f image2 image- %2d.png (приведенная выше команда ffmpeg успешно создает предварительный просмотр в Linux, но я хочу создать его с помощью программы Java)


Проблема 2. Когда я использую API JCodec, программа генерирует черное изображение, но НЕ изображение из видеофайла. Пример кода:

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);

}

Результат: получен запрос на создание эскиза для видео. VideoFilePath : /usr/appdir/VIDEO20171123165555.mp4, resultFileName /usr/appdir/vdthumb_0.jpg Кадр успешно захвачен.. Кадр успешно преобразован в RGB.. Создан предварительный просмотр..true

Проблема: JCodec генерирует черное изображение в формате jpg размером 5 КБ.


person Ravi Dua    schedule 24.11.2017    source источник


Ответы (2)


Проверьте этот код, так как он успешно создает файл. Внесли несколько изменений. Это решение для Issue1. Если вы не можете просмотреть журналы, проблема связана с регистратором. Вы можете вставить регистратор, который вы используете, или найти проблему с вашим регистратором в Google.

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;

}
person Urvashi Soni    schedule 24.11.2017
comment
Спасибо за ответ Урваши, но логгеры не проблема.. граббер не запустился даже после удаления логгеров и использования вашего отредактированного кода.. - person Ravi Dua; 24.11.2017
comment
Что вы используете для устранения зависимости FFmpegFrameGrabber?? Я использую зависимость maven из репозитория. Также вы можете использовать System.out.println() для прохождения течь изначально. - person Urvashi Soni; 24.11.2017
comment
Кроме того, вы исправили форму кода throws IOException {} на throws IOException { ?? - person Urvashi Soni; 24.11.2017
comment
Я использую maven со следующей зависимостью ‹dependency› ‹groupId›org.bytedeco‹/groupId› ‹artifactId›javacv‹/artifactId› ‹version›0.10‹/version› ‹/dependency› Также я изменил каждый регистратор на System.out. println, и все равно программа застряла на операторе fGrabber.start(). Выглядит граббером, даже не заводясь. Примечание: {} после IOException было опечаткой при вставке кода в stackoverflow. - person Ravi Dua; 24.11.2017
comment
Да, эта версия, которую вы используете, является исключением. Пожалуйста, используйте версию, уже опубликованную в моем предыдущем комментарии. Нажмите репозиторий. Используйте версию 0.8, и ваша работа сделана. - person Urvashi Soni; 24.11.2017
comment
Урваши, В версии 0.8 он даже не создал объект FFmpegFrameGrabber, оставив start(). Программа остановилась за одну строку до .start(), где создается объект FFmpegFrameGrabber. Он также не выдал никаких исключений. Просто сообщаю вам, что я запускаю программу на машине CentOs VPS. - person Ravi Dua; 24.11.2017
comment
Привет, Рави, я запускаю программу в JBoss Developer Studio (инструмент, похожий на Eclipse) на Fedora24, и оба файла успешно созданы. Тогда это кажется проблемой вашей среды. Что является исключением при создании объекта граббера? можно сюда то же самое вставить? - person Urvashi Soni; 25.11.2017
comment
Урваши, теперь он начал работать с вашим кодом. Спасибо за вашу помощь! - person Ravi Dua; 27.11.2017

Спасибо Урваши за все ваши комментарии и предложения. С FFMpeg в моей среде что-то не работает. Я тоже не получаю никаких исключений. Я попробую дальше и посмотрю, в чем проблема.

Но с JCodec (проблема № 2) я могу создать предварительный просмотр со следующим кодом:

В pom.xml добавлены следующие две зависимости:

<dependency>
    <groupId>org.jcodec</groupId>
    <artifactId>jcodec</artifactId>
    <version>0.2.2</version>
</dependency>
<dependency>
    <groupId>org.jcodec</groupId>
    <artifactId>jcodec-javase</artifactId>
    <version>0.2.1</version>
</dependency>

И в java-файле написан следующий код:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.jcodec.api.JCodecException;
import org.jcodec.api.awt.AWTFrameGrab;

public static boolean generatePreviewImage(String filePath, String previewFileName ) throws IOException, JCodecException {
    boolean isPreviewGenerated = false;
    try {
        double sec = 1;
        BufferedImage dst = AWTFrameGrab.getFrame(new File(filePath), sec);
        ImageIO.write(dst, "jpg", new File(previewFileName));
        isPreviewGenerated = true;
        //where filePath is the path of video file and previeFileName is the name of preview image file.    
    } 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;
}

Спасибо!

person Ravi Dua    schedule 27.11.2017