需求場景
手機端遠程控制電腦桌面:畫面傳輸、鼠標鍵盤事件轉發、雙向交互。
整體技術架構
1. 核心組件
| 組件 | 端側 | 職責 |
| Agent (被控端) | PC (Windows/macOS/Linux) | 桌面捕獲、輸入注入、編碼推流 |
| Client (控制端) | Android/iOS | 視頻解碼渲染、觸摸轉換、指令發送 |
| Signal Server | 雲端 | 設備發現、連接建立、NAT 穿透協商 |
| Relay Server (可選) | 雲端 | 中轉數據 (P2P 失敗時) |
2. 數據流向
[PC 桌面] → [捕獲] → [編碼 H.264/HEVC] → [網絡傳輸 UDP/TCP] → [解碼] → [Android 顯示]
[Android 觸摸] → [座標轉換] → [指令序列化] → [網絡傳輸] → [PC 注入輸入]
關鍵技術難點與方案
1. 桌面捕獲 (PC 端)
| 平台 | API/方案 | 特點 |
| Windows | DXGI Desktop Duplication API (Win8+) | 高性能、GPU 零拷貝、支持多顯示器 |
| Windows | GDI BitBlt / DirectDraw | 兼容舊版、CPU 佔用高 |
| macOS | CGWindowListCreateImage / ScreenCaptureKit (macOS 12.3+) | 系統級 API、權限管理嚴格 |
| Linux | X11 XShmGetImage / Wayland screencopy | 桌面環境相關、Wayland 權限受限 |
2. 視頻編碼與傳輸
- 編碼器:H.264 (廣泛硬解支持) / HEVC (更高壓縮比) / VP9 (免版稅)
- 硬件加速:Intel QuickSync, NVIDIA NVENC, AMD VCE, Apple VideoToolbox
- 傳輸協議:
- WebRTC (SRTP + DTLS) - 低延遲、NAT 穿透成熟
- QUIC/UDP + 自定義協議 - 可控性強
- RTMP/HTTP-FLV - 兼容性好但延遲高
- 自適應碼率:根據網絡狀況動態調整分辨率/幀率/質量
3. 輸入事件轉換 (Android → PC)
// 觸摸 → 鼠標映射
public class InputMapper {
// 單指拖動 → 鼠標移動
// 單指點擊 → 左鍵點擊
// 雙指捏合 → 滾輪縮放
// 雙指拖動 → 中鍵拖動/滾動
// 長按 → 右鍵菜單
// 座標轉換:Android 螢幕座標 → PC 桌面座標
public MouseEvent mapTouchEvent(MotionEvent event, DisplayMetrics phone, Dimension pc) {
float scaleX = (float) pc.width / phone.widthPixels;
float scaleY = (float) pc.height / phone.heightPixels;
return new MouseEvent(event.getX() * scaleX, event.getY() * scaleY, mapAction(event.getAction()));
}
}
4. 鍵盤輸入處理
- 虛擬鍵盤事件 → PC 鍵盤掃描碼
- 特殊鍵 (Ctrl/Alt/Win/Cmd) 狀態同步
- 輸入法編輯 (IME) 狀態同步 (極具挑戰性)
5. 連接建立與 NAT 穿透
- STUN/TURN/ICE 標準流程 (WebRTC 內建)
- 本地網絡 mDNS/Bonjour 發現
- 中繼服務器兜底 (商業產品必備)
開源項目參考
開發建議路徑
- MVP 階段:基於 scrcpy 修改,實現基本畫面+點擊
- 優化階段:接入 WebRTC、硬編、自適應碼率
- 產品化:信令服務器、NAT 穿透、賬號體系、權限管理
- 進階功能:文件傳輸、剪貼板同步、多顯示器、遠程喚醒
藍牙 vs WiFi 選擇
| 特性 | WiFi (局域網) | 藍牙 |
| 帶寬 | 高 (100Mbps+) | 低 (~2Mbps) |
| 延遲 | 低 (~10-30ms) | 高 (~50-100ms) |
| 距離 | 全屋覆蓋 | 10-20米 |
| 適用場景 | 主流遠程控制 | 極近距離、無網環境 |
遠程桌面是系統級工程,建議基於成熟開源項目 (scrcpy/RustDesk) 二次開發,而非從零構建核心傳輸棧。