【学习工作赛道】li Mirror 一款将手机屏幕共享到Mac的原生应用程序

个人介绍:

  • 我是一名软件产品经理,我日常主要使用 Mac,也经常遇到手机 App 演示、移动端问题复现、会议投屏、素材导出等跨设备场景;

  • 我想做 li Mirror,是因为这些看似简单的需求,现实中常常要在命令行工具、收费软件、手机端配套 App 和多套系统工具之间来回切换。我希望把复杂的底层连接封装成一个符合 macOS 使用习惯的原生应用:插上设备、识别设备、点击投屏,然后直接在 Mac 上继续操作。

  • 目前Vibe Coding不足半年

  • 一直渴望成为全栈型产品,比较擅长把需求拆成可验证的技术任务,并通过持续调试把原型打磨成可以长期使用的完整产品。希望未来能开发出更多解决实际工作的软件产品;

产品简介:

是什么

li Mirror 是一款原生 macOS 手机镜像与跨设备交互 App。

它支持 Android 和 iOS 设备通过 USB 将屏幕实时显示到 Mac;其中 Android 还支持鼠标、键盘、滚轮和触控板反向操作,并提供文件上传、下载、图片预览等能力;iOS 支持屏幕镜像和照片、视频的浏览与批量导出。

它解决的核心问题是:把原本分散在命令行投屏、系统采集、文件管理等工具中的流程,收进一个统一、低门槛的 Mac 原生界面里,同时尽量减少手机端安装和云端传输。

当前复赛版本为 v4.3

面向谁

核心用户包括:

  • 需要演示或调试 Android / iOS App 的开发者、测试工程师、产品经理;
  • 需要在会议、课堂、直播或录屏中展示手机画面的老师、讲师和内容创作者;
  • 主要使用 Mac,希望用大屏和键鼠操作 Android 手机的用户;
  • 需要在 Android 手机与 Mac 之间传输文件的用户。

典型场景包括:移动端 Bug 复现、App 功能演示、课堂讲解、手机界面录屏、图片素材整理、多设备对比测试,以及将投屏窗口置顶作为工作时的辅助屏幕。

软件特点:仅需在Mac电脑端安装软件程序,被镜像端无需安装任何App程序。实现插线即投的效果;

li Mirro完整功能:

1. Android 镜像与反向控制

  • 自动检测 USB 连接的 Android 设备并识别授权状态;
  • 手机端无需安装常驻 App,运行时通过 ADB 临时启动镜像服务;
  • H.264 视频流在 Mac 端通过 VideoToolbox 解码、Metal 渲染;
  • 支持鼠标点击、拖拽、右键、滚轮和触控板精确滚动;
  • 支持键盘文字输入、方向键、回车、退格及常用功能键映射;
  • 支持触控板双指捏合,映射为 Android 多点触控缩放;
  • 手机横竖屏切换后自动重建解码状态、更新画面比例与输入坐标;
  • 支持窗口缩放、窗口置顶、全屏和开始/停止投屏快捷键。

2. iOS 镜像与照片管理

  • 自动识别已通过 USB 连接并“信任此电脑”的 iPhone / iPad;
  • 使用 macOS 系统采集能力获取 iOS 屏幕画面,并复用 Metal 渲染链路;
  • iOS 模式专注镜像观看,不提供反向控制,避免误导用户;
  • 基于 ImageCaptureCore 浏览设备照片和视频;
  • 支持缩略图和单张预览。

3. Android 文件传输

  • 浏览手机目录并在文件夹层级间导航;
  • 将 Mac 文件拖入窗口上传到 Android;
  • 从 Android 单个或批量下载文件到 Mac;
  • 支持常见图片文件预览;
  • 展示上传 / 下载任务状态、进度与失败信息;
  • 文件传输与视频镜像使用独立链路,避免把所有能力耦合在一个任务中。

4. 多设备与原生 Mac 体验

  • Android 与 iOS 使用统一的 DeviceSession 会话接口;
  • 每台设备拥有独立的连接、渲染器和输入状态;
  • 同时识别多台设备后,可从顶部设备栏快速切换;
  • 提供欢迎引导、USB 调试教程、连接状态、错误恢复、帮助页和关于页;
  • 使用 SwiftUI + AppKit 构建,保留 macOS 原生窗口、菜单与快捷键体验。

