跳到主要内容
我本来只想用 spotatui 放本地文件,结果 cargo install 装完只剩一个 Spotify

我本来只想用 spotatui 放本地文件,结果 cargo install 装完只剩一个 Spotify

钻牛角
钻牛角

· 阅读约 5 分钟

我想找个终端里能放本地文件夹的音乐播放器,不想再折腾 GUI 占内存。看到 spotatui 说接了七类音源——本地、电台、YouTube 都有,就一把梭:

cargo install --locked spotatui

编译完,启动,它问我“你想启用哪些音源?”——我心想不错,还能选。结果列表里就一个 Spotify。

你说气不气。

我一开始以为是快捷键没找对。按 d 切音源与设备,还是只有 Spotify。按 ? 翻出全部按键,里面没有“添加本地文件夹”这回事。我甚至怀疑装错包了,反复确认两遍,没装错。

这一步我卡了俩小时,中间一度怀疑自己老花,菜单里那么大一个“本地文件夹”就是看不见。后来才反应过来:问题不在界面,在安装方式。

文档其实写得挺清楚,是我自己没细看,哎。预编译的二进制默认把全部音源、MCP 服务器、AI DJ 都打进去;源码构建的默认 features 只开 Spotify,其他音源得自己加。

也就是说,我照着 README 里那行 cargo install 命令装出来的,根本不是项目主页宣传的那个多音源播放器。是个半成品——还是个要 Premium 才能用的半成品。好家伙。

然后我就开始钻:为什么源码构建的默认偏偏是 Spotify?这个播放器接了本地文件夹、Subsonic、网络电台、YouTube、Qobuz、Apple Music。几类音源里,Spotify 是少数需要付费账号的之一。剩下的本地文件不用账号,Subsonic 不用,电台不用,YouTube 虽然依赖 yt-dlp 但也不用账号。

按逻辑,源码构建默认应该开这些零门槛的,把要付费的当可选项。结果它反着来——默认给你一个要订阅的,把不用钱的藏进 feature。

我猜这跟项目血统有关。spotatui 最初是从 spotify-tui 分叉出来的,Spotify 集成是基因,其他音源是后来才加的。feature 默认值没跟着产品重心变,还是老思路。所以 cargo install 的人拿到的是一个 Spotify 客户端骨架,不是那个能放本地、能听电台的播放器。

这种祖传默认值其实很常见。前端也有——比如某个构建配置里还留着三年前的 fallback,早没人懂了,但一直没删。Spotify 在这里就是这么个 fallback:它曾经是唯一音源,所以 feature 开它最省事。

但如果你只看项目主页,会觉得这是“一个多音源音乐播放器”。然后你从一个标准的 Rust 安装路径进去,拿到的却是个 Spotify 登录框。这中间的落差,比“装不上”还气人——因为你以为东西都在,结果只是你以为。

再往下钻,它的音源架构其实不差。本地文件、Subsonic、电台、YouTube、Qobuz 由自研音频引擎播;Spotify 内容也能直接在 spotatui 里播,或者推给 Spotify Connect 设备、局域网 Cast/Connect 音箱。Apple Music 更直白,就是个遥控器,真正播放的是 macOS 上的 Music 应用。

也就是说,Spotify 在架构上其实是个外挂,主力是那些自有引擎的音源。

结果 cargo install 默认把这个外挂当门面。这谁受得了。

说到 Spotify 这个集成,他们做了一件比 spotify-tui 时代舒服的事:不用自己注册开发者应用、不用填 client ID。内置客户端直接给你配对码登录,省了那套“去 Spotify 开发者后台建个 app”的破流程。这确实省事。但这件事反过来也强化了那个误会——源码构建装完只剩 Spotify,你甚至会以为这项目就是“终端版 Spotify”,把那些本地和开放音源的事情全丢掉了。

再看得更细一点:它的队列和同步机制,才是它真正想干的事。同一个队列能混合不同音源的曲目,播放列表能镜像同步到 Spotify、Qobuz、Subsonic 或 YouTube。这意味着内部数据模型是统一的,音源是插件化后端。这个能力做出来,用户拿到的应该是一面“音源墙”,不是一个 Spotify 登录框。

可安装方式挡在了这前面。官网脚本装的预编译二进制是全家桶,Windows 的 PowerShell 和 winget 也是;只有 cargo install 和 Nix flake 走源码构建,默认只 Spotify。更别说包管理器装完还要记得关自动更新,不然自更新和包管理器打架:

behavior.disable_auto_update = true

这些安装方式之间默认行为的差异,再加上自动更新的开关,说明它还没有把“发行”这件事统一成一个说法:你从哪里装,决定了你能用哪些音源,也决定了它会不会自己更新。这跟很多 Rust CLI 工具一样,功能被 feature flags 切得足够碎,但用户没兴趣在装之前先读一篇 feature 表。

这里我列张表,免得你也被坑:

安装方式默认音源备注
官网安装脚本(macOS/Linux/WSL)全部音源 + MCP + AI DJ预编译二进制
Windows PowerShell / winget全部音源 + MCP + AI DJ预编译二进制
cargo install --locked仅 Spotify需额外 features
Nix flake仅 Spotify需额外 features
Homebrew / AUR / .deb / Void取决于构建方装之前得看清楚

拉胯的还是源码构建这俩——尤其是 cargo install,因为你本来就是 Rust 用户,想快速折腾一下,结果拿了个半成品,还得自己拼特性。文档没在安装命令旁边贴脸标红,哎。

我还没重新用完整 features 编译一版去试那些本地和电台音源,今天时间不够了,先把默认值这头牛钻穿。等哪天我把它那个 AI DJ 的 MCP 也摸一遍,再回来补另一个牛角。

最后,说个跟这篇八竿子打不着的——昨晚我试着让我的一个 agent 通过 MCP 给我当 DJ,它给我推了一串 YouTube 上的现场翻唱,还振振有词说“氛围到了”。氛围是到了,我本地 flac 一个没播,真的会谢。跟这头牛一个毛病:默认走最远的那条路。下次我钻 AI DJ 的时候,看看是不是又是另一个“默认只 Spotify”。扯远了,反正——嘿嘿,下次见。

钻牛角
钻牛角

逮住一个前端小知识点挖到底:现象→实验→兼容性表格→闲聊,配 demo 玩梗。

查看主页 →