三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

一台电脑远程操控鸿蒙真机:HOScrcpy 投屏工具从零上手实战,附 5 个避坑点

一台电脑远程操控鸿蒙真机:HOScrcpy 投屏工具从零上手实战,附 5 个避坑点

一台电脑远程操控鸿蒙真机:HOScrcpy 投屏工具从零上手实战,附 5 个避坑点

【免费下载链接】鸿蒙远程真机工具该工具主要提供鸿蒙系统下基于视频流的投屏功能,帧率基本持平真机帧率,达到远程真机的效果。项目地址: https://gitcode.com/OpenHarmonyToolkitsPlaza/HOScrcpy

先讲一个让我抓狂的下午

周五下班前,我把手机忘在了工位的抽屉里,而第二天要交付的鸿蒙应用 Demo 还差最后几个交互没调完。家里的备用机没有鸿蒙系统,模拟器跑不出真机的效果,那一晚我基本是在"改代码—猜想—再改"的循环里硬熬。

后来同事丢给我一个开源工具叫HOScrcpy,一句话总结它的价值:让电脑通过视频流实时看到鸿蒙设备的屏幕,并把你的点击、滑动、按键原样"送"回设备,帧率基本能跟真机持平,体验上就像真机摆在面前。用它把落在家里的手机"搬"到电脑上,我那个 Demo 半小时就调完了。

这篇文章不打算按官方文档的目录复述一遍,而是把我从"下载到跑通到玩明白"的真实过程拆给你看。你照着走一遍,大概率也能在十几分钟内让鸿蒙设备乖乖出现在电脑屏幕上。

它到底是怎么做到的?用两个比喻讲清楚

抛开技术名词,HOScrcpy 只干了两件事:

  • 屏幕直播:设备端持续把屏幕画面编码成 H.264 视频流,通过网络送到电脑端,电脑再用内置的 FFmpeg 解码器把画面渲染出来。你可以把它想象成把手机屏幕当成一个"直播间"在播。
  • 远程反控:你在电脑画面上的每一次点击、滑动、滚轮、按键,都被转换成设备能听懂的指令注入回去。这相当于直播间观众不光能看,还能直接"上手"操作主播的手机。

顺带一提,HOScrcpy 还提供了网页端反控的演示(web_demo模块),也就是说只要中间有一层 WebSocket 转发,浏览器也能变成一块"远程屏幕"。下图是整个能力的概览,核心就是屏幕码流采集 + 实时 GUI 反控两条链路。

拿到手第一件事:把环境凑齐

先别急着 clone 代码,把下面四样东西确认好,能省掉后面一半的报错:

  1. JDK 8 或更高版本,并配置好JAVA_HOME环境变量(注意:值不要带bin目录);
  2. Maven(如果你打算用命令行构建);
  3. HDC 命令行工具,这是鸿蒙设备调试的"翻译官",HOScrcpy 靠它发现设备、执行按键命令;
  4. 一台开启开发者选项和 USB 调试的鸿蒙设备。

都齐了,再去拿源码:

git clone https://gitcode.com/OpenHarmonyToolkitsPlaza/HOScrcpy.git cd HOScrcpy

构建这一步,藏着两个最容易踩的坑

官方 README 推荐的是在 IntelliJ IDEA 里通过"工件(Artifact)"方式打包,产物会生成到项目的out目录下。如果你用的是 IDE,照下面三步走:

  1. 打开项目设置,新增一个JAR 工件,主类选Main,类型选"从具有依赖项的模块构建";
  2. 在工件配置里确认输出目录和依赖库都被收进 JAR,就像下图这样;
  3. 点击构建,等待产物出现在out/artifacts/HOScrpy_jar文件夹里。

构建完成后,out/artifacts/HOScrpy_jar下会躺着一堆 JAR——除了主程序,还有 FFmpeg、JSON 解析等依赖库,使用时这一整个文件夹的 JAR 都要保留,别只拷走一个主包。

两个坑提前给你排掉:

  • 坑一:Mac 上构建会失败。原因是 FFmpeg 的依赖默认带了windows-x86_64的分类器,Mac 用户需要去pom.xml里把这个依赖的<classifier>改成macosx-x86_64,然后重新构建。
  • 坑二:主类入口别记错。启动命令不是简单的java -jar,官方给的是java -jar HOScrcpy.jar -cp Main。第一次启动时界面可能看起来"空空的",别慌,先点"刷新设备"。

第一次连接:从"刷新"到"看到画面"的完整流程

启动程序后你会看到一个主界面,左侧是投屏画面区域,顶部有设备下拉框和"刷新设备""进入投屏"按钮,右侧则是电源键、音量加减、返回键这一排控制按钮。这张截图就是工具实际运行时的样子:

连接四步走:

  1. 点击"刷新设备",工具会通过 HDC 检测本机(127.0.0.1:8710)以及你配置过的远程 IP 下所有设备,结果会填进设备下拉框;
  2. 从下拉框选中你的设备(下拉项会显示设备 SN 和在线状态);
  3. 点击**"进入投屏"**,按钮会变成"停止投屏",表示已进入投屏模式;
  4. 稍等片刻,手机屏幕就会出现在电脑窗口里。此时窗口会自动按设备分辨率的三分之一比例缩放并居中,方便你留出操作空间。

如果点了"进入投屏"却一直黑屏,按优先级排查这几件事:

现象最可能的原因怎么解决
刷新不到设备设备没开 USB 调试,或没授权设备设置里打开开发者选项和 USB 调试,留意设备上的授权弹窗
画面一直没出来手机画面静止不动,视频流没触发滑动一下手机屏幕,让画面"动起来";也可以按下电源键再点亮
提示连接失败HDC 与设备版本不匹配检查 HDC 版本,必要时按设备系统版本选择匹配的 hoscrcpy 版本

最后一条值得多说一句:hoscrcpy 的 SDK 是分版本适配系统的,老系统(3.0.0.2x 那批)用 1.0.0-beta,之后的新系统用 1.0.1 及以后版本,1.0.4 专门修过 5.0.0.71 版本无法投屏的问题。投屏不上时,先看看是不是版本选错了。

画面出来之后,能干的事比想象中多

投屏最直观的用法当然是"操作",但真正上手后你会发现几个惊喜:

基础的触摸操作——鼠标左键单击对应手指点击,按住拖动就是滑动,多点触控、长按都能映射。画面右上角还有一个小提示,第一次使用时它会引导你"点击即触摸、拖动即滑动"。

完整的鼠标支持——如果设备系统支持,你可以开启"鼠标事件"开关,右键、中键、滚轮都会注入到设备上。滚轮上下滑动还能直接替代手指在列表里的滚动,这在调试长列表页面时非常顺手。

虚拟按键——电源键、音量加减、返回键都在控制区摆着,背后其实是通过executeShellCommand发送uinput指令实现的。比如返回键对应的是uinput -K -d 2 -u 2。对开发者来说,这意味着你完全可以绕开界面,直接用这套接口写自动化脚本。

连键盘输入都支持——你可以在电脑上直接打字输入到设备,中英文都可以,粘贴(Ctrl+V)也做了支持。做表单页面调试时,这个功能能省掉大量在手机软键盘上戳字的动作。

控件树查看:给 UI 调试和自动化测试开的后门

这是我最喜欢的功能,也是很多远程投屏工具没有的。点一下"控件查看",工具会拉取当前页面的布局结构,以 JSON 形式解析成一棵控件树显示在右侧面板,同时截图画面里会用矩形框高亮你选中的控件。

你可以:

  • 在控件树里点任意节点,右侧立刻列出它的texttype、坐标范围、相对位置、点击位置等属性;
  • 直接在截图上点击某个控件,工具会自动定位到树里对应的节点;
  • 用搜索框按关键字(支持模糊匹配)搜控件,配合"上一个/下一个"按钮在结果间跳转;
  • 通过"菜单 → 导入 Layout / 导出 Layout"把结构保存成 JSON 文件,或者把别人给的 Layout JSON 导进来回看。

对写 UI 自动化用例的人来说,这个功能的价值在于:控件的 xpath、范围、相对位置都是现成的,直接拿去写定位器就行。对普通用户来说,它也像一面"放大镜",让你一眼看清某个按钮到底是什么组件、占多大区域。

设备不够用?试试远程设备和多设备管理

开头说的"手机忘在工位上"其实还有进阶版本:如果手机在公司的机房里,你人在家,怎么办?HOScrcpy 的"菜单 → 管理远程 IP"就是为这个场景准备的。

在弹窗里添加远程设备所在机器的 IP,保存后点"刷新设备",工具就会通过hdc -s IP:8710 list targets去探测那台机器下挂载的设备。也就是说:

  • 多开发者可以共享同一台"设备服务器",谁要用谁连;
  • 你的设备列表可以同时出现本地设备 + 多个远程 IP 下的设备;
  • 切换投屏目标只需要重新选下拉框再点进入,来回切不费劲。

这一招对团队里设备资源紧张的情况特别管用,等于把"真机"变成了随时可借的公共资源。

画面卡顿?这三个旋钮帮你调