产品截图

相比初赛 Demo 的升级

初赛 PRD 中的 Demo 聚焦“Android 手机通过 USB 投屏到 Mac”,很多能力当时明确列为暂不支持。仅验证最小MVP。复赛 v4.3 已从单点演示扩展为完整的跨设备工具:

维度 初赛 Demo 复赛 v4.3
平台 Android Android + iOS
核心能力 单向画面镜像 镜像、Android 反控、文件与照片流转
输入 不支持反向操作 鼠标、键盘、滚轮、右键、触控板缩放
设备架构 单设备逻辑 独立 DeviceSession + 多设备切换
文件能力 不支持 Android 文件上传 / 下载 / 批量处理 / 图片预览
iOS 素材 不支持 照片视频浏览、预览、单项预览
旋转体验 基础方向适配 解码会话重建、关键帧恢复、窗口与坐标同步
产品化 核心功能原型 帮助、错误状态、菜单快捷键、DMG 构建与产品官网

这次升级最重要的不是简单增加按钮,而是重新整理了底层会话边界:Android 和 iOS 可以共享统一的产品体验,但各自保留适合平台的连接和能力,不为了“功能对称”而做不可靠的承诺。

产品演示视频:

https://my.feishu.cn/file/OHn0bh4EQo2BWsx235RchLUjnAf?from=from_copylink

产品创作历程:

1.灵感:把“能用的技术”变成“普通人愿意用的产品”

最初的需求很直接:在 Mac 上演示 Android App。scrcpy 等工具已经证明底层技术可行,但命令行、端口转发、编解码参数和设备授权对普通用户并不友好。我的目标不是再做一个命令包装器,而是把设备检测、状态引导、视频解码、渲染、控制和异常恢复组成一条完整体验。

2. 初赛:先打通 Android USB 镜像闭环

初赛阶段首先完成最短闭环:ADB 检测设备 → 临时推送 scrcpy server → 建立视频 Socket → 解析 H.264 帧 → VideoToolbox 硬件解码 → Metal 显示。与此同时,用 SwiftUI 构建欢迎、连接、投屏和错误状态,让第一次使用的用户知道如何开启 USB 调试并完成授权。

3. 从“看手机”升级为“在 Mac 上继续工作”

只有画面还不够。复赛阶段进一步解析 scrcpy v4.0 控制协议,自行实现控制消息的大端序二进制序列化、独立控制 Socket、视窗坐标到设备坐标映射,再把 MTKView 改造成可以接收鼠标、键盘、滚轮和触控板事件的交互视图。产品从单向投屏变成了真正的双向硬件交互。

4. 从单设备原型升级为双平台、多会话架构

加入 iOS 后,直接继续堆条件分支会让代码迅速失控。因此我引入 DeviceSession 协议,把每台设备的连接、渲染和状态封装为独立会话,再由 ViewModel 管理设备池和当前活动设备。这样 Android 可以保留反向控制,iOS 可以使用系统采集通道,两者在 UI 上仍保持一致。

5. 从投屏工具扩展为跨设备工作台

在真实使用中,用户投屏之后往往紧接着要导素材或传文件。基于这一观察,我为 Android 扩展 ADB push / pull、目录浏览和图片预览;为 iOS 使用 ImageCaptureCore 实现照片视频管理。它们不是孤立功能,而是投屏工作流的自然延伸。

6. 最棘手的问题:旋转时的卡死与崩溃

手机旋转会让 Android 编码器短暂停帧,并重新发送 SPS / PPS 与关键帧。早期实现中,Socket 读超时可能发生在一个帧头或帧体的中间,已经读取的半包会被丢弃,后续数据便永久错位;同时 VideoToolbox 会话与 Metal 纹理在重建时还存在跨线程生命周期竞争。

最终的解决方案包括:精确读取过程中保留 offset 并继续补齐当前包;收到新 SPS / PPS 后先创建新解码会话,再安全替换旧会话;等待关键帧恢复参考链;把每次绘制使用的纹理改为局部不可变快照,并保留到 GPU 完成。这个问题让我更深刻地认识到,实时音视频产品的“可用”与“稳定可用”之间,差的往往正是边界状态和资源生命周期。

TRAE 实践过程:

