scrcpy 为什么不能常亮

scrcpy wifi连接无法常亮

我自己开发软件发现无法常亮,这样子用起来就非常不方便,然后我研究了scrcpy,他虽然有一个--stayway on 的命令,但我发现这个只有连接usb才会保持常亮。

过程

  1. 分析Scrcpy 只是设置setting 手机属性而已,电源管理设置而已,但如果用wifi没有效果了,因为我没有充电,但这样子如果我挂机软件或者游戏感觉用起来就不方便了。
  2. 我发现anlink可以做到。

分析anlink

我猜测他用什么adb命令,我懒的逆向分析,直接用火绒剑分析进程行为,我发现他使用了命令

adb shell input keyevent mouse

我找了半天mouse,也没有找到这个按键值,然后我看google input.java的 源代码也没有这个有关的知识,然后我猜测就是未知值,那么我直接adb shell input keyevent 0 不就可以了吗?于是我在代码构建按键,而不是用adb命令模式,每隔10秒发送一个未知按键,未知按键就是0,这个是android 代码里面定义的,这样子就实现屏幕常亮。。。这个操作不管什么类型的手机都能常亮,因为都一直在按键。

额外发现

我突然发现如果间隔50毫秒发送未知按键就导致我的手机无法锁屏,这个逻辑结合屏幕关闭,就可以导致用户无法操作手机。。。。。。 有点无敌啊。。。所以以后普通用户千万不要授权APP 具备ADB命令,现在手机可以直接wifi adb, 不需要连接,这样子就可能出现木马,强制控制手机行为了。。。。。
安全手机不要开启开发者模式,否则带来很大危险。

scrcpy 源代码渲染逻辑整理

背景

自己学习scrcpy自己写的协同工具遇到了一些问题,所以分析了一下源代码,结果我出现的问题只是参数搞错了。

分析

  1. stream.c
    a. run_stream 创建线程,不停读取数据,然后投递接受的packet,然后投递数据
    b. stream_parse 解析收到数据packet
    c. push_packet_to_sinks 投递数据到
  2. decoder.c
    a. decoder_init 注册解码函数
    b. decoder_push 解析推过来的packet
    c. push_frame_to_sinks 推送得到frame 数据帧
  3. screen.c
    a. sc_screen_init 创建窗口
    b. 绑定frame处理函数
    c. sc_screen_frame_sink_push 投递从decoder解码的数据
  4. video_buffer.c
    a. sc_video_buffer_init 主要初始化队列和一些信号量
    b. sc_video_buffer_start 创建线程,不停读取队列,
    c. run_buffering 不停读取队列帧,判断是否超时,然后进行投递。sc_video_buffer_on_new_frame 通过这个回调到sceen.c 对象里面。
  5. screen.c
    a. sc_video_buffer_on_new_frame 通过 SDL_PushEvent 获取当前数据的

    总结


    这种c代码看起来还是很爽,几个对象抽象挺好,我自己写代码只封装解码层,网络层,SDL处理层,事件通知层。
    scrcpy 队列我没有感受他的好处,开始因为我的卡是没有这个帧的队列,后面发现,根本不是这么一会事情,事情情况渲染速度远远大于传送网络传送过来帧,我自己也实现一个简单队列,检测到帧堆积,直接丢弃,只显示最新的帧,结果从来就没有丢弃。
    scrcpy app 最核心SurfaceControl 反射实现,其他的模拟可以借鉴adb 命令实现代码实现,不过这个SurfaceControl 有人分析android 核心代码可以找到实现,但我自己看了一下貌似没有看懂,直接就拿scrcpy反射实现,其他几个控制命令都是我自己实现,更加简单明了,它是实现几个点击滚动太过于复杂了。

format.setInteger(MediaFormat.KEY_FRAME_RATE, 60);

这个代表帧率,这个Scrcpy其实动态的,这个跟延迟有一定关系,但我之前设置错参数出现反复点击一个表情会出现延迟,然后把这个设置120就延迟了,手机FPS是60.

format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, REPEAT_FRAME_DELAY_US); // µs

这个影响到延迟的,这个给我感觉保持一直采集有数据,之前就是我把这个设置错了,导致快速点击输入表情时候会出现明显的延迟。

format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
这个跟画面清晰度有关系,类似直播高清,蓝光4M 这些。

会删除掉复制tmp的jar包

我开始到目录找了好久,没有好到文件,但命令确实复制到tmp

我不知道scrcpy 用OS.write 有什么好处,我直接用websocket通信,也不走转发,我自己用Websocket跑的时候效果差不多,协议直接用JSON格式就可以了,也不用字节解析,视频流原始传递,这个才是消耗流量的地方,控制的消耗不了多少流量。

scrcpy 我觉得待补充的功能

  • 蓝牙【貌似分支有了】
  • 远程控制【我自己目前这种模式就可以支持远程,我目的就是远程控制手机】
  • 后台运行 【提供增强功能,可以给APP使用,市面已经这样子APP】
  • 输入法增强 【我不知道目前这个实现了没有】
  • 控制栏 【我自己用win32 实现了,感受最原始界面开发】
  • 鼠标点击录制【用来做脚本,结合辅助服务最好,不知道能不能直接反射使用,开启辅助是可以做到】,这个只要做到基本就是无敌了软件。
  • 鼠标模拟增强 【目前鼠标的模拟,如果玩游戏可以检测出来,应该跟属性有关系,这种要做专门优化】

自己开发的软件应该远程控制+手机增强功能,给自己开发用的软件。

app process 其实能做很多东西,
以后想到什么再补充吧。