如果你的网络一般,或者对画质有更高要求,HOScrcpy 的 SDK 给了你四个可调参数(HosRemoteConfig):

  • 帧率setFrameRate:默认 120 FPS,追求流畅就保持高位,网络差就降到 30;
  • 码率setBitRate:默认 30M,可以理解为"水管粗细"——水管越粗,画面细节越清晰,但对带宽要求也越高;
  • 分辨率缩放setScale:传 2 就是取原始分辨率的二分之一,3 就是三分之一,最大支持到 5。这是最立竿见影的省流量手段;
  • I 帧间隔setIFrameInterval:默认 2000ms,调小能加快画面关键帧刷新,代价是码流变大。

我的经验是:本机 USB 连接时全默认即可;走远程网络时,先把setScale(2)打开,再看卡不卡决定要不要把帧率降到 60。别一上来就动码率,分辨率缩放通常是性价比最高的第一刀。

进阶玩法:让网页也能投屏

桌面工具用顺手之后,你会发现仓库里还藏着一个web_demo模块。它的原理很直白:本地起一个 WebSocket 服务端(MyWebSocket.java,默认端口 8899),把设备视频流转发给浏览器,同时接收浏览器端发来的触摸事件注入设备。

三步跑起来:

  1. 运行MyWebSocket.javamain方法启动服务;
  2. 打开web_demo/src/main/resources/html/h264.html,把第 31 行的设备 SN 改成你自己的;
  3. 浏览器打开这个 HTML,稍等片刻就能在网页里看到并操作手机。

一个小提示:画面静止时浏览器不会自动刷新,想看效果就滑动一下手机。这个 demo 的价值不只是"好玩"——它证明了 HOScrcpy 的 SDK 可以嵌进任意 Java 后端,把投屏能力包成 Web 服务,这对做远程运维平台、测试看板之类的场景是现成的地基。

想二次开发?SDK 其实只有三个类

如果你不想用现成界面,而是把投屏能力集成进自己的工具,SDK 的 API 非常收敛,核心就三个类(都在com.huawei.hosscrcpy.api包下):

  • HosRemoteDevice:设备对象,负责启停视频流、注入触摸/鼠标/滚轮事件、执行 shell 命令、获取布局;
  • ScreenCapCallback:视频流回调,onData拿数据流,onReady表示流就绪,onException接住错误;
  • HosRemoteConfig:配置项,上面说的帧率、码率、缩放、端口、HDC 路径都在这里设置。

一个最小可用的接入骨架长这样:

HosRemoteConfig config = new HosRemoteConfig("设备SN号"); config.setScale(2); // 分辨率取二分之一 config.setFrameRate(60); // 帧率 60 HosRemoteDevice device = new HosRemoteDevice(config); device.startCaptureScreen(new ScreenCapCallback() { @Override public void onData(ByteBuffer byteBuffer) { // 拿到 H.264 视频流,交给你的解码器渲染 } @Override public void onReady() { // 流已就绪,此时可以注入操作,比如模拟一次点击 device.onTouchDown(100, 200); device.onTouchUp(100, 200); } @Override public void onException(Throwable throwable) { // 处理失败场景 } });

这里有个容易忽略的细节:onData只有画面发生变动时才会被回调,如果设备亮屏且画面静止,你可能永远等不到第一帧。所以onReady的设计意图就是给你一个"让画面动起来"的入口——比如在里面触发一次电源键点亮,或者主动滑动一下页面。

最后,五个坑帮你提前排掉

把我这一路踩过的坑浓缩成一张速查清单,你遇到类似问题时直接对号入座:

  1. 启动没界面→ 确认用了java -jar HOScrcpy.jar -cp Main这个完整命令;
  2. 刷新不到设备→ 检查 USB 调试与授权,远程设备要先把 IP 加进"管理远程 IP";
  3. 黑屏没画面→ 先滑动手机触发画面变动,别干等;
  4. Mac 构建失败→ 去pom.xml把 FFmpeg 的 classifier 换成macosx-x86_64
  5. 老系统投屏失败→ 按系统版本回退到 1.0.0 / 1.0.1 对应的 SDK 版本。

跑通之后,不妨再想一个问题:投屏能力拿到手,你最想先做的是什么?是给团队搭一个共享真机平台,还是把控件树查看到的能力接进你的自动化框架?我在把 web_demo 接进内部测试看板时,意外发现这套链路比想象中稳。如果你也在做类似的事情,欢迎聊聊你的场景——下一篇文章,我准备写一写"如何用这套 SDK 把投屏能力封装成团队内部的远程真机服务",把这次没展开的架构细节一次讲透。

【免费下载链接】鸿蒙远程真机工具该工具主要提供鸿蒙系统下基于视频流的投屏功能,帧率基本持平真机帧率,达到远程真机的效果。项目地址: https://gitcode.com/OpenHarmonyToolkitsPlaza/HOScrcpy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表