Simple Live 手表看直播实战:用 Flutter 把四大平台聚合应用跑在腕上的完整指南
【免费下载链接】dart_simple_live简简单单的看直播项目地址: https://gitcode.com/GitHub_Trending/da/dart_simple_live
清晨 8 点的地铁上,你想确认主播有没有开播——掏手机不方便,抬手腕却刚好。这就是 Dart Simple Live(Simple Live,"简简单单的看直播")想解决的问题:它用一个 Flutter 核心库同时打通虎牙、斗鱼、B 站、抖音四个平台的房间列表、播放链接和弹幕协议,让聚合直播从手机、电视搬到智能手表这类小屏设备上成为可能。
好消息是,你不需要从零造轮子。这个仓库本身就是"一个核心库 + 多个客户端"的单体仓库(monorepo),把核心能力抽离出来之后,做一个手表端应用只需薄薄一层 UI。下面按"确认可行性 → 理解核心 → 突破小屏限制 → 编译发布"的顺序走一遍。
为什么智能手表能跑:先看仓库怎么组织的
很多项目把网络、协议、UI 全糊在一个 App 工程里,换端就得重写。Simple Live 把仓库拆成了四层:
| 模块 | 定位 | 对穿戴端的意义 |
|---|---|---|
simple_live_core | 聚合直播核心库(v1.0.3) | 所有数据与协议能力,不依赖 Flutter UI,可直接复用 |
simple_live_app | 手机/桌面端 Flutter App(v1.11.4) | 现成的 UI 参考,含弹幕、同步、画中画 |
simple_live_tv_app | Android TV 客户端 | 大屏端示例,其低交互设计思路可借鉴到手表 |
simple_live_console | 控制台程序 | 调试核心库协议时不启动 UI |
关键收益:核心库是纯 Dart,不含任何 Flutter Widget 依赖。这意味着手表端工程可以只引用 simple_live_core,把simple_live_app里几百个 Widget 全部丢掉,包体和内存天然就小。
上面这张深色模式截图是手机端形态。手表端要做的事情很纯粹:把这套数据的展示面压缩到 1.2~1.8 英寸的圆屏上。
一个接口收敛四个平台:核心库的数据流
在写任何 UI 之前,先搞懂核心库怎么屏蔽平台差异。它只有两个顶层抽象:LiveSite(站点数据)和LiveDanmaku(弹幕)。
// 所有平台共用同一套站点接口,默认实现返回空值, // 各平台覆写自己支持的方法 class LiveSite { String id = ""; String name = ""; Future<LivePlayUrl> getPlayUrls( {required LiveRoomDetail detail, required LivePlayQuality quality}) { return Future.value(LivePlayUrl(urls: [])); } LiveDanmaku getDanmaku() => LiveDanmaku(); }四个平台各自覆写这个接口,内部难度差别很大,但对调用方完全透明:
- 虎牙:弹幕 token 走 Tars 协议,仓库内置了 tars_dart 编解码包。
HuyaSite里就是一个 HTTP 客户端:BaseTarsHttp("http://wup.huya.com", "liveui", ...),请求包编码发出、响应解码拿到 CDN token,全程约 20 行胶水代码。 - B 站:标准 REST 接口加 WebSocket,难点在 buvid cookie 的获取,bilibili_site.dart 里先请求一次 buvid 再拼请求头。
- 抖音:接口参数需要 JS 生成的签名(x-gorgon 等),核心库直接内嵌
dart_quickjs,在 Dart 侧跑 JS 引擎算签名,scripts/douyin_sign.dart存的就是签名脚本。
一次"打开房间"的完整链路如下:
对穿戴端来说,这张图就是你要实现的合同:拿到LivePlayUrl交给播放器,挂上LiveMessage流做通知或滚动弹幕。数据层一行不用改。
1.5 英寸屏幕上的三个硬约束
手表和小屏设备的限制是真实的,逐项对应解法:
约束一:信息密度
圆屏可视区域大约只有 200x200 像素,手机端的"封面+标题+主播+人数+分类"五要素必须砍掉一半。做法是每个房间只留一行标题和一行观看数:
// 手表卡片:标题截断到 10 字,全卡只两行文字 Text( room.title.length > 10 ? '${room.title.substring(0, 10)}…' : room.title, style: TextStyle(fontSize: 10, color: Colors.white), maxLines: 1, overflow: TextOverflow.ellipsis, )列表页建议放弃宫格改单向滚动列表,一次只看 2~3 个卡片,降低视觉负担。
约束二:内存与包体
手表可用内存通常在 200MB 上下,而simple_live_app的 pubspec 里有 30 多个依赖。手表端只保留最小集:
dependencies: simple_live_core: path: ../simple_live_core # 核心库,含弹幕/签名/Tars 全部能力 media_kit: ^1.2.2 # 视频解码播放 media_kit_video: ^2.0.0图片加载建议用带压缩的加载器,把封面按显示尺寸缩放后再入缓存,而不是原图直接解码。
约束三:续航
直播是长连接+持续解码,对电池消耗最大的其实是"空闲时的无意义刷新"。按电量分档控制行为比一刀切省电更有效:
| 电量区间 | 房间列表刷新 | 弹幕长连接 | 播放清晰度 |
|---|---|---|---|
| < 15% | 60s | 断开,仅保留开播通知 | 最低档 |
| 15%~40% | 30s | 保持,消息静默缓存 | 标清 |
| > 40% | 10s | 正常 | 用户选择 |
弹幕侧还有一个现成能力可以利用:LiveDanmaku暴露了heartbeatTime心跳周期,低电量档把心跳拉长,空闲时连接开销可降一半以上。
播放侧则直接复用 播放器核心代码 的 media_kit 方案:直播流是 m3u8/flv,player.open(Media(url), play: true)即播,不需要手机端那套清晰度切换 UI,默认锁定一档画质反而更省。
从 clone 到上手的最短步骤
- 准备环境:Flutter 3.38+(与仓库
README声明一致),装好 Android SDK 与手表调试证书。 - 拉取代码并建手表工程:
git clone https://gitcode.com/GitHub_Trending/da/dart_simple_live # 新建 simple_live_watch_app,仅引用 core: # dependencies 里指向 path: ../simple_live_core- 跑通第一帧:先用 simple_live_console 在控制台验证某个房间的
getPlayUrls返回非空列表,确认核心库可用,再接手表端 UI。 - 出包:
flutter build apk --release --dart-define=WEAR_DEVICE=true发布前的验收清单可以直接当测试用例用:
| 验收项 | 方法 | 通过标准 |
|---|---|---|
| 内存 | 连续播放 30 分钟观察占用 | 峰值 < 80MB,无持续上涨 |
| 续航 | 标清连播 | > 3 小时 |
| 断连恢复 | 播放中锁屏 10 分钟 | 唤醒后自动重连,无需重启 |
| 弹幕 | 静音环境下 | 消息静默落库,电量档恢复后回放 |
小结
Simple Live 手表端的全部增量,就是"一个薄 UI 层 + 一套省电策略":数据、协议、签名、弹幕长连接这些脏活累活全部沉淀在 simple_live_core 里,虎牙的 Tars、抖音的 JS 签名、B 站的 cookie 机制都不用你碰。如果你想动手,最短路径是今天先把 console 跑通一个房间的播放地址,明天就能在手表上看到第一帧画面。
【免费下载链接】dart_simple_live简简单单的看直播项目地址: https://gitcode.com/GitHub_Trending/da/dart_simple_live
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考