AndroidWebRTC4Control
本示例演示了如何在没有中心信令服务器的情况下,通过局域网在两个 Android 设备之间直接利用 WebRTC 技术进行实时的屏幕录制传输和利用安卓无障碍服务实现远程控制。
Install / Use
/learn @halifox/AndroidWebRTC4ControlREADME
AndroidWebRTC4Control
本项目是一个基于 WebRTC 和 Android 无障碍服务(AccessibilityService)实现的 Android 设备局域网远程控制和屏幕共享应用。
项目背景与说明: 本项目的业务需求是在一个纯内网(或局域网)环境中,实现一台 Android 设备对另一台同在局域网中的 Android 设备的远程控制。由于纯内网的限制,传统的依赖公网信令服务器和中转服务器的方案不可行。本项目采用 NSD(mDNS)实现局域网设备发现,并通过纯局域网环境下的直连 Socket 交换 WebRTC 信令及控制指令。
⚠️ 注意:当前该项目仅作为功能可行性调研(Proof of Concept)的示例。其重点在于跑通局域网直连、屏幕流传输和手势无障碍控制的流程,因此未进行严谨的架构设计与异常处理,代码质量仅限调研演示级别,不可直接用于生产环境。
核心功能
- 局域网发现:使用 Android NsdManager(mDNS)在局域网内自动发现并配对设备。
- 屏幕共享:基于 WebRTC 和 Android MediaProjection 实时、低延迟地传输受控端屏幕画面。
- 远程控制:控制端可以实时同步触摸事件(支持多点触控)以及全局操作(返回、主页、最近任务)到受控端。
- 手势模拟:受控端通过 AccessibilityService 接收坐标并执行手势模拟,实现无 Root 控制。
模块角色
- 受控端 (Slave):
- 开启无障碍服务,准备接收手势和全局按键指令。
- 开启屏幕录制服务(Foreground Service),通过
MediaProjection捕获屏幕画面。 - 注册局域网 NSD 服务,并开启 Socket Server 等待控制端连接。
- 控制端 (Master):
- 搜索局域网中的受控端设备。
- 连接受控端的 Socket 服务。
- 接收 WebRTC 视频流并渲染。
- 捕获用户的屏幕触摸与按键操作,并通过 Socket 发送给受控端。
完整的数据交互流程
本项目的数据交互主要分为 发现阶段、信令与控制连接建立、WebRTC 音视频协商、远程控制指令流转四个部分。所有的信令(WebRTC SDP/ICE)和控制指令(触摸、按键)都复用同一个 TCP Socket 连接。
1. 发现阶段 (NSD)
- 受控端:通过
NsdManager注册一个服务类型为_control._tcp.,端口为40000的服务,服务名通常为设备型号。 - 控制端:通过
NsdManager扫描_control._tcp.类型的服务,发现受控端设备后,解析出其局域网 IP 地址和端口号(40000)。
2. 信令与控制连接 (TCP Socket)
- 受控端:在
ScreenCaptureService中启动ServerSocket监听40000端口。 - 控制端:在
ScreenCaptureActivity中创建Socket连接受控端的 IP 和40000端口。 - 双方建立连接后,获取
DataInputStream和DataOutputStream,开始基于一套自定义的整数类型协议(定义于ext.kt)进行通信。协议类型包括:101 (ACTION_EVENT): 全局按键操作(返回、主屏幕等)102 (TOUCH_EVENT): 屏幕触摸事件201 (ICE_CANDIDATE): WebRTC ICE 候选者202 (SESSION_DESCRIPTION): WebRTC SDP 会话描述203 (CONFIGURATION_CHANGED): 屏幕配置(分辨率/比例)改变
3. WebRTC 屏幕共享流转
- 受控端初始化:受控端获取
MediaProjection权限后,通过 WebRTC 的ScreenCapturerAndroid采集屏幕画面,作为本地视频轨添加到PeerConnection。 - 创建 Offer:受控端主动创建 WebRTC Offer SDP,并通过 TCP Socket (
SESSION_DESCRIPTION) 发送给控制端。 - 控制端响应 Answer:控制端收到 Offer SDP 后,设置为远端描述,随后创建 Answer SDP,再通过 TCP Socket (
SESSION_DESCRIPTION) 发送回受控端。 - 交换 ICE:双方的
PeerConnection收集到网络候选者(ICE Candidate)时,通过 TCP Socket (ICE_CANDIDATE) 发送给对方,对方接收后加入PeerConnection,完成 P2P 通道的穿透和建立。 - 画面渲染:控制端收到受控端的远端视频轨后,在
SurfaceViewRenderer上实时渲染。
4. 远程控制指令流转
- 触摸事件:
- 控制端用户在
SurfaceViewRenderer上的触摸动作会触发onTouchEvent。 - 控制端提取动作类型(ACTION_DOWN, ACTION_MOVE 等)、坐标(X, Y)、渲染器宽高、压力值等数据,打包成
TOUCH_EVENT通过 TCP Socket 发送。 - 受控端收到
TOUCH_EVENT后,将坐标从“控制端渲染器尺寸”等比例映射还原到“受控端实际屏幕尺寸”。 - 受控端的
Controller将坐标转换为MotionEvent,并传递给GestureControlAccessibilityService,使用GestureDescription构建笔画,在受控端真实屏幕上模拟点击或滑动。
- 控制端用户在
- 全局按键事件:
- 控制端点击“返回”、“主页”或“多任务”按钮时,发送对应的
ACTION_EVENT(如GLOBAL_ACTION_BACK) 给受控端。 - 受控端收到后,调用
GestureControlAccessibilityService的performGlobalAction方法,系统层级执行相应的全局导航操作。
- 控制端点击“返回”、“主页”或“多任务”按钮时,发送对应的
- 屏幕状态同步:
- 受控端屏幕发生旋转等配置改变时,通过
BroadcastReceiver监听,发送CONFIGURATION_CHANGED(包含最新宽高) 给控制端。 - 控制端收到后,动态调整
SurfaceViewRenderer的比例,确保画面不被拉伸变形。
- 受控端屏幕发生旋转等配置改变时,通过
依赖库
- 界面 UI:Jetpack Compose, Material3
- WebRTC:
io.getstream:stream-webrtc-android - 依赖注入:
io.insert-koin:koin-android - 工具库:
com.blankj:utilcodex
Related Skills
node-connect
339.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.9kCommit, push, and open a PR
