Monte Screen Recorder突发故障 录制生成空白无法播放视频
MonteScreenRecorder生成视频空白无法播放问题
问题现象
此前一直使用MonteScreenRecorder录制测试执行过程,一周前最后一次成功录制的视频可正常使用,近期突然出现录屏异常:测试运行完成后视频文件正常生成到指定目录,但尝试播放时视频无法加载、无法启动播放,全程显示为空白。
现有实现代码
录屏工具类代码
public class ScreenRecorderUtil extends ScreenRecorder { public static ScreenRecorder screenRecorder; public String name; public ScreenRecorderUtil(GraphicsConfiguration cfg, Rectangle captureArea, Format fileFormat, Format screenFormat, Format mouseFormat, Format audioFormat, File movieFolder, String name) throws IOException, AWTException { super(cfg, captureArea, fileFormat, screenFormat, mouseFormat, audioFormat, movieFolder); this.name = name; } @Override protected File createMovieFile(Format fileFormat) throws IOException { if (!movieFolder.exists()) { movieFolder.mkdirs(); } else if (!movieFolder.isDirectory()) { throw new IOException("\"" + movieFolder + "\" is not a directory."); } SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH.mm.ss"); return new File(movieFolder, name + "-" + dateFormat.format(new Date()) + "." + Registry.getInstance().getExtension(fileFormat)); } public static void startRecord(String methodName) throws Exception { File file = new File("./reports-recordings/"); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int width = screenSize.width; int height = screenSize.height; Rectangle captureSize = new Rectangle(0, 0, width, height); GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment(). getDefaultScreenDevice() .getDefaultConfiguration(); screenRecorder = new ScreenRecorderUtil(gc, captureSize, new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI), new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, CompressorNameKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, DepthKey, 24, FrameRateKey, Rational.valueOf(15), QualityKey, 1.0f, KeyFrameIntervalKey, 15 * 60), new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, "black", FrameRateKey, Rational.valueOf(30)), null, file, methodName); screenRecorder.start(); } public static void stopRecord() throws Exception { screenRecorder.stop(); } }
测试基类启停逻辑
public abstract class BaseTest extends DriverUtil { @BeforeMethod protected static void openDriver() throws Exception { DriverUtil.openBrowser(); ScreenRecorderUtil.startRecord("TestRecording"); } @AfterMethod protected static void cleanUp() throws Exception { DriverUtil.closeBrowser(); ScreenRecorderUtil.stopRecord(); } protected void LOG(String message) { TestListener.getTestSection().info(message); } protected void IMG(String message) { String screenshot = ((TakesScreenshot) UIActions.driver).getScreenshotAs(OutputType.BASE64); TestListener.getTestSection().addScreenCaptureFromBase64String(screenshot, message); } }
引入的Maven依赖
<dependency> <groupId>com.github.stephenc.monte</groupId> <artifactId>monte-screen-recorder</artifactId> <version>0.7.7.0</version> </dependency>
故障原因与修复方案
按优先级从高到低排查修复:
- 鼠标格式配置错误:当前代码中
mouseFormat参数的EncodingKey被设置为"black",属于非法配置。该参数用于指定鼠标光标的编码格式,传入"black"会触发编码器异常,输出全黑/空白帧,之前可正常使用是因为旧版本JDK或系统组件未对该参数做合法性校验,近期环境更新后参数校验生效触发问题。将该参数替换为合法配置即可:new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE, FrameRateKey, Rational.valueOf(30)) - 停止录屏时序错误:当前
@AfterMethod逻辑中先关闭浏览器再停止录屏,浏览器关闭时触发的资源释放、屏幕重绘可能打断Monte的视频流写入,导致AVI文件头、帧索引损坏,播放器无法识别有效帧。调整执行顺序,先停止录屏再关闭浏览器:@AfterMethod protected static void cleanUp() throws Exception { ScreenRecorderUtil.stopRecord(); DriverUtil.closeBrowser(); } - 高DPI缩放适配问题:如果近期系统更新自动开启了125%/150%等非100%显示缩放,Monte 0.7.7.0版本无法自动识别物理分辨率,通过
Toolkit.getDefaultToolkit().getScreenSize()拿到的是缩放后的逻辑分辨率,捕获区域超出物理屏幕范围,采集到的全是空帧。两种修复方式二选一:- 给JVM启动参数添加
-Dsun.java2d.dpiaware=false禁用DPI感知 - 手动计算缩放比例,将捕获宽高乘以系统缩放系数,匹配物理屏幕分辨率
- 给JVM启动参数添加
- 目录权限问题:检查生成的视频文件大小,如果文件大小仅几KB,说明录屏进程只有文件创建权限、没有帧数据写入权限,给
./reports-recordings/目录开放当前用户的完全读写权限即可。
内容的提问来源于stack exchange,提问作者zheb
相关产品推荐
相关产品推荐

