我正在尝试用Java创建一个记录程序。我宁愿不使用除JMF(Java Media Framework)之外的任何外部库。我正在使用两个Swing Timers(作为它的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。我试过改变许多不同的东西&amp;在互联网上搜索,我找不到解决方案。我想知道我在哪里得到足够快的记录。提前感谢任何想出来的人(我已经坚持了三天)。
编辑:我计划将其更改为一个计时器&amp;使用一种方法来写(我最初有两个因为写延迟),如SimonC所说。
答案 0 :(得分:1)
试试Monte Media Library screen recorder。我上次测试时得到了很好的结果。
Windows Media Player说它无法打开它..
AFAIR WMP用所有 MOV表示。非常恼人,因为它声称文件关联。尝试使用非WMP的播放器。
从长远来看,您可能希望将MOV转换为其他格式。使用JMF生成的是 huge。
答案 1 :(得分:0)
尝试独立于计时器运行这些线程。我的意思是,不要使用这些计时器。使用Thread
启动sleep(1000/FPS)
并实施时间安排。
答案 2 :(得分:0)
使用Swing Timer
保持屏幕捕获任务是值得的,但是图像编写任务应该在添加后立即移动到简单的Thread
拉出队列中的图像。由于您将在多个线程之间进行协调,因此请考虑将队列更改为BlockingQueue
。