zoukankan      html  css  js  c++  java
  • Python移动端录屏库

    Python移动端录屏库

    背景

    日常移动端专项测试和自动化测试通常有一些场景如:Ui自动化的操作捕获、App启动耗时、视频启播耗时等,通常都有需要边操作边录屏,而对于启动耗时测试通常还需要质量较高且帧率稳定的视频源(如果用stagesepx),本文将介绍双端基于脚本化的录屏解决方案,让录屏更好的和你的case结合

    概述

    它是一个python库,更准确的说是一个录屏的装饰器,名为screcord,意为:screen + record,底层是对scrcpyxrecord调用的极简封装

    PyPI version

    scrcpy和xrecord

    因为screcord底层是对scrcpyxrecord调用,故在正式介绍之前先梳理一下目前双端现有的录屏方案

    安卓端

    方案 自动化控制 兼容性 视频源质量
    自带录屏功能 较好
    录屏软件 较差
    screenrecord 部分机型没有 一般
    scrcpy 可选

    iOS端

    方案 自动化控制 兼容性 视频源质量
    自带录屏功能
    录屏软件 较差
    xrecord

    从以上的对比中可以看出:

    • scrcpy 实际是一款开源、跨平台的安卓投屏和控制工具,且可以通过命令行控制
    • xrecord 是一款开源的iOS端可命令行控制的录屏工具

    原理

    录屏原理

    当你正确安装了scrcpy之后,只需要输入如下命令,即可录取指定设备的屏幕

    scrcpy -s device --render-expired-frames -Nr ./demo.pm4
    
    --render-expired-frames:尽可能最大帧率
    -N:不再PC端展示
    -r:录制mp4/mkv文件
    

    iOS端,下载xrecord并通过alias指定xrecord到对应的文件路径

    alias xrecord='./xrecord/bin/xrecord'
    xrecord -q -i device -o ./demo.mp4 -f
    
    -i, --id:
          Device ID.
    -o, --out:
          Output File.
    -f, --force:
          Overwrite existing files.
    -q, --quicktime:
          Include QuickTime devices (necessary for iOS recording).
    

    screcord的封装原理

    知道了scrcpy和xrecord的录屏原理之后,就可以通过脚本封装实现了,原理为:

    • 通过_cmd区分平台拼接录屏命令行
    • record装饰器中通过subprocess.Popen()启动任务
    • 当case执行完毕后再调用proc.terminate()结束任务
    # record装饰器
    def record(
            platform: typing.Union[str],
            device: typing.Union[str],
            file_path: typing.Union[str, os.PathLike],
            offset: typing.Tuple[int] = (1, 1),
            pre_kill: typing.Union[bool] = True
    ):
        """record wrapper
    
        platform: 'a', 'android', 'i', 'ios'
        device: android device id or iOS udid
        file_path: mp4 file path
        offset: default (1, 1), mean of: before record sleep 1s and after record sleep 1s
        pre_kill: before start whether kill or not, default True
        """
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                ofs = _update_offset(offset)
                proc_name, cmd = _cmd(platform, device=device, fp=file_path)
                p = start(proc_name, cmd, pre_kill)
                try:
                    time.sleep(ofs[0])
                    func(*args, **kwargs)
                    time.sleep(ofs[1])
                except Exception as e:
                    logger.error(e)
                finally:
                    stop(proc_name, p)
            return wrapper
        return decorator
    

    _cmd()可以看到,它是通过platform来区分平台,再通过传入的device, file_path拼接成为cmd

    # _cmd,双端录屏命令行拼接方法
    def _cmd(platform: str, **kwargs):
        """build cmd according to platform
        """
        platform = platform.lower()
        assert platform in ('a', 'android', 'i', 'ios'), f"platform should in ('a', 'android', 'i', 'ios')"
        if platform in ('a', 'android'):
            cmd = 'scrcpy -s "{device}" --render-expired-frames -Nr "{fp}"'.format(**kwargs)
            proc_name = 'scrcpy'
        else:
            kwargs['xrecord'] = os.path.join(
                os.path.dirname(screcord.__file__), 'xrecord'
            )
            cmd = '"{xrecord}" -q -i="{device}" -o="{fp}" -f'.format(**kwargs)
            proc_name = 'xrecord'
        logger.info(
            f'
    ===== CMD INFO ====='
            f'
    platform: {platform}'
            f'
    name: {proc_name}'
            f'
    cmd: {cmd}'
            f'
    ===================='
        )
        return proc_name, cmd
    

    使用

    首先,安装screcord库,要求py3.6+

    pip3 install screcord
    

    在case的方法上引入record这个装饰器即可

    record 方法入参格式如下:

    • platform - 安卓/iOS可缩写为:a/i
    • file_path - 录屏视频的文件路径,建议mp4格式
    • offset - 偏移量,tuple类型,表示录屏开始后,在case开始前等待几秒,case执行完等待几秒,通常用于case前后的等待缓冲期
    • pre_kill - 在开始录屏前是否需要kill掉已有的进程
    from screcord import record
    
    # 安卓端
    device = "xxxxx"
    video_fp = "./demo.mp4"
    @record('android', device, video_fp, offset=(1, 2))
    def start_app():
        # your case
        ......
        
    # iOS端
    device = "xxxxx"
    video_fp = "./demo.mp4"
    @record('ios', self.device, video_fp, offset=(1, 1), pre_kill=False)
    def start_app():
        # your case
        ......
    

    值得注意的是:

    • iOS端已经将xrecord纳入screcord库,故无需再单独安装
    • 因为scrcpy同意时刻只允许一个进程运行,所以安卓端建议将pre_kill置为True
    • iOS端建议将pre_kill置为False,因为每次启动xrecord时候都会重连设备,这会导致WDA服务中断

    github

    https://github.com/ssfanli/screcord

    积跬步,至千里
  • 相关阅读:
    macOS 终端可用的 Hex 查看与编辑器
    MAC brew install 跳过 update
    zstd
    JAVA中的时区设置
    conda虚拟环境中设置环境变量
    vertx 获取请求参数
    idea2020.3激活码最新破解教程(亲测有效)
    Camtasia recorder 的快捷键
    ARM STM32 各种缩写和全称
    如何解决keil mdk中文汉字乱码或设置编码问题
  • 原文地址:https://www.cnblogs.com/freedomlidi/p/13199790.html
Copyright © 2011-2022 走看看