Java整合Selenium录制视频

捕捉视频

有时候我们未必能够分析故障只需用日志文件或截图的帮助。有时捕获完整的执行视频帮助。让我们了解如何捕捉视频。

我们将利用Monte媒体库的执行相同。

配置

第1步:导航到URL下载屏幕记录JAR,如下图所示。

http://www.randelshofer.ch/monte/index.html

第2步:下载后,添加JAR文件添加到当前项目的库。

第3步:我们会利用Java的AWT包来初始化显卡配置。

GraphicsConfiguration gc = GraphicsEnvironment

.getLocalGraphicsEnvironment()

.getDefaultScreenDevice()

.getDefaultConfiguration();

第4步:它采用下列参数创建ScreenRecorder的一个实例。

示例

我们将捕获简单的测试执行视频 - 百分比计算。

package com.demo.test;

import static org.monte.media.FormatKeys.EncodingKey;

import static org.monte.media.FormatKeys.FrameRateKey;

import static org.monte.media.FormatKeys.KeyFrameIntervalKey;

import static org.monte.media.FormatKeys.MIME_AVI;

import static org.monte.media.FormatKeys.MediaTypeKey;

import static org.monte.media.FormatKeys.MimeTypeKey;

import static org.monte.media.VideoFormatKeys.CompressorNameKey;

import static org.monte.media.VideoFormatKeys.DepthKey;

import static org.monte.media.VideoFormatKeys.ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE;

import static org.monte.media.VideoFormatKeys.QualityKey;

import java.awt.AWTException;

import java.awt.GraphicsConfiguration;

import java.awt.GraphicsEnvironment;

import java.io.File;

import java.io.IOException;

import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;

import org.monte.media.Format;

import org.monte.media.FormatKeys.MediaType;

import org.monte.media.math.Rational;

import org.monte.screenrecorder.ScreenRecorder;

import org.openqa.selenium.By;

import org.openqa.selenium.Keys;

import org.openqa.selenium.OutputType;

import org.openqa.selenium.TakesScreenshot;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

