我如何使用 WebRTC 和 Kotlin 构建了一个无服务器、P2P 家长控制应用

发布: (2025年12月7日 GMT+8 06:31)
5 min read
原文: Dev.to

Source: Dev.to

简介

作为一名父母兼 Android 开发者,我想在不涉及商业家长控制应用隐私问题的前提下,监控孩子在 TikTok 和 YouTube 上的活动。

几乎所有商业方案的工作方式都相同:

  • 收集孩子的数据(位置、历史、应用使用情况)。
  • 将所有数据上传到集中式云数据库。
  • 在父母的手机上显示。

我不想让孩子的位置信息历史存放在第三方服务器上,于是我使用 Kotlin、Jetpack Compose 和 WebRTC 构建了 SafeStream——一个完全无服务器、点对点的监控系统。

架构:“无后端”方案

核心思路很简单:父母设备充当服务器。数据直接从 设备 A(孩子) 流向 设备 B(父母),中间不进行持久化。

  • Guardian App(孩子) – 运行后台服务,本地收集数据并充当 WebRTC 对等方。
  • Parent App – 充当观看端对等方,直接接收 JSON 负载并存入本地 Room(SQLite)数据库。
  • 信令 – 仅使用 Firebase Realtime Database 进行握手(SDP Offer/Answer 交换)。用户数据不触碰 Firebase。

技术栈

组件技术
语言100 % Kotlin
UIJetpack Compose(Material 3) – 现代 “Reel‑like” 信息流
P2PGoogle 的 WebRTC 库,封装在自定义 WebRTCConnectionManager
穿透STUN/TURN 服务器,用于绕过 NAT 和防火墙(4G/5G 环境必需)
加密基于 WebRTC 的 DTLS 之上使用 AES‑256‑GCM(安全等级:高)

关键技术挑战

1. 提取视频元数据(伦理黑客)

TikTok 和 YouTube 并未提供观看历史的 API。我实现了一个 Accessibility ServiceGuardianAccessibilityService.kt),用于扫描 UI 层级:

  • 检测用户是否处于视频应用(com.zhiliaoapp.musicallycom.google.android.youtube)。
  • 抓取可见视图的 contentDescription 或文本,以提取视频标题和频道。

优化: 逻辑经过大量防抖,仅在屏幕内容变化时运行,最大限度降低电池消耗。

2. 后台的 WebRTC 握手

在现代 Android 上保持后台 WebRTC 连接活跃非常困难,因为 Doze 模式和 App Standby Buckets 的限制。

解决方案:

  • 使用前台服务并显示持久通知,以保持连接存活。
  • 按需开启: 父母端发送高优先级 FCM(Firebase Cloud Message)“唤醒”孩子设备,随后孩子设备发起 WebRTC 信令流程。

3. 点对点传输图片

高分辨率截图会超过 WebRTC 的安全消息大小限制(约 16 KB)。我编写了分块算法:

  1. Bitmap 压缩为 WebP。
  2. 将二进制数据拆分为小包。
  3. 通过 DataChannel 按顺序发送这些包。
  4. 在父母端重新组装。

商业模式(独立开发者现实)

SafeStream 免费发布,但运行 TURN 服务器(带宽中继)会产生费用。为在不采用订阅或出售数据的情况下保持可持续,我引入了 积分系统

  • 文本日志和实时位置免费(低带宽)。
  • 下载高分辨率截图会消耗 “积分”。
  • 用户每天可获得免费积分,或观看奖励型 AdMob 广告来补充积分,以覆盖 TURN 带宽费用。

接下来计划

我将在下周启动公开 Beta,并征求关于不同网络运营商(尤其是 CGNAT)下 P2P 稳定性的反馈。

如果你对 P2P 实现感兴趣或想亲自测试,请前往这里查看: SafeStream Guardian Architecture – beta subscription

祝编码愉快! 🚀

Back to Blog

相关文章

阅读更多 »