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

    积跬步,至千里
  • 相关阅读:
    dubbo入门(一)
    java中文件操作《一》
    Unity 游戏框架搭建 2019 (七) 自定义快捷键
    凉鞋:我所理解的框架 【Unity 游戏框架搭建】
    Unity 游戏框架搭建 2019 (六) MenuItem 复用
    Unity 游戏框架搭建 2019 (五) 打开所在文件夹
    Unity 游戏框架搭建 2019 (四) 导出 UnityPackage
    Unity 游戏框架搭建 2019 (三) 生成文件名到剪切板
    Unity 游戏框架搭建 2019 (二) 文本复制到剪切板
    Unity 游戏框架搭建 2019 (一) 简介与第一个示例文件名的生成
  • 原文地址:https://www.cnblogs.com/freedomlidi/p/13199790.html
Copyright © 2011-2022 走看看