Skip to content

本示例演示了如何在没有中心信令服务器的情况下,通过局域网在两个 Android 设备之间直接利用 WebRTC 技术进行实时的屏幕录制传输和利用安卓无障碍服务实现远程控制。

License

Notifications You must be signed in to change notification settings

halifox/AndroidWebRTC4Control

Repository files navigation

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)

  1. 受控端:通过 NsdManager 注册一个服务类型为 _control._tcp.,端口为 40000 的服务,服务名通常为设备型号。
  2. 控制端:通过 NsdManager 扫描 _control._tcp. 类型的服务,发现受控端设备后,解析出其局域网 IP 地址和端口号(40000)。

2. 信令与控制连接 (TCP Socket)

  1. 受控端:在 ScreenCaptureService 中启动 ServerSocket 监听 40000 端口。
  2. 控制端:在 ScreenCaptureActivity 中创建 Socket 连接受控端的 IP 和 40000 端口。
  3. 双方建立连接后,获取 DataInputStreamDataOutputStream,开始基于一套自定义的整数类型协议(定义于 ext.kt)进行通信。协议类型包括:
    • 101 (ACTION_EVENT): 全局按键操作(返回、主屏幕等)
    • 102 (TOUCH_EVENT): 屏幕触摸事件
    • 201 (ICE_CANDIDATE): WebRTC ICE 候选者
    • 202 (SESSION_DESCRIPTION): WebRTC SDP 会话描述
    • 203 (CONFIGURATION_CHANGED): 屏幕配置(分辨率/比例)改变

3. WebRTC 屏幕共享流转

  1. 受控端初始化:受控端获取 MediaProjection 权限后,通过 WebRTC 的 ScreenCapturerAndroid 采集屏幕画面,作为本地视频轨添加到 PeerConnection
  2. 创建 Offer:受控端主动创建 WebRTC Offer SDP,并通过 TCP Socket (SESSION_DESCRIPTION) 发送给控制端。
  3. 控制端响应 Answer:控制端收到 Offer SDP 后,设置为远端描述,随后创建 Answer SDP,再通过 TCP Socket (SESSION_DESCRIPTION) 发送回受控端。
  4. 交换 ICE:双方的 PeerConnection 收集到网络候选者(ICE Candidate)时,通过 TCP Socket (ICE_CANDIDATE) 发送给对方,对方接收后加入 PeerConnection,完成 P2P 通道的穿透和建立。
  5. 画面渲染:控制端收到受控端的远端视频轨后,在 SurfaceViewRenderer 上实时渲染。

4. 远程控制指令流转

  1. 触摸事件
    • 控制端用户在 SurfaceViewRenderer 上的触摸动作会触发 onTouchEvent
    • 控制端提取动作类型(ACTION_DOWN, ACTION_MOVE 等)、坐标(X, Y)、渲染器宽高、压力值等数据,打包成 TOUCH_EVENT 通过 TCP Socket 发送。
    • 受控端收到 TOUCH_EVENT 后,将坐标从“控制端渲染器尺寸”等比例映射还原到“受控端实际屏幕尺寸”。
    • 受控端的 Controller 将坐标转换为 MotionEvent,并传递给 GestureControlAccessibilityService,使用 GestureDescription 构建笔画,在受控端真实屏幕上模拟点击或滑动。
  2. 全局按键事件
    • 控制端点击“返回”、“主页”或“多任务”按钮时,发送对应的 ACTION_EVENT (如 GLOBAL_ACTION_BACK) 给受控端。
    • 受控端收到后,调用 GestureControlAccessibilityServiceperformGlobalAction 方法,系统层级执行相应的全局导航操作。
  3. 屏幕状态同步
    • 受控端屏幕发生旋转等配置改变时,通过 BroadcastReceiver 监听,发送 CONFIGURATION_CHANGED (包含最新宽高) 给控制端。
    • 控制端收到后,动态调整 SurfaceViewRenderer 的比例,确保画面不被拉伸变形。

依赖库

  • 界面 UI:Jetpack Compose, Material3
  • WebRTC:io.getstream:stream-webrtc-android
  • 依赖注入:io.insert-koin:koin-android
  • 工具库:com.blankj:utilcodex

About

本示例演示了如何在没有中心信令服务器的情况下,通过局域网在两个 Android 设备之间直接利用 WebRTC 技术进行实时的屏幕录制传输和利用安卓无障碍服务实现远程控制。

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages