裁剪 BufferedImage 以用于 Xuggle encodeVideo

Cropping BufferedImage For Use in Xuggle encodeVideo

我有一个应用程序可以捕获屏幕视频并保存到文件中。我让用户能够在 480、720 和 "Full Screen" 视频尺寸之间进行选择。 480会录在屏幕的小方框里,720会录在更大的方框里,当然,"Full Screen"会录在更大的方框里。但是,这个全屏框不是实际的屏幕分辨率。这是应用 window 大小,恰好在 1700x800 左右。视频工具非常适合 480 和 720 选项,如果 "Full Screen" 被覆盖为 1920x1080 的整个屏幕,它也可以正常工作。

我的问题:是否只允许某些尺寸?它是否必须符合特定的纵横比,或者是 "acceptable" 分辨率?下面我的代码是从 xuggle CaptureScreenToFile.java 文件修改而来的(问题的位置在注释中注明):

    public void run() {
        try {
            String parent = "Videos";
            String outFile = parent + "example" + ".mp4";
            file = new File(outFile);

            // This is the robot for taking a snapshot of the screen.  It's part of Java AWT
            final Robot robot = new Robot();
            final Rectangle customResolution = where;  //defined resolution (custom record size - in this case, 1696x813)

            final Toolkit toolkit = Toolkit.getDefaultToolkit();
            final Rectangle fullResolution = new Rectangle(toolkit.getScreenSize());  //full resolution (1920x1080)

            // First, let's make a IMediaWriter to write the file.
            final IMediaWriter writer = ToolFactory.makeWriter(outFile);

            writer.setForceInterleave(false);  

            // We tell it we're going to add one video stream, with id 0,
            // at position 0, and that it will have a fixed frame rate of
            // FRAME_RATE.    
            writer.addVideoStream(0, 0, FRAME_RATE, customResolution.width, customResolution.height);  //if I use fullResolution, it works just fine - but captures more of the screen than I want.

            // Now, we're going to loop
            long startTime = System.nanoTime();
            while (recording) {    
                // take the screen shot
                BufferedImage screen = robot.createScreenCapture(fullResolution);  //tried capturing using customResolution, but did not work.  Instead, this captures full screen, then tries to trim it below (also does not work).
                // convert to the right image type
                BufferedImage bgrScreen = convertToType(screen, BufferedImage.TYPE_3BYTE_BGR);  //Do I need to convert after trimming?

                BufferedImage trimmedScreen = bgrScreen.getSubimage((int)customResolution.getX(), (int)customResolution.getY(), (int)customResolution.getWidth(), (int)customResolution.getHeight());

                // encode the image
                try{
                    //~~~~Problem is this line of code!~~~~  Error noted below.
                    writer.encodeVideo(0, trimmedScreen, System.nanoTime() - startTime, TimeUnit.NANOSECONDS);  //tried using trimmedScreen and bgrScreen
                } catch (Exception e) {
                    e.printStackTrace();
                }

                // sleep for framerate milliseconds
                Thread.sleep((long) (1000 / FRAME_RATE.getDouble()));

            }
            // Finally we tell the writer to close and write the trailer if
            // needed
            writer.close();
        } catch (Throwable e) {
            System.err.println("an error occurred: " + e.getMessage());
        }
    }

    public static BufferedImage convertToType(BufferedImage sourceImage, int targetType) {
        BufferedImage image;

        // if the source image is already the target type, return the source image
        if (sourceImage.getType() == targetType)
            image = sourceImage;
        // otherwise create a new image of the target type and draw the new image
        else {
            image = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), targetType);
            image.getGraphics().drawImage(sourceImage, 0, 0, null);
        }

        return image;
    }

错误: java.lang.RuntimeException: 无法打开流 com.xuggle.xuggler.IStream@2834912[index:0;id:0;streamcoder:com.xuggle.xuggler.IStreamCoder@2992432[codec=com.xuggle.xuggler.ICodec@2930320[type=CODEC_TYPE_VIDEO;id=CODEC_ID_H264;name=libx264;];time base=1/50;frame rate=0/0;pixel type=YUV420P;width=1696;height=813;];framerate: 0/0;时基:1/90000;方向:出站;]:不允许操作

注意:文件已成功创建,但大小为零,无法用 Windows Media Player 打开,错误文本如下: Windows 媒体播放器无法播放该文件。播放机可能不支持文件类型或可能不支持用于压缩文件的编解码器。

抱歉这个冗长的问题。我有兴趣学习什么和为什么,而不仅仅是解决方案。因此,如果有人可以解释为什么它不起作用,或者向我指出 material 以提供帮助,我将不胜感激。谢谢!

尺寸尽量为偶数1696x812