文章目錄
- 前言
- 一、解決的問題
- 二、使用步驟
-
- 1.opendx源碼下載下傳
- 2.修改agent内容
前言
opendx是一款基于 appium 的自動化測試平台。支援web端控制手機,整個架構設計非常優秀,可以根據公司業務,進行二次開發使用。
一、解決的問題
由于華為手機高版本無法使用appium自帶的錄制功能。是以opendx添加了scrcpy錄制功能,缺點是需要在agent端安裝scrcpy,且windows無法支援錄制。由于公司大多數同學使用windows,導緻啟動的agent在高版本華為手機上無法錄制視訊,在用例結束後難以排查問題。
二、使用步驟
1.opendx源碼下載下傳
下載下傳位址
2.修改agent内容
ScrcpyVideoRecorder類代碼如下(示例):
package com.daxiang.core.mobile.android.scrcpy;
import com.daxiang.core.Device;
import com.daxiang.core.mobile.android.AndroidDevice;
import com.daxiang.utils.Terminal;
import com.daxiang.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Created by jiangyitao.
*/
@Slf4j
public class ScrcpyVideoRecorder {
private String mobileId;
private String videoName;
private boolean isRecording = false;
private CountDownLatch countDownLatch;
private Device device;
private FileChannel fc;
private Scrcpy scrcpy;
private static final String H264 = ".h264";
private static final String MP4 = ".mp4";
public ScrcpyVideoRecorder(String mobileId,Device device) {
this.mobileId = mobileId;
this.device = device;
}
public synchronized void start() {
if (isRecording) {
return;
}
countDownLatch = new CountDownLatch(1);
scrcpy = ((AndroidDevice) device).getScrcpy();
try {
videoName = UUIDUtil.getUUID();
fc = new FileOutputStream(videoName+H264).getChannel();
scrcpy.start(imgData -> {
try {
fc.write(imgData);
} catch (IOException e) {
}
});
isRecording = true;
} catch (Exception e) {
isRecording = false;
throw new RuntimeException(e);
}finally {
countDownLatch.countDown();
}
}
/**
* 1. kill scrcpy server來停止錄制視訊是最優方案。但大多數安卓Mobile隻能通過ps(非ps -ef)擷取到scrcpy server程序,
* 此時的程序名為app_process, appium在Mobile裡運作的程序也是app_process,是以可能會誤殺appium在Mobile裡運作的程序,不采用該方法
* 2. ExecuteWatchdog.destroyProcess()會導緻最後一部分視訊無法寫入,
* 因為運作在pc的scrcpy程序被直接幹掉,無法寫入最終的視訊,導緻擷取到破損的視訊
* 3. 在非windows作業系統下,scrcpy收到kill信号後,會寫入最後一部分視訊,目前采用該方法
* 4. 無法在windows上使用,windows taskkill和ExecuteWatchdog.destroyProcess()一樣
*/
public synchronized File stop() throws IOException {
if (!isRecording) {
throw new IllegalStateException("video is not in recording");
}
log.info("[{}]stop record video: {}", mobileId, videoName);
scrcpy.stop();
if (fc != null){
fc.close();
}
String killScrcpyCmd = String.format("ffmpeg -f h264 -i %s.h264 -y -vcodec copy %s.mp4", videoName,videoName);
Terminal.execute(killScrcpyCmd);
try {
// 等待視訊寫入完成,最多等3min
countDownLatch.await(3, TimeUnit.MINUTES);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
FileUtils.deleteQuietly(new File(videoName+H264));
log.info("[{}]video: {} recording complete", mobileId, videoName);
isRecording = false;
return new File(videoName+MP4);
}
}
AndroidDevice類代碼如下(示例):
@Override
public void startRecordingScreen() {
if (canUseAppiumRecordVideo) {
try {
AndroidStartScreenRecordingOptions androidOptions = new AndroidStartScreenRecordingOptions();
// Since Appium 1.8.2 the time limit can be up to 1800 seconds (30 minutes).
androidOptions.withTimeLimit(Duration.ofMinutes(30));
androidOptions.withBitRate(Integer.parseInt(App.getProperty("androidRecordVideoBitRate")) * 1000000); // default 4000000
((AndroidDriver) driver).startRecordingScreen(androidOptions);
return;
} catch (Exception e) {
log.warn("[{}]無法使用appium錄制視訊", getId(), e);
canUseAppiumRecordVideo = false;
}
}
if (scrcpyVideoRecorder == null) {
scrcpyVideoRecorder = new ScrcpyVideoRecorder(getId(),this);
}
try {
scrcpyVideoRecorder.start();
}catch (Exception e){
log.warn("[{}]無法使用scrcpy錄制視訊", getId(), e);
}
}
修改以上兩個類後,agent端不需要安裝scrcpy,windows也支援錄制視訊