STF STF 工具之 minicap-补充

songzx · March 22, 2017 · Last by songzx replied at December 19, 2019 · 6248 hits

minicap

minicap 是开源项目 STF 中的高速截图工具。STF利用此工具不断的传输图片信息并在web端绘制实现 Real-time screen view。

minicap使用

  1. 将 minicap 所需的文件 "minicap" 和 "minicap.so" push至手机中
  2. 启动 minicap,映射一个端口用来获取 minicap 数据
  3. 获取 minicap 的数据并进行解析处理

一、push文件至手机中

minicap 的使用有很强的针对性,针对不同架构的CPU和SDK制作了不同的 "minicap" 和 "minicap.so" 文件。

获取CPU版本

$ABI=adb shell getprop ro.product.cpu.abi

获取SDK版本

$SDK=adb shell getprop ro.build.version.sdk

push文件(红色字体为minicap项目路径,具体依个人情况而定)

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

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

二、启动minicap

检查minicap是否可用

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

若在结果中包含 "OK" 字样则表示可用

-P 后面的参数格式:{RealWidth}x{RealHeight}@{VirtualWidth}x{VirtualHeight}/{Orientation}

Orientation可以理解为手机的旋转角度,可选参数为 0 | 90 | 180 | 270

如何获取Orientation

  1. 利用命令 adb shell dumpsys display(win下grep更换为findstr)获取分辨率 和 rotation方向(adb 一般获取到为0 or 1)(同学们自己动手做一次文件差异对比就知道用什么参数了)
  2. 官方提供的方法(传送门) 首先编译出app(不管win还是linux不要忘记参数'assembleDebug'),安装后就可以启动一个service,该services可以返回手机当前的方向。该app已集成在STFService.apk中,使用请参考文档

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

此时相当于启动了一个socket服务端。然后设置下访问端口adb forward tcp:1313 localabstract:minicap(其意思是将pc上的端口1313重定向至手机上的minicap)然后就可以通过 1313 端口来获取minicap不断发出来的信息了。

三、minicap数据解析

minicap 会不断的返回很多二进制信息,这些二进制信息代表什么意思?

其返回的信息可以分为两类Global header binary formatFrame binary format(以下简称为 Banner 和 Frame), 其数据格式如下:

每次客户端连接 minicap 服务时,最先收到的24字节为 Banner 数据段(该数据段只会在最开始发送一次)。
然后接收到的数据可视为 N个Frame 数据段,Frame数据的前4个字节为 Frame 中 JPG 数据的长度,其后为JPG内容数据。

官方示例

(注:官方示例的数据处理方法是建立在收到的二进制数据以16进制形式表现的情况下)

根据使用者解析语言不同还需要注意大小端存储的问题

数据解析思路:

  • 解析Banner
  • 计算JPG数据长度
  • 获取JPG数据-操作JPG数据
tempdata //保存还没有被处理的数据
framehead //保存fram的前4个字节
framejpg  //保存frame中jpg数据
jpglength //JPG数据长度

for {
  minicapread(data)
}

function minicapread(data) {
  data = append(tempdata,data)

  // ------------Banner start------------
  if banner not ok{
    if data length >= 24{
      getBanner(data)
      data = data - Banner // 减去banner长度余下的数据
    }else{
      tempdata = data
      return
    }
  }
  // ------------Banner end------------
  
  // ------------JPG length start------------
  if framhead length < 4{
    if data length >= (framehead length - 4) {
      framehead = getHead(data)
      jpglength = getJpgLength(framhead) 
      data = data - framehead
    }else{
      framehead = append(framehead,data)
      return
    }
  }
  // ------------JPG length end------------

  // ------------JPG start------------
  if framejpg length < jpglength{
    if data length >= (jpglength - framejpg length){
      framjpg = getJpg(data)
      data = data - framejpg
    }else{
      framejpg = append(framejpg,data)
      return
    }
  }
  // ------------JPG end------------
  
  tempdata = append(tempdata,data)
}

minicap获取数据与Orientation的联系

假设分辨率为 1080x1920, 以 左上角为0,0坐标

当屏幕为竖屏显示时以Orientation=0 启动minicap服务,此时我们会得到正常的宽高为1080x1920的截图。

若翻转手机为横屏显示数据时,依然得到宽高为1080x1920的截图且高度在1080以上时的部分为黑色填充。只有关闭minicap以Orientation=90重新启动,可以获取到宽高为1920x1080的正常截图。

也就是说想要实时正确获取屏幕显示,要监控屏幕方向,并以新的方向重启minicap服务。(可查看STF的输出日志)

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 4 条回复 时间 点赞

STFService.apk 这个东西具体 ,如何使用 你这边有研究吗?

一秒钟最多可以传多少帧这个有说明吗

怎么停止minicap 进程然后重新启动呢

Marlon992058 回复

minicap 是push到手机中使用,android 系统你可以认为是阉割版本的linux,所以你看到它在使用时命令是已 adb shell 开头的。所以你关闭它可以按linux的方式来,1. 查找minicap进程 ps -ef | grep minicap 2.查看进程id 3. kill xxxx 。

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up