【问题标题】:JavaCV FFmpegFrameFilter does not work for fps filterJavaCV FFmpegFrameFilter 不适用于 fps 过滤器
【发布时间】:2020-01-14 15:33:13
【问题描述】:

我正在尝试使用 FFmpegFrameFilter 和 JavaCV 的 -grabber 更改视频的帧速率。但是,filter.pull(); 总是返回 null。

我基本上已经尝试了拉框架和推框架的所有组合,但似乎没有任何效果。

这是我的代码:


    FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new File("input.mp4"));
    grabber.start();

    FFmpegFrameFilter filter = new FFmpegFrameFilter("fps=fps=60", null, grabber.getImageWidth(), grabber.getImageHeight(), 0);
    filter.setVideoInputs(1);
    filter.start();

    Java2DFrameConverter converter = new Java2DFrameConverter();

    for (int i = 0; i < 10; i++) {
        //Push the newly grabbed frame to the filter.
        Frame frame = grabber.grabImage();
        int n = frame.image.length - 1;
        filter.pushImage(n > 0 ? n : 0, frame.imageWidth, frame.imageHeight, frame.imageDepth, frame.imageChannels, frame.imageStride, grabber.getPixelFormat(), frame.image);

        //Pull the frame from the filter, convert it to a BufferedImage, and save it.
        //This line throws an IllegalArgumentException, stating the image is null.
        ImageIO.write(converter.convert(filter.pullImage()), "jpg", new File(outputPath + i + ".jpg"));
    }

我的最佳猜测是我给pushImage(...) 提供了错误的参数,因为我不确定n 的第一个参数应该是什么。

【问题讨论】:

  • 使用 push() 代替,这将满足需要。除此之外,fps 需要时间戳,因此我们可能需要手动设置这些时间戳,如本期所述:github.com/bytedeco/javacv/issues/717#issuecomment-377913162
  • @SamuelAudet 谢谢,但push() 也不起作用。但是,我想出了一种方法来避免使用 while 循环进行过滤。我会在下面发布我的解决方案,以防有人偶然发现这篇文章。

标签: java video video-processing javacv javacpp


【解决方案1】:

我想出了一个避免过滤器的方法。

class GrabWithDifferentFrameRate {

    private Frame lastFrame;
    private FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(input);

    // Basically converts a frameNumber based on the desiredFrameRate 
    // to one fitting for the grabbers frameRate and returns the frame at that frameNumber
    public Frame grabAt(int frameNumber, int desiredFrameRate) {
        double stepSize = desiredFrameRate / grabber.getFrameRate();
        double adjustedFrameNumber = calculateAdjustedFrameNumber(stepSize);

        Frame frame = lastFrame;
        while ((adjustedFrameNumber <= frameNumber && frameNumber / stepSize < grabber.getLengthInFrames())) {
            frame = grabber.grabImage();
            adjustedFrameNumber = calculateAdjustedFrameNumber(stepSize);
        }

        return frame;
    }

    private double calculateAdjustedFrameNumber(double stepSize) {
        return grabber.getFrameNumber() * stepSize;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-11
    • 2021-07-07
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    相关资源
    最近更新 更多