我使用 TRAE 把产品需求拆成 Spec、Tasks、Checklist 和调研文档,再逐项实现、编译和验收。主要包括以下几条任务线:

关键任务一:Android 反向控制

  • 先编写《反向控制功能 Spec》,明确为什么做、协议格式、控制通道建立顺序和验收场景;
  • 将工作拆为 ControlMessage、ControlConnection、InputController、ViewModel 集成、UI 事件捕获和构建验证六类任务;
  • 对照 scrcpy v4.0 协议确认 14B 键盘消息、32B 触摸消息和 21B 滚动消息的大端序布局;
  • 使用 Checklist 逐项确认鼠标、键盘、滚轮、坐标映射、线程安全和 DMG 构建。4003739593350636:8723e561f976dccc90b6eaf9ce1eb22d_6a2f4b0e5a8f86b7d4ae47c6.6a2fbd6f5f8c99654b7fec79.6a2fbd6f5f8c99654b7fec77:TRAE Work CN.0.1.39.no_sid.no_ppe.T(2026/6/15 16:53:03)

关键任务二:双平台与多设备架构

  • 先让 TRAE 分析原 ViewModel 中高度耦合的 Android 逻辑;

  • 制定 AndroidSession 提取计划和统一 DeviceSession 接口;

  • 为每台设备建立独立 renderer、decoder、connection 和 input controller;

  • 再加入 iOS 系统采集与顶部设备切换,避免继续扩张单体 ViewModel。

    4003739593350636:cf87d1cad4378dce237402fb9c8079cf_6a2f4b0e5a8f86b7d4ae47c6.6a3c90c042a2f8934708f9b1.6a3c90c042a2f8934708f9af:TRAE Work CN.0.1.39.no_sid.no_ppe.T(2026/6/25 10:21:52)

关键任务三:文件与照片传输

  • 先比较 Android ADB、iOS Photos / ImageCaptureCore、MobileDevice 私有接口等方案;
  • Android 选择已有 ADB 能力扩展 push / pull,降低新增依赖和兼容风险;
  • iOS 放弃不稳定的通用文件系统访问,只聚焦官方系统能够可靠提供的照片视频导出;
  • 在方案明确后再实现任务状态、批量选择、预览与错误提示。4003739593350636:f912ad2d80ab87df4d2262a3fa5a19d5_6a2f4b0e5a8f86b7d4ae47c6.6a3e761add8d779952f6946e.6a3e761add8d779952f6946c:TRAE Work CN.0.1.38.no_sid.no_ppe.T(2026/6/26 20:52:42)

关键任务四:稳定性诊断与旋转修复

  • 让 TRAE 沿“视频 Socket → H.264 配置帧 → VideoToolbox → CVPixelBuffer → Metal”完整链路排查;

  • 对比正常帧与旋转时的超时、SPS / PPS、关键帧和分辨率变化;

  • 修复半包丢失、失效 Socket 空转、解码会话替换和 GPU 纹理生命周期;

  • 分别执行 Debug 与 Release 构建验证。

    4003739593350636:894ab5eab8c05f7ff668f7b550d6ab63_6a2f4b0e5a8f86b7d4ae47c6.6a3cf6d9836f1249872ee57a.6a3cf6d9836f1249872ee578:TRAE Work CN.0.1.39.no_sid.no_ppe.T(2026/6/25 17:37:29)

其他功能及任务节点:

4003739593350636:71fc157f0e0b31534eb39700da50f4f8_6a2f4b0e5a8f86b7d4ae47c6.6a471f203552d3ae69c5e6ac.6a471f203552d3ae69c5e6aa:TRAE Work CN.0.1.38.no_sid.no_ppe.T(2026/7/3 10:32:00)

4003739593350636:603e8a74cb15944f59c1928cd8df1335_6a2f4b0e5a8f86b7d4ae47c6.6a3e9a40dd8d779952f6992e.6a3e9a40dd8d779952f6992c:TRAE Work CN.0.1.38.no_sid.no_ppe.T(2026/6/26 23:26:56)

4003739593350636:66d34f2f703e680055ab2e351088174e_6a2f4b0e5a8f86b7d4ae47c6.6a3cc62d836f1249872edf24.6a3cc62d836f1249872edf22:TRAE Work CN.0.1.38.no_sid.no_ppe.T(2026/6/25 14:09:49)

技术方案分享

