早上好,我是まさきん。
我家平时经常用 Sonos 放音乐。不过想跟着一起唱 J-POP 的时候,总是记不住歌词。于是今天早上,我做了一个把歌词显示在屏幕上的小应用。整个过程都是边和 Claude 商量边完成的。
※本文信息以发布时为准,最新条件请以官方网站为准。
- 做了一个应用:跟随 Sonos 正在播放的歌曲,手机上会高亮显示当前这一行歌词
- Sonos 的信息由家里的 Mac 直接读取
- 歌词来自免费的公开数据库「LRCLIB」
- 分享给家人用的是 Tailscale,额外费用为 0 日元
- 从开始商量到在妻子的 iPhone 上跑起来,只用了早上 约 2 小时
做了什么
用手机打开后,就会显示 Sonos 正在播放的歌曲的歌词。正在唱的那一行会发白光。画面会自动滚动,把当前行保持在正中间。
实际用下来,还有几个功能特别方便。
- 点一下某一行,Sonos 就会从那一行开头重新播放
- 对不上的歌可以用「提前/延后」每次微调 0.3 秒,并且按歌曲记住
- 可以从「候选」里切换到另一个版本的歌词
- 就算不同房间在放不同的歌,也能选择房间
- 可以添加到主屏幕,显示期间屏幕不会熄灭
点行重播比想象中好用得多。「副歌再来一遍」一下子就能做到。说不定还能拿来练歌。
起因是一句「能做出来吗」
早上 6 点 40 分左右,我问 Claude「这个能做出来吗」,一切就从这里开始。它首先确认的是:音乐在哪里播放。
答案是 Sonos。我还告诉它只在家里用,而且家里的 Mac 一直开着。有了这两点,整体结构基本就定下来了。
我也提到平时听的大多是 J-POP。这成了选择歌词来源的决定性因素。我的感受是:一开始先定好「在哪里」「放什么」,后面的讨论就会快很多。
整体结构
整个系统由 3 个部分组成。
- Sonos 音箱本体(在家庭网络里)
- 运行在家里 Mac 上的小型中转服务器
- 用手机打开的页面(PWA)
Mac 上的中转服务器从 Sonos 读取歌名和播放位置。同时从歌词数据库获取带时间戳的歌词。手机每 1 秒问一次 Mac「现在播到哪了?」,然后决定高亮哪一行。
中转服务器是请 Claude 在不使用任何外部包的前提下写的。Mac 这边没有额外安装任何东西。既然是在家里跑,我觉得组件越少越安心。
在家里直接读取 Sonos
Sonos 其实也有官方的云 API。不过需要注册开发者账号、准备登录授权等。
| 读取方式 | 准备工作 | 运行位置 | 适合的用法 |
|---|---|---|---|
| 官方云 API | 开发者注册、登录授权 | 任何地方 | 想在外面也能操控 |
| 在家里直接读取 | 几乎不需要 | 家庭网络内 | 只在家里使用 |
这次只在家里用,所以选择了直接读取的方式。Sonos 在家庭网络里就会告诉你歌名和播放位置。我家有 5 台,都被自动发现了。
多个房间合并播放的「分组」也能直接读取。所以即使不同房间在放不同的歌,也可以选择。
歌词取自 LRCLIB
歌词需要带时间戳的版本,也就是「这一行从 1 分 23 秒开始」这样的信息。这种格式叫做 LRC。
我比较了几个候选来源。
| 来源 | 费用 | J-POP 带时间戳歌词 | 易用性 |
|---|---|---|---|
| LRCLIB | 免费 | 知名歌曲相当多 | 不需要 API 密钥就能查 |
| 音乐流媒体服务的歌词 | 视订阅而定 | 很丰富 | 没有面向个人的接口 |
| 日本的歌词网站 | 可免费浏览 | 很丰富 | 没有面向个人的接口 |
LRCLIB 是由志愿者收集整理的公开数据库。J-POP 到底收录了多少,我实际试了几首。
- 米津玄师、YOASOBI、Official髭男dism、Vaundy、Mrs. GREEN APPLE 都有带时间戳的版本
- Spitz、优里、Creepy Nuts 也有带时间戳的版本
- 歌名完全匹配找不到的歌,用模糊搜索也能找到
- 有些童谣找不到
如果是一家人常听的热门歌曲,大部分应该都够用。对于找不到的歌,我请 Claude 做成了自己放一个 LRC 文件就能用的形式。
卡在了罗马字歌名上
刚做好就遇到了麻烦:显示出来的歌词是罗马字。
原因出在正在播放的 YouTube Music 的歌曲信息上。艺人名是以「Aimyon」「Kenshi Yonezu」这样的罗马字传过来的。直接拿去搜索,结果就选中了罗马字版的歌词。
于是我请 Claude 把歌词中日文所占的比例加入评分,优先选择假名和汉字较多的版本。同时,艺人名是罗马字还是日文的差异,不再作为扣分项。
歌名方面也下了点功夫。因为有些歌带英文副标题,比如日文歌名后面接着「- One Voice」这样的形式。所以也会用去掉副标题和括号后的名字再搜一次。
- 如果日文版里混有译词,有时会选中罗马字版
- 米津玄师的《Lemon》就是这种情况
- 遇到这种情况,可以从画面上的「候选」切换到其他版本
把误差压到 1 秒以内的小技巧
另一个问题是时间误差。Sonos 返回的播放位置是舍去小数、只精确到秒的数字。直接用的话,最多会差 1 秒。
对歌词来说,1 秒其实挺大的。换行一慢,就赶不上开口唱了。
所以我请 Claude 稍微动了点脑筋。真实位置一定在「返回的秒数」和「再往后 1 秒」之间。页面这边自己推进的预测值,会一直被限制在这个范围内。
每秒询问一次,范围就会逐渐收窄。测试中,误差控制在了 0.5 秒以内。搞懂原理的那一刻,还挺爽的。
在手机上用需要 HTTPS
一开始,我是在家庭网络里直接打开的。虽然能用,但有两个问题。
- 就算添加到主屏幕,也不能像应用一样打开
- 唱到一半,屏幕会变暗
这两个功能都要求页面通过 HTTPS 打开。防止屏幕熄灭的功能(Wake Lock)是以安全连接为前提的。
这时派上用场的,是我本来就装着的 Tailscale。用 Tailscale 的「serve」功能,Mac 上的服务器就有了带正规证书的 URL。也不再需要固定 IP 地址。
家里的这些系统,全都跑在网络通信之上。家人手机上用的东西越多,就越会在意线路和套餐的内容。
分享给家人就用 Tailscale
我也想让妻子用上,所以考虑了分享方式。
| 分享方式 | 对方要做的事 | 使用体验 | 需要注意的点 |
|---|---|---|---|
| 用家里 Wi-Fi 直接打开 | 无 | 屏幕会熄灭、不能作为应用使用 | 出门就用不了 |
| 邀请加入 Tailscale | 安装应用并登录 | 可以作为应用使用 | 多了一个 VPN 应用 |
| 给公开 URL 加登录 | 首次通过邮件认证 | 可以作为应用使用 | 设置更麻烦 |
妻子之后也打算通过 Tailscale 使用其他应用,所以选择了邀请的方式。Tailscale 面向个人的免费套餐最多支持 6 人。一家人用完全够了。
在妻子的 iPhone 上,步骤只有下面 4 步。
- 打开邀请链接,创建账号
- 在 App Store 安装 Tailscale,用同一个账号登录
- 允许「添加 VPN 配置」
- 用 Safari 打开 URL,添加到主屏幕
妻子的 iPhone 看不到 Mac 的原因
明明按步骤做了,妻子的 iPhone 却看不到 Mac。Tailscale 应用显示「已连接」,但能看到的设备只有她自己那一台。
打开管理后台一看,设备状态显示「Owner needs approval」。原来不是设备,而是用户在等待审批。
根据官方说明,2025 年 5 月 22 日之后创建的 tailnet 默认开启用户审批。审批前的用户可以连上 Tailscale,但无法与其他设备通信。
在管理后台的「Users」里批准之后,马上就能看到了。邀请家人时,记住这一点会比较好。
让 Mac 持续运行的小技巧
中转服务器是用 Mac 的常驻机制(launchd)运行的,设置成了崩溃后会自动重启。
我家有一条规矩:用 launchd 直接启动程序时,有时会因为读不了「文稿」文件夹而崩溃。所以统一改成通过 shell 来启动。
这次 Claude 一开始也写成了直接启动的形式。我家的检查机制发现了这一点,马上就让它改好了。我觉得把家里的规矩写成文档,在和 AI 一起干活时也很管用。
花费与时间
| 项目 | 内容 |
|---|---|
| 额外费用 | 0 日元 |
| 读取 Sonos | 在家里直接读取(无需注册) |
| 歌词 | LRCLIB(免费) |
| 分享给家人 | Tailscale 免费套餐 |
| 所用时间 | 早上 6 点 40 分开始商量 → 9 点左右在妻子的 iPhone 上跑起来 |
Mac 用的是本来就一直开着的那台,没有新买任何东西。
适合的人与不适合的人
比较适合下面这样的家庭。
- 用 Sonos 放音乐,经常一家人一起唱
- 家里有一直开着的 Mac 或 PC
- 在用 Tailscale,或者想试试
另一方面,也有不太适合的情况。
- 家里没有一直开着的电脑
- 经常用 Sonos 播放电视或外部输入的声音(收不到歌名,所以不会显示歌词)
- 经常听童谣或不太知名的歌
- 家里有一直开着的 Mac 或 PC
- 用 Sonos 播放音乐流媒体服务的歌曲
- 家人愿意在手机上装一个应用
- 找不到歌词的歌,愿意自己准备
常见问题
Q. 需要编程知识吗?
这次所有代码都是 Claude 写的。不过,如果懂一点 Mac 终端和 launchd 的概念,会更安心。遇到问题时,也更容易一起判断哪里出了错。
Q. Spotify 或 Apple Music 也能用吗?
只要是在 Sonos 上播放,歌名和播放位置都能从 Sonos 拿到。所以流媒体服务的种类应该关系不大。我自己只试过 YouTube Music。
Q. 找不到歌词的歌会怎样?
画面上会显示「没有找到歌词」。可以从「候选」里重新找其他版本。如果还是没有,自己放一个 LRC 文件,下次就能用了。
Q. 在家外面也能用吗?
通过 Tailscale 的话,在外面也能打开。不过显示的是家里 Sonos 正在放的歌。并不会显示你在外面听的歌的歌词。
Q. 歌词时间对不上怎么办?
用画面下方的「提前/延后」,每次可以微调 0.3 秒。调整量会按歌曲记住,下次就直接生效。
Q. iPhone 上也能保持屏幕不熄灭吗?
只要是通过 HTTPS 打开,较新的 iOS 应该都有效。旧版 iOS 从主屏幕打开时有时会不生效。把 iOS 更新到最新会比较放心。
Q. 每月需要花钱吗?
我家是 0 日元。LRCLIB 免费,Tailscale 在面向个人的免费套餐范围内。大概也就是 Mac 的电费吧。
参考的官方信息
- LRCLIB(带时间戳歌词的公开数据库)
- LRCLIB API 文档
- Tailscale serve(在 tailnet 内公开服务的功能)
- Tailscale 启用 HTTPS 证书
- Tailscale 用户审批
- Tailscale 价格方案
- MDN Screen Wake Lock API
- Sonos 开发者文档
关于家庭自动化,我还写过其他文章。Cloudflare Workers 免费额度下 Cron 不够用的时候,以及把学校通知显示到家里电子看板的系统,也欢迎一起看看。
总结
从一句「能做出来吗」开始,用一个早上的 2 小时,做到了家人都能用的程度。难点大概只有罗马字歌名和时间误差这两个。两者都是边用真实歌曲测试边修好的。
一家人一边看着歌词一边唱歌,比想象中还要开心。如果你家也有 Sonos,或许值得一试。
本文包含联盟营销广告。如果您通过本站链接申请相关商品或服务,我们可能会从合作企业获得报酬。此外,运营者是乐天集团的员工,也可能通过员工推荐计划获得报酬。文章内容与评价均基于运营者的真实体验与调查完成,与是否存在广告无关,但请您在阅读前了解上述关系。详情请参阅免责声明与联盟营销说明。 免责声明与联盟营销说明
本文包含机器翻译内容。正式条件请以乐天移动官方网站的多语言页面为准。
如果您对乐天移动的通信区域·信号状况有疑问,可以通过官方的 电波改善调查申请表 进行咨询。