• python+minicap的使用


    说起Minicap,不得不提到STF,STF (Smartphone Test Farm) 是一个开源的web架构应用,用户可通过浏览器远程操作Android设备、调试Android应用、在设备上进行测试,实现真正意义云端使用、调试、测试、管理真机器。STF出现以后,国内几个大互联网公司也纷纷跟进效仿,出现了类似的真机调试、管理平台,较为知名的有腾讯Wetest、阿里MQC、百度MTCTestIn等。可见远程真机调试在移动研发领域的作用还是受到了比较高的重视,也能为公司以及用户带来比较直接的收益。下面是STF官方的介绍动画。

     
    STF

    minicap简介

    minicap属于STF框架的一个工具,由STF团队自身开发,属于较为核心的一部分,minicap运行于android设备端,负责设备屏幕视频的实时采集并通过socket接口发送,github下载地址:https://github.com/openstf/minicapmicicap。minicap采集屏幕的原理很简单:通过ndk的截屏接口不停的截屏并通过socket接口实时发送,这样客户端便可以得到一序列的图片流,图片流合成后就成为视频;

    构建minicap

    micicap由Android ndk开发,包含一个可执行的二进制文件以及一个so文件,运行minicap前,需要通过adb命令将设备对应CPU架构以及设备对应SDK版本的minicap文件拷贝到设备后,再执行。由于github上并没有上传编译完成后的产物,因此我们需要自行编译。

    编译依赖环境:

    1)、NDK;

    2)、make;

    3)、git;

    环境依赖较为简单,如果没有NDK以及make环境的,可自行百度安装;

    构建过程:

    1)、通过git下载minicamp源码:

    git clone https://github.com/openstf/minicap.git

    2)、micicap项目还依赖于libjpeg-turbo,首先我们需要在minicap引入libjpeg-turbo项目源码:

    git submodule init

    git submodule update

     
     

    3)、执行ndk-build,构建完成后,minicap编译后的产物将会在libs目录下找到;

    ndk-build

     
     

    运行minicap

    1)、获取设备CPU支持的ABI,minicap针对4种不同的ABI构建了不同的so文件和可执行文件,分别是:x86_64/x86/arm64-v8a/armeabi-v7a;

    ABI=$(adb shell getprop ro.product.cpu.abi|tr -d' ')

    2)、拷贝对应ABI版本的文件到设备,这里使用的是adb push;

    adb push libs/$ABI/minicap /data/local/tmp/

    3)、获取设备对应的SDK版本;

    SDK=$(adb shell getprop ro.build.version.sdk|tr -d' ')

    4)、只有可执行文件是不够的,我们还需要拷贝对应sdk版本的共享库到设备;

    adb push jni/minicap-shared/aosp/libs/android-$SDK/$ABI/minicap.so /data/local/tmp/

    5)、每次启动minicap,我们都需要设置LD_LIBRARY_PATH,不然会提示找不到公共库,-P后面的参数为:{RealWidth}x{RealHeight}@{VirtualWidth}x{VirtualHeight}/{Orientation},可以指定采集的实际大小、虚拟大小以及屏幕方向,实际大小一般设置成设备物理分辨率大小,虚拟大小是通过socket接口发送的大小,屏幕实际窗口大小我们可以通过adb命令获取;

    adb shell dumpsys window | grep -Eo 'init=d+xd+' | head -1 | cut -d= -f 2

    6)、启动minicap,下面我们假设获取到的实际屏幕大小是1080x1920,需要发送的虚拟窗口大小是540x960,采集的屏幕方向是纵向;

    adb shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P 1080x1920@1080x1920/0

    7)、端口转发,通过adb forward命令,可以把minicap端口映射到我们PC指定的端口,localabstract:minicap是UNIX域名的SOCKET名称,把minicap的socket端口映射到PC的1313端口,这样我们就可以在PC通过连接1313端口获取到设备的实时视频流;

    adb forward tcp:1313 localabstract:minicap

    minicap协议解析

    minicap启动并用adb forward命令映射端口后,我们就可以通过socket与minicap建立连接。

    1)、Global header

    minicap协议是一种简单的二进制流推送流协议,一旦与minicap建立连接,minicap首先会推送长度为24字节的global header,global header只会推送一次,后续推送的数据不会再包括global header,而是不断的推送实时图片流数据,直到客户端关闭socket连接。

     
    Global header binary format

    Global header说包含了基本的一些信息,如minicap的版本信息、头长度、实际大小以及虚拟大小、设备方向等,这些信息我们可以保存起来,方便后面使用,这里我使用python解析了Global header,代码参考如下:

     
     

    2)、Frame binary format

    接下来,minicap会不断的推送一帧一帧的图片流,每一帧都包含两部分信息:0-3字节,表示这一帧图片的长度n,由4个字节的32位整型小端格式存储;4-(n+4)字节,是具体的图片数据,由JPG格式存储,这部分才是我们想要的最关键数据;

     
    Frame binary format
     
     

    至此,我们完成了minicap协议的解析,并获取到了minicap推送过来的每一帧图片。需要注意的是,由于minicap是实时推送流,因此流的数据可能会比较大,客户端获取的buffer需要尽可能的大,不然我们在渲染每一帧的时候,可能会出现卡顿的现象,具体多大合适,我们可以稍微推算一下,一张由minicap推送过来的1080x1920大小的png图片,大概是100-200KB,minicap宣称帧率可以达到20 FPS左右,因此我们的buffer可以设置为:200KB * 20 = 4096000字节,每隔一秒recv()一次;

    PyQt实时渲染

    获取到图片流数据后,我们可以使用PyQt中的paintEvent进行渲染,下面的refreshFrame()方法,关联了获取图片线程中的一个信号槽,一旦获取图片线程从minicap解析到一帧的图片,便会通知refreshFrame()中的self.update()方法,self.update()方法则会调用paintEvent进行界面的刷新:

     
     
     本文转载地址自:https://www.jianshu.com/p/777af34b4f21
    参考博客 https://www.cnblogs.com/xiand/p/6724399.html
  • 相关阅读:
    java笔记之输入输出流
    英文单词个数统计及排序
    课后作业_程序员修炼之道读后感
    第五周-内网穿透简易搭建(远程查看javaweb程序)
    第五周总结
    结对开发
    第四周学习总结
    第四周--爬虫的学习
    第四周学习总结
    第三周---------学习动态规划
  • 原文地址:https://www.cnblogs.com/qiangayz/p/9580389.html
Copyright © 2020-2023  润新知