Flutter 穿戴开发实战:Dart Simple Live 智能手表直播应用的 3 处改造拆解
【免费下载链接】dart_simple_live简简单单的看直播项目地址: https://gitcode.com/GitHub_Trending/da/dart_simple_live
早高峰抬腕,先确认主播开没开播——这是智能手表直播应用最实际的需求。Dart Simple Live 的 核心库 是纯 Dart 实现,搬到手表端一行不用改;真正要重写的是列表 UI、播放器和功耗管理,共 3 处。下面按改造顺序走一遍,最后给真机验收清单。
手表端做直播,到底难在哪
与手机端相比,手表端要解决的不是功能问题,而是资源问题。直播链路本身已经完成:拉房间列表、解析弹幕协议、取播放地址,这些在核心库里全部就绪;缺的只是显示、供电、算力三块空间。三个约束放一起看:
| 约束 | 手机端 | 手表端 |
|---|---|---|
| 屏幕 | 6 英寸级,可同时放网格列表与弹幕层 | 1.2~1.8 英寸,一张卡片一屏,操作靠抬腕和单指 |
| 电量 | 全天续航,后台长驻可接受 | 连续播放以小时计,后台轮询必须能停 |
| 算力 | 硬解与多层渲染开销不大 | 弹幕渲染与解码都会放大掉帧,必须做减法 |
三个约束指向同一个结论:不要整包搬 手机端应用,保住数据层,重写外壳。这也符合仓库现状——simple_live_tv_app/ 与 simple_live_app 共用核心库、各写各的壳,TV 端已经验证过这条路径,手表端是沿用同一思路的第三个壳。
Simple Live 哪些层能直接复用到穿戴端
看依赖方向就能划清复用边界。simple_live_core/ 完全不依赖 Flutter,只引入 dio、web_socket_channel、protobuf 做网络、弹幕和协议解析,所以在 Flutter 3.22 的手表端工程里可以直接引用,数据层不产生任何渲染开销。它对外暴露两组接口:LiveSite 提供 getRecommendRooms、getRoomDetail、getPlayUrls、getLiveStatus 等方法,LiveDanmaku 提供 onMessage、start、stop 与 heartbeat,覆盖一个直播应用需要的全部数据动作,且 bilibili、douyin、douyu、huya 四个站点的实现已经写好。
必须重写的是两类东西。第一类是 simple_live_app 里所有 Widget 与 GetX 控制器,手机端的设置页、同步、工具箱这些功能在手表上没有位置,连迁移都谈不上;第二类是 PlayerController 里的 MediaKit 配置与 wakelock_plus、screen_brightness 等系统特性,它们在手表端要么无效要么有害。另外说明一点:仓库现有两个应用都没有包含穿戴端代码,Wear OS 壳工程需要自己新建,这正是后文 3 处改造的出发点。
三处必须改动的代码:列表 UI、播放器与功耗 ⚡
① 列表 UI:一张卡片只留三样。手机端的 直播间卡片 带标签、弹幕入口等元素,手表上没有空间也没有必要。保留 LiveRoomItem 里的封面、标题、人气三个字段,字号压到 9~10,让单张卡片成为唯一的操作单元,左右滑动翻页:
// 手表端房间卡片:只留封面、标题、人气 class WatchRoomCard extends StatelessWidget { final LiveRoomItem room; const WatchRoomCard({required this.room}); @override Widget build(BuildContext context) { return Column(children: [ NetImage(room.cover, width: 96, height: 54), Text(room.title, maxLines: 1, overflow: TextOverflow.ellipsis), Text('${room.online} 人气', style: const TextStyle(fontSize: 9)), ]); } }② 播放器:配置收窄,弹幕按类型过滤。手机端播放器叠加了手势、画中画、小窗等多层 mixin,手表端全部砍掉,只保留创建 Player 的部分并显式开硬解——手表直播播放器要把解码尽量交给 GPU:
late final player = Player(); late final videoController = VideoController( player, configuration: const VideoControllerConfiguration( enableHardwareAcceleration: true, ), ); // 弹幕只透传聊天消息,过滤礼物与醒目留言 danmaku.onMessage = (msg) { if (msg.type == LiveMessageType.chat) { pushDanmaku(msg.message); } };播放地址直接取 core 的 getPlayUrls 返回值,headers 原样带上;手表端选最低清晰度档位,网络流量和耗电都会随之下降。弹幕侧只保留 LiveMessageType.chat,gift 与 superChat 直接丢弃,渲染压力主要来自这里。
③ 功耗:按电量档位降级。手表上最大的消耗源是轮询与常亮。用电池档位决定刷新间隔和功能保留,低电量先断弹幕连接、再放 wakelock:
Duration getRefreshInterval(int batteryLevel) { if (batteryLevel < 20) return const Duration(seconds: 60); if (batteryLevel < 50) return const Duration(seconds: 30); return const Duration(seconds: 10); } void applyBatteryPolicy(int batteryLevel) { if (batteryLevel < 15) { danmaku.stop(); // 断开弹幕连接 WakelockPlus.disable(); // 停止屏幕常亮 } else { WakelockPlus.enable(); } }10s~60s 的间隔没有标准答案,按目标机型的实测续航回调即可,原则只有一个:低电量先降级,而不是等系统杀进程。
手表真机验收清单:内存、续航与多设备
3 处改造完成后不要急着打包。手表芯片型号差异大,内存和续航不设精确百分比,用定性口径:内存看"反复进出直播间后是否明显漂移",续航看"真机连续播放能撑多久",对照以下条目逐项过:
- 反复进出直播间 10 次后,手表进程内存无持续爬升,不触发系统杀进程或卡帧
- 最低清晰度连续播放至少 1 小时,不出现低电量告警或过热保护
- 后台挂起 30 分钟后,弹幕 WebSocket 已断开,数据流量只剩心跳级别
- 至少 2 块不同屏幕形态(圆形、方形)的设备通过布局验收:文字不截断、卡片可点中
- Wi-Fi 与移动网络来回切换时不崩溃,播放能自动恢复
下一步:跑通真机,再扩展到其他穿戴平台
- 先在一块 Wear OS 真机(或对应模拟器)上跑通智能手表直播的"列表 → 播放"全链路,用系统开发者工具记录内存与电量曲线,回填到验收清单。
- 验收通过后,把同一套 3 处改造移植到其他穿戴平台,观察功耗策略在不同平台需要重新调整的部分。
- 在 LiveMessage 结构上试验语音输入发送弹幕的入口,先作为实验性功能,不进默认开关。
- 每次改造后更新 README.md 中的验收口径,后续加新平台时能直接照单验收。
【免费下载链接】dart_simple_live简简单单的看直播项目地址: https://gitcode.com/GitHub_Trending/da/dart_simple_live
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考