技术栈

  • **客户端语言与 UI:**Swift、SwiftUI、AppKit;
  • **视频解码与帧处理:**VideoToolbox、CoreVideo;
  • **GPU 渲染:**Metal、MetalKit;
  • **iOS USB 画面:**AVFoundation、CoreMediaIO;
  • **iOS 照片视频:**ImageCaptureCore;
  • **Android 连接:**内置 ADB、scrcpy server v4.0、TCP Socket;
  • **官网:**React、Vite、Tailwind CSS;
  • **构建交付:**Swift Package Manager、DMG 打包脚本。

Android 视频链路

Android 屏幕
  → 系统采集 / MediaCodec H.264 编码
  → scrcpy LocalSocket
  → ADB 端口转发
  → Mac 帧头与 NAL 解析
  → VideoToolbox 硬件解码
  → CVPixelBuffer
  → Metal 纹理与 MTKView

Android 控制链路

macOS 鼠标 / 键盘 / 触控板
  → InteractiveMetalView 捕获事件
  → InputController 做坐标与按键映射
  → ControlMessage 二进制序列化
  → 独立控制 Socket
  → Android 注入触摸、滚动或键盘事件

关键技术决策

  1. **手机端零常驻安装:**Android 镜像服务运行时临时推送和启动,结束后清理;
  2. **视频与控制分离:**画面接收和输入发送使用独立 Socket,降低互相阻塞;
  3. **硬解 + GPU 渲染:**减少 CPU 参与,适合实时镜像;
  4. **会话隔离:**多设备分别持有连接与渲染状态,切换 UI 不等于重建全部设备;
  5. **按平台能力取舍:**Android 提供深度控制和通用文件传输;iOS 提供可靠的镜像与照片预览,不虚构系统未开放的控制能力;
  6. **本地优先:**USB 镜像和文件流转以本地链路为主,不上传屏幕数据。

创新性与产品价值

li Mirror 的创新点不在于单独发明一种投屏协议,而在于把多套底层能力重新组合成一个连贯的原生工作流:

  • 把 Android 命令行镜像能力产品化,让非开发者也能完成连接;
  • 把“投屏”和“操作手机”统一在同一个画布上;
  • 把 Android 与 iOS 放入统一设备会话模型,同时尊重两个平台的能力差异;
  • 把文件和照片流转放到镜像上下文里,减少用户切换工具;
  • 针对横竖屏、断流、关键帧、GPU 生命周期等边界做稳定性处理,而不是只在理想路径下展示 Demo。

它可以减少移动端演示、教学和调试的准备成本,也能帮助主要使用 Mac 的用户更自然地使用 Android 设备。对个人开发者而言,它还展示了一条可复用的路径:借助 TRAE,把“想法—需求—技术调研—任务拆分—实现—验证—产品化”连成完整闭环。

后续迭代规划

  1. **稳定性与兼容性:**补充更多品牌(如鸿蒙系统)和 Android 版本的长时间投屏、快速旋转、反复插拔测试;
  2. **输入体验:**实现完整的 macOS 原生输入法链路与中日韩文组合输入;
  3. **剪贴板:**在完善控制通道接收能力后,加入 Android 与 Mac 文本剪贴板同步;
  4. **无线能力:**对现有 Android Wireless ADB 原型做真实设备验证和可达 UI,再决定是否正式发布;
  5. **生产力功能:**探索录屏、截图、标注、多设备同步演示与测试辅助;
  6. **工程质量:**增加协议序列化、帧解析、坐标映射和连接异常的自动化测试。

结语

从最初只能把 Android 画面显示到 Mac 的 Demo,到现在支持双平台、多设备、Android 反向控制、文件传输和 iOS 照片管理的 v4.3,li Mirror 的每一步迭代都来自真实使用中的下一个问题。

我希望它最终成为一个“感受不到协议存在”的工具:用户不需要理解 ADB、H.264、Socket、VideoToolbox 或 Metal,只需要连接设备,然后自然地继续手上的工作。

感谢阅读,欢迎交流产品体验、设备兼容性和跨端交互方向的建议。

fu赛都好强啊好可怕

这类产品Mac上应该会有类似的竞品吧,感觉可以顺便了解一下竞品,可能对下一步开发有帮助。

:ok_hand:正有此意

1 个赞