屏幕镜像:WebCodecs + Canvas 实现的远程桌面
入口位置
侧栏点 Screen Mirror(最后一项)。手机端 PlainApp 本身没有专门的屏幕镜像页面——这个功能只有浏览器端有 UI,手机端是后台服务,收到浏览器的"开始镜像"请求时才启动。
界面长什么样

面板是一个大 Canvas 画布(手机画面实时渲染在这里) + 上方工具栏。工具栏按钮从左到右:
- Start / Stop — 请求手机开始 / 停止屏幕捕获
- Remote Control 开关 — 打开后画布上的鼠标 / 触屏操作传给手机
- Back / Home / Recents 三键 — 模拟 Android 三大导航键
- Fullscreen — 画布占满整个浏览器窗口(Esc 退出)
- HD / Smooth 质量切换 — HD 优先清晰度、Smooth 优先低延迟
- Screenshot 截屏 — 一键下载 PNG
- Record 录屏 — 本地录屏到浏览器,带录制计时器
- Audio 音频开关 — 请求手机音频、独立静音
- Pause / Relaunch — 暂停节省带宽、重启手机端镜像服务
技术栈
PlainApp 屏幕镜像的实现不走 WebRTC(那是 PlainCast 的技术栈),而是:
- 手机端用 Android MediaProjection API 捕获屏幕帧
- H.264 / H.265 编码(WebCodecs 浏览器解码)
- 通过加密的 WebSocket 发到浏览器
- 浏览器解码后画到
<canvas>里
这个路线的好处:不需要任何插件(WebCodecs 已经是现代浏览器标准 API),也不需要额外的信令服务器(WebRTC 需要)。
三大质量模式
| 模式 | 分辨率 | 帧率 | 适合场景 |
|---|---|---|---|
| Auto | 自适应 | 自适应 | 默认,Wi-Fi 好就升、差就降 |
| HD | 原始或接近原始 | 15–20 fps | 看文档界面、做演示、截屏 |
| Smooth | 降低分辨率 | 25–30 fps | 操控游戏、滑动滚动、快速交互 |
切换质量是热切换——点一下工具栏按钮,下一个关键帧生效,不用重启整个会话。
远程控制怎么用
Remote Control 开关打开后:
- 点击画布 → 手机点一下对应坐标
- 拖拽画布 → 手机滑一下(支持长按)
- 滚轮 / 触屏滑动 → 手机滚动操作
- 键盘输入 → 如果当前手机有可输入区域,按键会传过去
坐标系统做了归一化——不管浏览器窗口你拉多大,点到画布的什么位置都能准确映射到手机屏幕上对应的实际坐标。全屏切换也不影响映射精度。
截屏与录屏
- 截屏 — 工具栏点相机图标,当前画布内容下载成 PNG 文件。比手机音量键 + 电源键方便,因为你不用碰手机
- 录屏 — 点 Record,浏览器开始用 MediaRecorder API 录制 Canvas 内容;再点一次停止,下载 WebM 视频文件。录制期间工具栏有个小红点和计时器
关于 HTTPS 依赖
WebCodecs API 只在 HTTPS 或 localhost 下才能用。PlainApp 的本地服务器默认已经是 HTTPS(自签名证书),所以没问题。
如果你手动用 http:// 8080 端口开的面板,Screen Mirror 页面会显示"需要 HTTPS"提示,并给一个 HTTPS 链接跳转。点那个链接继续,不要硬开 HTTP 版。
常见问题
| 问题 | 处理 |
|---|---|
| 手机弹窗询问"是否允许屏幕录制" | 点允许,然后 PlainApp 屏幕镜像开始 |
| 画面是黑屏 | 大概率手机端镜像服务挂了,工具栏点 Relaunch 重启 |
| 浏览器延迟很高 | 切到 Smooth 模式 + 确认手机和电脑在同一 5 GHz Wi-Fi |
| 远程控制面板没反应 | 确认 Remote Control 开关是亮的;关掉再开试试 |