上个月音乐 App 会员又涨价,一年两百多。涨就涨吧,关键是歌单里灰了一片——好几首听了十几年的歌,突然"因版权问题暂时下架"。
我坐在客厅地板上发了会儿呆,想起硬盘里还躺着从大学攒到现在的音乐文件夹。最早是 2008 年在网吧用 U 盘拷的 mp3,后来是 ape、flac,再后来是各种无损资源。二十年,差不多 60 个 G。
这些歌在硬盘里躺了这么多年,一个能听的入口都没有。
那就自己搭一个。
为什么是 Navidrome
自建音乐服务器可选的不多,主流是这几个:
| 方案 | 特点 | 我的判断 |
|---|---|---|
| Navidrome | Go 写的单文件,资源占用小,兼容 Subsonic API | 选它 |
| Plex / Emby | 功能全,但音乐是附属功能,还要会员 | 太重 |
| Ampache | 老牌 PHP 方案,配置繁琐 | 折腾成本高 |
| Koel | 界面好看,但更新慢 | 生态一般 |
选 Navidrome 的核心理由是它兼容 Subsonic API。这意味着市面上几十个音乐客户端都能直接连它,iOS、Android、桌面、甚至车机,不用等官方出 App。
而且它真的很轻。一个 Go 编译的单文件容器,60G 的库跑起来内存占用一百多兆。
部署
services:
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
restart: unless-stopped
ports:
- "4533:4533"
environment:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: ""
volumes:
- ./navidrome/data:/data
- /mnt/music:/music:ro
ND_SCANSCHEDULE: 1h 是每小时扫一次新歌,加了歌不用手动触发。
/music:ro 挂只读,避免误删——这一点很重要,我第一次跑的时候差点把源目录搞乱。
起来之后访问 http://IP:4533,第一次进去建管理员账号,然后指向 /music 目录开始扫描。
目录结构决定刮削质量
Navidrome 没有复杂的元数据抓取服务,它主要靠文件名和 ID3 标签来识别歌。
官方推荐的目录结构:
/music
/周杰伦
/范特西
01-爱在西元前.flac
02-爸我回来了.flac
歌手 / 专辑 / 曲目 三层,文件名带序号和歌名。这个结构它认得最准。
我一开始把歌全平铺在一个文件夹里,文件名是"周杰伦-范特西-01-爱在西元前.mp3"这种。扫出来专辑全乱了,同一张专辑被拆成好几个。
如果库里已经乱了,别硬扫,先整理。 我花了一个晚上写了个脚本按文件名正则重排目录,比手动快得多。
标签:中文乱码这一关
整理完目录,扫出来发现一半歌名是乱码:"鍠滄浣犵殑"这种。
原因不复杂:早年 mp3 的 ID3v2 标签用的是 GBK 编码,Navidrome 按 UTF-8 读,就对不上了。
处理办法是批量转码。我用 mp3tag(Windows/macOS 都有):
- 全选文件
- 工具 → 选项 → 标签 → 编码设成"读取 GBK"
- 再执行"保存",写入时用 UTF-8
macOS 上也可以用命令行:
# 需要安装 eyeD3 或 mutagen
pip3 install mutagen
写个小脚本扫一遍,把有非 ASCII 乱码的标签重写。不过对大多数人来说,mp3tag 图形界面更快。
封面缺失是第二个问题。Navidrome 会找专辑目录下的 cover.jpg 或 folder.jpg,没有就显示占位图。
我给每个专辑目录补了 cover.jpg,用 MusicBrainz Picard 批量匹配封面。这个工具能按专辑名、艺人名去数据库匹配,命中率挺高,中文歌差一些,得手动挑。
扫描:第一次会很慢
60G 的库,第一次扫描跑了四十多分钟。
不是 Navidrome 慢,是要读每个文件的标签、算资源指纹。之后的增量扫描就快了,只扫新文件。
扫描期间后台能看到进度,也能在「活动」页面看日志。如果卡住不动,通常是某个文件损坏,日志里会有具体路径。
我遇到过一个 flac 文件损坏,扫描到那个专辑就停住,删掉那个文件就好了。
客户端
这是 Navidrome 最爽的地方——Subsonic 协议,客户端随便挑。
iOS:
- Amperfi(免费,界面干净)
- play:Sub(付费,功能全)
- Sonixd 的移动版
Android:
- Symfonium(付费,但值得,离线缓存做得好)
- Subtracks(免费开源)
- DSub(老牌,功能多但丑)
桌面:
- Web 界面直接用
- Sonixd(Windows/macOS/Linux)
我手机用 Symfonium,电脑上直接开网页。两边的播放进度会同步——同一首歌在手机上听到一半,回到电脑上打开,接着放。
这个体验跟商业平台已经没区别了,而且歌是自己的。
外网访问
局域网内直接用 IP 就行。出门在外想听,得做外网访问。
我这边是用 Nginx Proxy Manager 反代(之前写过那篇),把 music.xxx.com 指到 192.168.1.200:4533。
需要注意两点:
一、Subsonic 客户端要填完整地址,包括协议和端口。有的客户端对反代后的路径很挑,ND_BASEURL 要跟实际访问路径一致,不然封面、流媒体地址会错。
二、流媒体走反代,带宽要够。 一首 flac 几十兆,外网听会卡。Navidrome 支持转码——在设置里可以配"外网播放时降码率",比如转成 128kbps 的 mp3 流。我配了 192kbps,手机流量听不心疼,音质也够。
四个坑
坑一:flac + cue 不分轨
早年下的无损很多是一整个 flac 加一个 cue 文件。Navidrome 不认 cue,会把它当成一首几十兆的"超长歌曲"。
处理:用 foobar2000 或 shntool 按 cue 分轨,分完把 cue 删掉。
shnsplit -f album.cue -o flac album.flac
坑二:同一张专辑多个版本
比如《范特西》有普通版和一个"十周年纪念版",标签里专辑名不一样,扫出来就是两张专辑,封面打架。
处理:统一专辑名,版本信息写进备注或者放不同目录。
坑三:中文搜索搜不到
Navidrome 的搜索是按标签匹配的,如果标签里歌名是繁体,你搜简体就搜不到。
处理:统一成简体,或者客户端里用拼音首字母碰运气。
坑四:外网播放卡顿
前面提过,flac 直传带宽不够。配转码,或者把常用歌单提前下到手机上离线。
这套东西的真实用处
搭完两周,我基本没再打开过音乐 App。
- 通勤路上手机听,离线缓存好,地铁里没信号也不断
- 家里音响用平板连,同一个库
- 电脑上一边干活一边听,网页端
最舒服的是不用再担心下架。歌在硬盘里,服务器在自己家,谁也拿不走。
缺点也有:
- 新歌不会自动来,得自己找资源
- 60G 的库放在外接硬盘上,硬盘挂了就全没了——我另外做了一份冷备
- 出门在外听要流量,无损歌单很吃流量
最后
这件事做完,我才意识到"音乐会员"卖的不是歌,是入口。入口自己搭一个,歌本来就在你硬盘里。
如果你硬盘里也躺着几百首歌,又不想再交年费,Navidrome 是最省事的方案——一个容器,一个网页,剩下就是整理标签的耐心。
如果你也在折腾这套东西,碰到卡住的地方,可以加我微信 lige0552 聊聊。白天要上班,消息回得慢,看到都会回。