【问题标题】:Combining BufferedImages into video with xuggler使用 xuggler 将 BufferedImages 组合成视频
【发布时间】:2014-10-13 16:56:45
【问题描述】:

我正在尝试使用 xuggler 从 BufferedImages 列表中制作视频。我按照this教程,代码运行良好。

但是,当我将示例中的工作代码合并到我的代码中时,我得到了一个 RuntimeException:

java.lang.RuntimeException: 无法写入数据包:com.xuggle.xuggler.IPacket@46575264[complete:true;dts:67915;pts:67915;size:24201;key:false;flags:0;stream index :0;持续时间:1;位置:-1;时基:1/65535;] 在 com.xuggle.mediatool.MediaWriter.writePacket(MediaWriter.java:1215) 在 com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:767) 在 com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:810) 在 s3.S3CompositeUtil.generateVideo(S3CompositeUtil.java:247) 在 s3.S3CompositeUtil.main(S3CompositeUtil.java:349)

Xuggler 文档提到: 调用者必须确保 IMediaData.getTimeStamp()(如果指定)始终单调递增,否则将引发 RuntimeException。

但我认为我在生成视频时所花费的时间在任何时候都不会减少。

    private void generateVideo() {
    System.out.println("Creating video...");
    String outputMoviePath = "";
    IMediaWriter writer = null;
    if (allLabels) {
        outputMoviePath = TEMP_DIR_PATH + "/" + clipName + "/" + clipName + "_" + "all_labels" + ".avi";
    }
    else {
        outputMoviePath = TEMP_DIR_PATH + "/" + clipName + "/" + clipName + "_" + labels[desiredLabelIdx] + ".avi";
    }
    writer = ToolFactory.makeWriter(outputMoviePath);
    // add one video stream, with position 0 and ID 0, and a frame rate of OUTPUT_MOVIE_FPS
    writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4, vidWidth, vidHeight);
    long startTime = System.nanoTime();
    for (int idxF = 0; idxF < numFrames; idxF++) {
        BufferedImage currFrameImg = convertToType(videoBIHolder.get(idxF), BufferedImage.TYPE_3BYTE_BGR);
//          BufferedImage currFrameImg = videoBIHolder.get(idxF);
        System.out.println("currFrameImg type is " + currFrameImg.getType()); // debug
        // encode video to stream at 0
        long frameTimeInVideo = System.nanoTime() - startTime;
        System.out.println("Time: " + frameTimeInVideo);
        writer.encodeVideo(0, currFrameImg, frameTimeInVideo, TimeUnit.NANOSECONDS);
        // sleep for millisec. amount of time of the frame rate
        try {
            Thread.sleep((long) (1000/OUTPUT_MOVIE_FPS)); //OUTPUT_MOVIE_FPS
        }
        catch (InterruptedException e) {
            System.err.println();
        }
    }

(S3CompositeUtil.java:247) 是行

            writer.encodeVideo(0, currFrameImg, frameTimeInVideo, TimeUnit.NANOSECONDS);

我需要 OUTPUT_MOVIE_FPS 为 1,但奇怪的是,当它为 5 时,视频创建时没有例外,当它为 2 时,“视频”只是第一帧(没有其他帧),而当它是 1,我得到了这个异常。

有什么想法吗?我非常感谢我能得到的所有帮助!

【问题讨论】:

    标签: java xuggler


    【解决方案1】:

    我在我的一个多媒体课程中教授 Xuggler,我的一些学生在创建定格动画或创建图片幻灯片的视频时报告了类似的问题。

    我们采取了至少 2 甚至 10 FPS 的方法。有趣的是,您很可能不会使用更多内存来存储视频。 MPG4 编码器足够聪明,可以只将预测帧插入到基本上是空的视频文件中,因为在插入全新的帧之前,帧中没有差异。

    这种方法的唯一缺点是会导致更多的编码开销。显然,将任何帧插入到视频流中都会导致 CPU 负载,即使最终解码器决定只能插入一个空的预测帧。

    编辑:事实证明,我们实际上是以 25 fps 的速率将帧插入到视频中。具有上述所有缺点。但是,出于好奇,我现在用 10 fps 和 25 fps 之间的帧速率进行了测试,结果发现文件大小没有显着变化。有趣的是,10 fps 的测试文件是最大的。

    静止图像的 5 秒全高清视频大小在 450kb 到 580kb 之间。所以我建议你尝试一下帧速率,然后选择 ffmpeg / Xuggler 可以为 H264 处理的最低帧速率(实际上这应该在某个地方的文档中,但我现在找不到它)。

    为了测试,我使用以下代码重新插入相同的 BufferedImage。

        final IMediaWriter writer = ToolFactory.makeWriter(outputFile);
        writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, img.getSize().width, screenshot.getSize().height);
        long startTime = System.nanoTime();
        for (int i=0; i<seconds*25; i++) {
            BufferedImage bgrScreen = Tools.convertToType(img, BufferedImage.TYPE_3BYTE_BGR);
            writer.encodeVideo(0, bgrScreen, System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
            try {
                Thread.sleep((long) (1000 / 25));
            } catch (InterruptedException e) {
                // ignore
            }
        }
        writer.close();
    

    专业提示:在现实世界的应用程序中,我们使用一个线程来提供图像帧,并使用一个线程来执行编码 (writer.encodeVideo),这样我们就可以确保我们击中了一个准确的帧速率为 25 fps。在您的示例(以及我的测试代码)中,添加了 Xuggler / ffmpeg 的编码时间。

    【讨论】:

    • 非常感谢您的回答!当我做 2 FPS 时,尽管我总共有 12 帧,但我只得到了第一帧的“视频”。所以它几乎只显示了大约 6 秒的图像。您或您的任何学生都发生过这种情况吗?如果是这样,您是如何解决的?
    • 嗨,是的,我们经历过类似的影响,但我现在很难记住这些影响是何时以及如何发生的。尽管如此,我现在尝试对帧速率从 10 fps 到 25 fps 的单个静止图像进行编码,并将结果添加到我的答案中。也许这可以说服您提高帧速率。
    • 好的,谢谢您的建议!我最终将帧速率提高到 5,然后多次添加每个帧,使视频看起来具有 1 的帧速率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    相关资源
    最近更新 更多