天天看點

解決opendx在windows下無法使用scrcpy錄屏前言一、解決的問題二、使用步驟

文章目錄

  • 前言
  • 一、解決的問題
  • 二、使用步驟
    • 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也支援錄制視訊