搭建stf+minicap实现安卓群控

版权声明:如需转载请注明出处 https://blog.csdn.net/zhonglunshun/article/details/80831537

网上找了很多的文章,关于怎么搭建stf的,有很多文章只是简单的粘贴复制抖机灵,我猜作者自己也没有搞成功;所以我特开一贴,从小白开始教大家怎么样利用stf+minicap做手机的群控,这里使用的linux内核ubantu作为客户端,使用安卓手机作为服务端;

首先声明一下我的环境,本机是全新的机器,安装了win7 64位的旗舰版系统;同时在上面通过vmBox安装了一个ubantu的虚拟机,所以适用于绝大部分的读者;

这篇文章主要是从两个部分带领大家搭建一下环境:

  1. 使用Windows编译minicap的so文件;
  2. 将so文件安装到nexus设备并运行;
  3. 搭建stf客户端环境;
  4. 运行客户端的浏览器,查看效果并操作;

编译并运行minicap

1. 下载minicap源码
安装git后,选一个目录裙房minicap源码(不要有中文):

D:\Android\project>git clone https://github.com/openstf/minicap.git
D:\Android\project>cd minicap
D:\Android\project\minicap>git submodule init
D:\Android\project\minicap>git submodule update

下载并配置Ndk-build环境变量,连上手机,获取到手机的abi:

>adb shell getprop ro.product.cpu.abi

我这里获取到的是armeabi-v7a;

2. minicap源码编译

>ndk-build.cmd APP_PLATFORM=android-25 APP_ABI=armeabi-v7a

(android-25根据你的手机指定)执行完毕后,在libs/armeabi-v7a下会生成minicap、minicap.so、minicap-nopie三个文件,实际用到的只有minicap,这里生成的minicap.so是一个空实现。我们把minicap和minicap.so推到设备的/data/local/tmp目录;

>adb push libs\armeabi-v7a\minicap /data/local/tmp
>adb push libs\armeabi-v7a\minicap.so /data/local/tmp

3. 更改权限
由于我们是在windows下面编译的,文件是没有linux文件系统的运行权限的,所以需要赋予运行权限:

>adb shell chmod 777 /data/local/tmp/minicap
>adb shell chmod 777 /data/local/tmp/minicap.so

4. 端口映射
然后,使用adb工具进行端口映射,将服务端的端口映射到1717:

>adb forward tcp:1717 localabstract:minicap

5. 拿到手机分辨率并启动服务端

>adb shell wm size

Physical size: 1080x1920,这里得到我的手机屏幕分辨率是768x1280,可以启动服务端了,这里设置了LD_LIBRARY_PATH环境变量、不然会找不到minicap.so库:

>adb shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P 768x1280@768x1280/0

到这里编译并运行minicap就完成了;接下来搭建客户端并通过客户端访问这个服务器;

搭建STF客户端并运行

1. 安装stf
网上有两种安装方式,一种是使用原生的,需要安装很多依赖,一种是使用docker的,我没有搞成功过;
最后我使用了一种很轻松的方式:
https://github.com/thinkhy/deploy-stf-docker
这是github上面的大牛搞得脚本,省略了我们很多的时间;

2. 运行stf
先启动一个数据库

docker run -d --name rethinkdb -v /srv/rethinkdb:/data --net host rethinkdb rethinkdb --bind all --cache-size 8192 --http-port 8090

再启动adb service

docker run -d --name adbd --privileged -v /dev/bus/usb:/dev/bus/usb --net host sorccu/adb:latest

再启动stf 启动的时配置的IP地址为你虚拟机桥接的网址 enp0s3

docker run -d --name stf --net host openstf/stf stf local --public-ip 192.168.1.100

3. 错误排除
在启动的过程中或者使用脚本一键安装过程会出现红色的错误,大概是说删不掉containers,这种情况下,使用docker stop [容器名称],然后使用docker rm [容器名称]把这个容器删除,然后重新启动;

4.查看app下的源码
如果我们要修改stf里面额源码进行二次开发,openstf/stf镜像中的代码全部在/app文件夹,用下面的命令可以进入docker镜像中查看文件:

docker run --rm -it --user root openstf/stf /bin/bash

修改stf的源码,优化网络传输效率

修改stream.js源码(stf/lib/units/device/plugins/screen/stream.js):
我们看到229行有这么一段:

  FrameProducer.prototype._startService = function() {
      log.info('Launching screen service')
      return minicap.run(util.format(
          '-S -Q %d -P %s'
        , options.screenJpegQuality
        , this.frameConfig.toString()
        ))
        .timeout(10000)
    }

通过查阅官方代码发现这里的-Q参数可以调整minicap抓取的图片质量
再看下这个- Q参数的默认值,在stream.js 的启动函数找到了,如果没有人为设置这里的默认值是80,也就是说原始图片质量的80%

修改lib/cli/device/index.js:下的screen-jpeg-quality:

.option('screen-jpeg-quality', {
      describe: 'The JPG quality to use for the screen.'
    , type: 'number'
    , default: process.env.SCREEN_JPEG_QUALITY || 50//Larson modify 80 to 50
    })

还有lib/cli/provider/index.js:下的screen-jpeg-quality:

.option('screen-jpeg-quality', {
      describe: 'The JPG quality to use for the screen.'
    , type: 'number'
    , default: process.env.SCREEN_JPEG_QUALITY || 50 //Larson modify 80 to 50
    })

相对来说还是不够理想。如果再降低图片质量就不太合适,只能通过降低图片数量来继续降低总的流量了。继续研究stream.js 最终找到了减少传输帧数的方法:在websocket的ws会话发送图片二进制数据到web端时丢弃1/3的数据,修改方式如下:(修改lib/units/device/plugins/screen/stream.js:)

 function send(message, options) {
            return new Promise(function(resolve, reject) {
              switch (ws.readyState) {
              case WebSocket.OPENING:
                // This should never happen.
                log.warn('Unable to send to OPENING client "%s"', id)
                break
              case WebSocket.OPEN:
                // This is what SHOULD happen.
                //----------------larson addbelow---------------
                index++
                if(index%4==0)
                {
                break
                }
                //--------------larson add above--------------------
                ws.send(message, options, function(err) {
                  return err ? reject(err) : resolve()
                })
                break
              case WebSocket.CLOSING:
                // Ok, a 'close' event should remove the client from the set
                // soon.
                break
              case WebSocket.CLOSED:
                // This should never happen.
                log.warn('Unable to send to CLOSED client "%s"', id)
                clearInterval(pingTimer)
                broadcastSet.remove(id)
                break
              }
            })

通过降低帧数数据流量从692KB/s降低到了468KB/s,实际使用中降低帧数后的体验并没有相差很远,因为工作在PC 端的浏览器上17帧的刷新屏幕也是够流畅了。

还有一种方式搭建stf:
https://blog.csdn.net/gzh0222/article/details/47146211

猜你喜欢

转载自blog.csdn.net/zhonglunshun/article/details/80831537
STF