【问题标题】:Java can't record the screen fast enoughJava 录屏速度不够快
【发布时间】:2013-12-16 07:16:55
【问题描述】:

我正在尝试用 Java 制作一个记录程序。我不希望使用除 JMF(Java 媒体框架)以外的任何外部库。我正在使用两个 Swing 计时器(作为其 Swing 应用程序),一个用于捕获屏幕并将其添加到队列中,另一个用于将 BufferedImage 从队列中取出并将其写入文件。这是我的计时器: 插入队列:

timer = new Timer(1000/FPS, new ActionListener() { //FPS is a user-inputed value from 1-60 by default its 25
        @Override
        public void actionPerformed(ActionEvent ae) {
            executor.execute(new Runnable() { //executor is a java.util.concurrent.Executor;
                //I put them in an executor so the timer wouldn't wait for the code to finish
                @Override
                public void run() {
                    try {
                        images.insert(R.createScreenCapture(Screen)); //Images is my own queue & R is a java.awt.Robot
                        //Screen is a rectangle that is Toolkit.getDefaultToolkit().getScreenSize()
                    } catch (Exception e) {
                        ExceptionPrinter.PrintE(e); //This is just a method to print the exception to me
                        System.out.print(images.length());
                        timer.stop();
                        timer2.stop();
                    } catch (OutOfMemoryError e) { //This is mainly a debug catch
                        timer.stop();
                        timer2.stop();
                        System.out.print(images.length());
                        e.printStackTrace();
                    }
                }
            });
        }
    });

要写图像:

timer2 = new Timer(1000 / FPS, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (images.length() != 0) {
                            if (!(new File("C:").getFreeSpace() <= 10000000)) {
                                String path=AppRunner.AppR3Directory + "VideoTemp" + File.pathSeparator + file + getModifier() + File.pathSeparator + image + ".JPEG";
                                //AppRunner.AppR3Directory is the working directory of the program (never changes)
                                //file is the user-inputed filename & getModifier() is either "" or a number above 0 (for when the program auto-starts another record)
                                ImageIO.write(images.pop(), "JPEG", new java.io.File(path));
                                imagelist.add(path); //This adds it to my list of images for when i change it to a .mov (custom array)
                                image++;
                            } else {
                                throw new SecurityException("Not enough memory!");
                            }
                        }
                    } catch (IOException e) {
                        ExceptionPrinter.PrintE(e);
                        timer.stop();
                        timer2.stop();
                    } catch (SecurityException e) {
                        ExceptionPrinter.PrintE(e);
                        timer.stop();
                        timer2.stop();
                    }
                }
            });

我的问题是它的录制速度似乎不够快。例如,默认值为 25 FPS,我只能得到 6 FPS。我尝试更改许多不同的内容并在整个互联网上进行搜索,但找不到解决方案。我想找出我在让这个记录足够快的地方是不正确的。在此先感谢任何想出来的人(我已经坚持了三天)。

编辑:正如 SimonC 所说,我确实计划将其更改为一个计时器并使用一种写入方法(由于写入延迟,我最初有两个)。

【问题讨论】:

  • “例如,默认值为 25 FPS,我只能得到 6 FPS。” 那是什么屏幕分辨率?为了尽快获得更好的帮助,请发帖SSCCE
  • FPS 声明为什么?这也是一个常见的问题,捕获整个屏幕需要很长时间......
  • @Andrew Thompson:我的屏幕分辨率是 1366 x 768
  • @MadProgrammer 它是从 JSlider 检索的 int 值
  • 速度部分几个月前已经问过了:stackoverflow.com/questions/17665529/…。 2004年的bugbugs.sun.com/view_bug.do?bug_id=5090776还没有关闭。

标签: java swing screen-capture recording


【解决方案1】:

试试Monte Media Library screen recorder。我上次测试时得到了很好的结果。

Windows Media Player 说它无法打开它..

AFAIR WMP 用 all MOV 来说明这一点。很烦人,因为它声称文件关联。尝试使用不是 WMP 的播放器。


从长远来看,您可能希望将 MOV 转换为另一种格式。使用 JMF 制作的那些是巨大的。

【讨论】:

    【解决方案2】:

    尝试独立于定时器运行这些线程。我的意思是,不要使用这些计时器。启动Thread,使用sleep(1000/FPS)实现计时。

    【讨论】:

    • 我要试试这个。
    • 不,这并没有改变结果。
    【解决方案3】:

    使用 Swing Timer 保留屏幕捕获任务是值得的,但图像写入任务应该移动到一个简单的 Thread 在添加图像后立即从队列中拉出图像。由于您将在多个线程之间进行协调,因此请考虑将您的队列更改为BlockingQueue

    【讨论】:

    • 据我所知,在 EDT 外拨打 Robot#createScreenCapture 应该是安全的......我可能是错的,所以我只是想问一下你是否知道我不知道的事情 ;)
    猜你喜欢
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2020-07-26
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多