我目前正在使用 Java 中的 Robot 类来记录屏幕。但是,它没有达到每秒 30 帧的最小值。我没有重新创建对象,并且尽可能高效,但我平均每秒只有 15 帧左右。机器人根本没有切割它。
我可以使用什么来捕获屏幕?我已经尝试过 Xuggle,但我似乎也无法足够快地捕捉到它。
对于遵循 X11 标准的操作系统(Linux、FreeBSD、Solaris 等),我们可以通过JavaCV和FFmpeg这样做:
import com.googlecode.javacv.*;
public class ScreenGrabber {
public static void main(String[] args) throws Exception {
int x = 0, y = 0, w = 1024, h = 768; // specify the region of screen to grab
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(":0.0+" + x + "," + y);
grabber.setFormat("x11grab");
grabber.setImageWidth(w);
grabber.setImageHeight(h);
grabber.start();
CanvasFrame frame = new CanvasFrame("Screen Capture");
while (frame.isVisible()) {
frame.showImage(grabber.grab());
}
frame.dispose();
grabber.stop();
}
}
我不了解 Windows 或 Mac OS X,但我怀疑我们需要直接访问本机 API。尽管如此,JavaCPP可以帮助解决这个问题。
建立在@Samuel的回答之上,根据官方的ffmpeg文档,如果你将file
传递给的参数FFmpegFrameGrabber
(这实际上是input
作为ffmpeg的选项传递下来的参数-i
)遵循不同的每个device
期望的格式。
IE:
对于 Windows:dshow
预计-i video="screen-capture-recorder"
对于 OSX:avfoundation
预计-i "<screen device index>:"
对于 Linux:x11grab
期望-i :<display id>+<x>,<y>
.
因此,只需将这些值(参数-i
)传递给构造函数并相应地设置格式(通过setFormat
)就可以了:
例子:
对于 Windows:
new FFmpegFrameGrabber("video=\"screen-capture-recorder\"")
.setFormat("dshow");
对于 OSX:
new FFmpegFrameGrabber("\"<screen device index>:\"")
.setFormat("avfoundation");
对于 Linux:
new FFmpegFrameGrabber(":<display id>+<x>,<y>")
.setFormat("x11grab");
PS:尚未对此进行全面测试,因此不确定报价是否真的必要。