public class webdriverdemo {

private static ScreenRecorder screenRecorder;

public static void main(String[] args) throws IOException, AWTException {

GraphicsConfiguration gconfig = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();

screenRecorder = new ScreenRecorder(gconfig, 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, (int) 24,

FrameRateKey, Rational.valueOf(15), QualityKey, 1.0f,

KeyFrameIntervalKey, (int) (15 * 60)), new Format(MediaTypeKey,

MediaType.VIDEO, EncodingKey, "black", FrameRateKey,

Rational.valueOf(30)), null);

WebDriver driver = new ChromeDriver();

// 开始捕获视频

screenRecorder.start();

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

driver.navigate().to("https://www.baidu.com/");

driver.manage().window().maximize();

for (int i = 0; i < 3; i++) {

driver.findElement(By.id("kw")).sendKeys("selenium", Keys.ENTER);

driver.navigate().forward();

driver.navigate().back();

try {

Thread.sleep(3000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);

FileUtils.copyFile(screenshot, new File("D:screenshotsscreenshots1.jpg"));

// 停止捕获视频
screenRecorder.stop();

}

}

输出

录制的视频保存在"C:users<<UserName>>Videos"文件夹,如下图所示。

自定义视频位置代码

java 复制代码
package webui;

import static org.monte.media.FormatKeys.EncodingKey;
import static org.monte.media.FormatKeys.FrameRateKey;
import static org.monte.media.FormatKeys.KeyFrameIntervalKey;
import static org.monte.media.FormatKeys.MIME_AVI;
import static org.monte.media.FormatKeys.MediaTypeKey;
import static org.monte.media.FormatKeys.MimeTypeKey;
import static org.monte.media.VideoFormatKeys.CompressorNameKey;
import static org.monte.media.VideoFormatKeys.DepthKey;
import static org.monte.media.VideoFormatKeys.ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE;
import static org.monte.media.VideoFormatKeys.QualityKey;

import java.awt.AWTException;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;
import org.monte.media.Format;
import org.monte.media.FormatKeys.MediaType;
import org.monte.media.math.Rational;
import org.monte.screenrecorder.ScreenRecorder;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class webdriverdemo {
    private static ScreenRecorder screenRecorder;
    //ScreenRecorder 官方地址,可以下载源码
    //http://www.randelshofer.ch/monte/index.html

    public static void main(String[] args) throws IOException, AWTException {
        GraphicsConfiguration gconfig = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        screenRecorder = new ScreenRecorder(gconfig, 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, (int) 24,
                FrameRateKey, Rational.valueOf(15), QualityKey, 1.0f,
                KeyFrameIntervalKey, (int) (15 * 60)), new Format(MediaTypeKey,
                MediaType.VIDEO, EncodingKey, "black", FrameRateKey,
                Rational.valueOf(30)), null);

        WebDriver driver = new ChromeDriver();
        

        // 开始捕获视频
        screenRecorder.start();

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

        driver.navigate().to("https://www.baidu.com/");

        driver.manage().window().maximize();

        for (int i = 0; i < 3; i++) {
            driver.findElement(By.id("kw")).sendKeys("selenium", Keys.ENTER);
            driver.navigate().forward();
            driver.navigate().back();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);

        FileUtils.copyFile(screenshot, new File("D:/screenshotsscreenshots1.jpg"));
        System.out.println(screenRecorder.getStartTime());
        
        String vedioPath = "";
        //默认录制的视频保存在"C:users<<UserName>>Videos"文件夹,如下图所示。
        //获取视频所在位置,这里只有一个视频
        List<File> ll= screenRecorder.getCreatedMovieFiles();
        for (int i = 0; i < ll.size(); i++) {
        	System.out.println(ll.get(i).getAbsolutePath());
        	vedioPath = ll.get(i).getAbsolutePath();
		}
        
        // 停止捕获视频
        screenRecorder.stop();
        //复制视频到固定位置
        FileUtils.copyFile(new File(vedioPath), new File("D:/111.mp4"));
        System.out.println("Finish!!!!!");
    }
    
    public static void copyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
        if (srcFile.isDirectory()) {
            throw new IOException("Source '" + srcFile + "' exists but is a directory");
        } else if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
            throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
        } else {
            File parentFile = destFile.getParentFile();
            if (parentFile != null && !parentFile.mkdirs() && !parentFile.isDirectory()) {
                throw new IOException("Destination '" + parentFile + "' directory cannot be created");
            } else if (destFile.exists() && !destFile.canWrite()) {
                throw new IOException("Destination '" + destFile + "' exists but is read-only");
            } else {
                doCopyFile(srcFile, destFile, preserveFileDate);
            }
        }
    }
    private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate) throws IOException {
        if (destFile.exists() && destFile.isDirectory()) {
            throw new IOException("Destination '" + destFile + "' exists but is a directory");
        } else {
            Path srcPath = srcFile.toPath();
            Path destPath = destFile.toPath();
            long newLastModifed = preserveFileDate ? srcFile.lastModified() : destFile.lastModified();
            Files.copy(srcPath, destPath, StandardCopyOption.REPLACE_EXISTING);
            checkEqualSizes(srcFile, destFile, Files.size(srcPath), Files.size(destPath));
            checkEqualSizes(srcFile, destFile, srcFile.length(), destFile.length());
            destFile.setLastModified(newLastModifed);
        }
    }
    
    private static void checkEqualSizes(File srcFile, File destFile, long srcLen, long dstLen) throws IOException {
        if (srcLen != dstLen) {
            throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "' Expected length: " + srcLen + " Actual: " + dstLen);
        }
    }
}
相关推荐
深度学习lover1 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
API快乐传递者2 小时前
淘宝反爬虫机制的主要手段有哪些?
爬虫·python
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
阡之尘埃4 小时前
Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)
人工智能·python·机器学习·数据分析·智能风控·信贷风控
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js