最近研究了一段时间 hypium 和一些 devecho 开发工具的 jar 包,各种反编译,逆向啥的,找了一些方案,大概整理下。
现在可以找到的:
deveco testing 的投屏工具,使用 uitest 命令加载一个 so,名字叫 “libscrcpy_server.z.so”。
1、执行命令:/system/bin/uitest start-daemon singleness --extension-name libscreen_recorder.z.so -p 5001 -m 1,这句命令大概就是在 5001 开放一个 grpc 服务。
2、按接口定义 proto 获取数据,看了下投屏工具的使用效果,我猜测大概率是在疯狂截图,然后 h5 渲染的图片,事件转发用的 uiinput,用起来很卡顿。
观察到上面的效果,我看名字既然包含 scrcpy,那我是不是可以尝试安卓 scrcpy 的路子,安卓的路子大概这样:
1、使用系统反射获取屏幕,编码为 h264 流,开一个 socket 服务,把码流丢到这个 socket 服务上
2、客户端查看的时候,接收 socket 的码流,解码渲染
3、这种流畅度比截图要高出不少,应为只发送变化的部分,单位时间内发送的数据少很多
4、然后第一步是用 Java 实现,做成安卓虚拟机支持的可执行文件格式:dex,使用 app_process 执行
于是,我在鸿蒙一番探索,首先是不走 app 的方式,因为这种方式最方便,我尝试了 2 个路子:
1、C、C++ 编译可执行文件,因为 HM-next 本身支持 native 开发和 ts(js)开发,一顿操作猛如虎,一上真机运行不了,提示没权限(这里可能有人说你没 chmod 777,别说了,我试过了),模拟器可以执行
2、ts 之路,这个路子试过了,ts 可以编译为 abc(可以类比于为 dex 文件),但是鸿蒙上没有执行这个文件的命令。。。
结论:眼看着这路子不通,只能绕弯了,我只能想个不用 app 的办法
思路如下:
1、既然反射、内部 api 啥的走不通,那暂时只能用截图(鸿蒙内置 2 个截图:snapshot_display 和 uitest screenCap,前者效率比后者搞很多)
2、文件传输通道:走 pipe 通道,就是先截图、然后编码为 base64
3、h5 渲染,img 标签渲染
4、h5 获取用户事件,转发给设备(uiinput 命令)
有人说,你这个和 devecho testing 不是一样么,一不一样我不知道,但是我只知道,我比他稍微流畅那么一丢丢。因为原生能力不行,所以只能策略来凑,比如我想到以下 magic:
1、首先截图方式:前面说了系统内置 2 个截图命令,snapshot_display 和 uitest screenCap,根据我 10W 次测试情况看,snapshot_display 效率高,所以截图用这个
2、图片截图分辨率,没必要或者原屏幕分辨率,可以缩到原来的 30~40%,这样传输的文件大小由原来的 100+kb 就缩小到 10+kb,理论上可以提高帧率
3、截图拉取的方式,没必要拉到本地,可以直接在机器上转换为 base64 直接走 pipe 获取
4、在电脑(客户端)上渲染,可以考虑一些高效率的解码渲染方式,不用 h5
以上就是 4 个优化小妙招,有兴趣的可以一块折腾。