YaBooks Sync
一款非官方的 Garmin Connect IQ 应用:通过 Wi-Fi 把 Yandex 图书的有声书章节下载到手表,离线播放,无需手机。手表从手机停下的位置继续,手表上听过的进度也会回传到 Yandex 图书。
- 角色
- 全流程
- 技术栈
- Monkey C · FastAPI · ffmpeg
- 周期
- 3 天进入测试版
- 年份
- 2026

需求
跑步和路上听有声书时不想带手机,而 Garmin 手表自己就能播放音频。Connect IQ 上没有 Yandex 图书的客户端。另一个难点是进度:在手机上开始一章,在手表上继续,再回到手机——各处都应该是同一个位置。
方案
手表通过 Wi-Fi 下载章节,并提前储备几小时的内容——1 到 12 小时,默认 3 小时——无需手机即可播放。进度双向同步,精确到秒,听完的章节自动删除。
登录通过 OAuth Device Flow 输入验证码——手表上不输入密码;快进 30 秒、快退 15 秒,音质 64 或 192 kbps。这是继 YaMusic Sync 之后该系列的第二款应用:共用同一套框架,标识也是同样的黄色。
开发过程
全部由我一人完成:研究了非公开的 API,用 Monkey C 写了应用,用 FastAPI 写了代理,准备了商店的图片和文案。从第一次提交到可用的 0.1.6 测试版约 3 天,共 6 个测试版构建;首次发布前代码经过对抗式评审,修复了 11 个缺陷。
难点
手表上的响应不能超过约 21 KB,而《战争与和平》的目录有 475 KB、321 章:代理把它压缩到 7.8 KB。CMAF 在模拟器里能被接受,在真实手表上却无法播放:服务器用 ffmpeg 重新封装章节,13 小时的书从 378 MB 减到 201 MB。REST 写入进度返回 200 却什么都没改——进度只能由 GraphQL mutation 推动。
用到的技术
手表端是 Monkey C 与 Connect IQ SDK 9:Toybox.Media、SyncDelegate,登录走 OAuth 2.0 Device Flow。服务端是 Python 3.12 与 FastAPI,配合 httpx:访问 Yandex 图书的 REST API,用 GraphQL mutation 写入进度,用 ffmpeg 把 CMAF 重新封装为 MP4(单声道,32 kbps),并维护最多 2 GB 的 LRU 缓存。服务器上有 Docker、nginx 和 Let's Encrypt;117 个 pytest 测试。





