tar*_*sch 6 java multithreading video-capture
以下问题应该是观看屏幕,记录事件(测量文本框变为绿色)并记录导致它的所有事件,从而产生导致它的事件的"电影".不幸的是,需要记录整个屏幕.到目前为止,我已经完成了识别参与的部分.但是我几乎没有每秒两帧.我想有大约25到30帧/秒.
我的想法是用两个单独的线程进行写作和阅读.由于写入事件很少并且可以在后台运行,因此录制事件可能会占用更多时间并且运行得更快.不幸的是,整个事情似乎太慢了.我希望能够在事件发生前 10到20秒在磁盘上写入屏幕.
编辑:如果可能的话,我希望尽可能保持与平台无关.
编辑2:Xuggler似乎有一个独立于平台的jar文件.不幸的是,我并没有真正了解我将如何能够将它用于我的目的:记录20秒,直到触发isarecord.
这是我到目前为止所做的:
package fragrecord;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
public class Main {
public static void main(String[] args) {
//The numbers are just silly tune parameters. Refer to the API.
//The important thing is, we are passing a bounded queue.
ExecutorService consumer = new ThreadPoolExecutor(1,4,30,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(100));
System.out.println("starting");
//No need to bound the queue for this executor.
//Use utility method instead of the complicated Constructor.
ExecutorService producer = Executors.newSingleThreadExecutor();
Runnable produce = new Produce(consumer);
producer.submit(produce);
try {
producer.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
consumer.shutdown();
try {
consumer.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Produce implements Runnable {
private final ExecutorService consumer;
public Produce(ExecutorService consumer) {
this.consumer = consumer;
}
boolean isarecord(BufferedImage image){
int x=10, y = 10;
Color c = new Color(image.getRGB(x,y));
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
// Determine whether to start recording
return false;
}
@Override
public void run() {
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//
// Capture screen from the top left to bottom right
//
int i = 0;
while(true) {
i++;
BufferedImage bufferedImage = robot.createScreenCapture(
new Rectangle(new Dimension(1024, 798)));
Runnable consume = new Consume(bufferedImage,i);
consumer.submit(consume);
}
}
}
class Consume implements Runnable {
private final BufferedImage bufferedImage;
private final Integer picnr;
public Consume(BufferedImage bufferedImage, Integer picnr){
this.bufferedImage = bufferedImage;
this.picnr = picnr;
}
@Override
public void run() {
File imageFile = new File("screenshot"+picnr+".png");
try {
System.out.println("screenshot"+picnr+".png");
ImageIO.write(bufferedImage, "png", imageFile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于各种原因,使用执行器、重写 nio 和类似的东西不会有帮助。
以下是您应该考虑的一些事项:
一言以蔽之:java 很糟糕,非常糟糕。
尽管如此,我已经编写了这个工具的我自己的版本。 http://pastebin.com/5h285fQw
它所做的一件事是允许在鼠标之后记录一个较小的矩形。在 500x500 下,它可以轻松达到 25fps,图像在后台写入(图像压缩+写入对我来说需要 5-10 毫秒,因此写入速度比记录速度快得多)
(*) 您没有谈论如何分析图像,但这似乎是性能问题的主要根源。一些想法:
(**) 在 macOS 上,您可以使用内置的 Quicktime X 非常高效地录制到硬盘;在 Windows 上,我听说 playclaw (http://www.playclaw.com/) 非常好,也许物有所值(想想你在优化 java 野兽上浪费的时间会赚到什么:))
| 归档时间: |
|
| 查看次数: |
1168 次 |
| 最近记录: |