我正在开发一个应用程序,该应用程序在他/她执行某些活动时记录用户的屏幕、网络摄像头和麦克风。它将用于研究目的。该应用程序已在 Windows 上成功测试,但在 Mac OS X (Maverick with ) 上,该应用程序在开始录制时Java 7.0.45
变得缓慢且无响应。
这就是为什么我觉得这很难理解:
- 录制是在单独的线程中完成的,那么它如何影响另一个线程的响应?特别是在每次运行之后
Thread.yield()
或者Thread.sleep(...)
被调用。 - 日志显示,在尝试以 录制时
15 FPS
,产生的帧速率为2 FPS
. 所以看起来捕获单帧的代码可能太慢了。但是为什么它在 Windows 上运行良好呢?
快速说明:该应用程序已在 Windows 上被大量用户成功测试,但我只需要在一台 Mac 上测试它。然而,那个刚刚被格式化并得到了 OS X Maverick、Java(和 Netbeans)的全新安装。
您将在下面找到记录屏幕并使用Xuggler将其写入视频的代码。录制网络摄像头的代码是相似的,我怀疑录制音频与它有什么关系。我的问题是:
应用程序无响应的原因可能是什么?, 和
如何使代码更高效,从而提高 FPS?
IMediaWriter writer = ToolFactory.makeWriter(file.getAbsolutePath());
Dimension size = Globals.sessionFrame.getBounds().getSize();
Rectangle screenRect;
BufferedImage capture;
BufferedImage mousePointImg;
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);
int i = 0;
while (stop == false) {
// Get mouse cursor to draw over screen image.
PointerInfo mousePointer = MouseInfo.getPointerInfo();
Point mousePoint = mousePointer.getLocation();
Point screenPoint = new Point((int) (mousePoint.getX() -
Globals.sessionFrame.getBounds().getX()), (int) (mousePoint.getY() -
Globals.sessionFrame.getBounds().getY()));
// Get the screen image.
try {
screenRect = new Rectangle(Globals.sessionFrame.getBounds());
capture = new Robot().createScreenCapture(screenRect);
} catch ( ... ) { ... }
// Convert and resize the screen image.
BufferedImage image = ConverterFactory.convertToType(capture,
BufferedImage.TYPE_3BYTE_BGR);
IConverter converter = ConverterFactory.createConverter(image,
IPixelFormat.Type.YUV420P);
// Draw the mouse cursor if necessary.
if (mouseWithinScreen()) {
Graphics g = image.getGraphics();
g.drawImage(mousePointImg, (int) screenPoint.getX(),
(int) screenPoint.getY(), null);
}
// Prepare the frame.
IVideoPicture frame = converter.toPicture(image, (System.currentTimeMillis() -
startTimeMillis()) * 1000);
frame.setKeyFrame(i % (getDesiredFPS() * getDesiredKeyframeSec()) == 0);
// Write to the video
writer.encodeVideo(0, frame);
// Delay the next capture if we are at the desired FPS.
try {
if (atDesiredFPS()) {
Thread.yield();
} else {
Thread.sleep(1000 / getDesiredFPS());
}
} catch ( ... ) { ... }
i++;
}
writer.close();