对于遵循 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();
}
}
Run Code Online (Sandbox Code Playgroud)
我不了解 Windows 或 Mac OS X,但我怀疑我们需要直接访问本机 API。尽管如此,JavaCPP可以帮助解决这个问题。
以@Samuel 的回答为基础,根据官方ffmpeg 文档,如果您将file参数传递给FFmpegFrameGrabber(实际上是input作为-i选项传递给 ffmpeg 的参数)遵守不同的格式每个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");
Run Code Online (Sandbox Code Playgroud)
对于 OSX:
new FFmpegFrameGrabber("\"<screen device index>:\"")
.setFormat("avfoundation");
Run Code Online (Sandbox Code Playgroud)
对于 Linux:
new FFmpegFrameGrabber(":<display id>+<x>,<y>")
.setFormat("x11grab");
Run Code Online (Sandbox Code Playgroud)
PS:还没有完全测试过,所以不确定引号是否真的有必要。