自建音乐串流服务探索

听歌这件事似乎变得越来越麻烦。
2014 年之前,我主要用 QQ 音乐听歌,那时随便一个平台都有着丰富的曲库。2014 年,我转到了眉清目秀的网易云音乐,那时的网易云音乐还很纯粹,后来国内音乐进入了「版权时代」,看着歌曲一天天变灰也坚持用着,直到开始不务正业引入短视频等各种臃肿功能,2018 年的下架周董歌曲「打包收费」事件,让我直接卸载了网易云音乐,即使还有很长时间的会员没到期。此时国内音乐进入了「独家版权时代」,不同时开几个平台的会员很难有好的体验。好在及时醒悟过来放弃了国内音乐平台,之后一直用着 Apple Music 搭配 Spotify,算是比较省心。不过为了给消费降级趋势出一份力,去年底也取消订阅了使用 8 年的 Apple Music。
其实也是发现自己对音乐曲库的需求越来越小了,平时基本在听老歌,听歌更多时候是为了作为 BGM 增加点氛围感。我对华语音乐的记忆似乎还停留在 10 年前,对外语音乐的记忆停留在 5 年前,可能一代人有一代人的歌,新一代的歌我也很难去欣赏。现在只是偶尔去听下自己关注歌手的新曲,或者 Spotify 推荐歌单。既然如此,不如自建音乐串流服务,整理出自己的专属曲库,体验应该也差不了太多。
自建音乐服务项目有不少,我主要是听个响,有损 MP3 320 Kbps / AAC 256kbps 足以,还省空间,所以 Roon 这类很贵专业的方案是直接跳过的。同时我的音乐文件都习惯先通过 MusicBrainz Picard 整理标记,所以对服务端功能也没太多要求。过去一年里陆续尝试过 Emby/Jellyfin, Navidrome, Gonic, LMS (Lightweight Music Server) 等服务,网上能搜到很多介绍文章,这里不再多说。同时也把 iOS App Store 里能搜索到的对应客户端几乎试了个遍。
就结论来说,过去大半年里我都用着 Navidrome 服务端搭配 Amperfy 客户端。整体比较满意,美中不足的是 Navidrome 还不支持读取外挂歌词文件(等了快一年的 PR,应该也快了)。因为这个问题有段时间换到过 Jellyfin 搭配 Manet/AmpFin,但体验下来还是不如 Navidrome + Amperfy 简单顺滑,加上 Amperfy 后来新增了 macOS 原生客户端支持,毫不犹豫的换了回来并使用到现在。

当然,我也知道还有一个热门的组合没尝试,经常看到网友对 Plex 的音乐软件 Plexamp 赞美有加,但很多特性需要开通 Plex Pass 会员才支持,而我对 Plex 的印象一直不太好。以前搭建过 PMS (Plex Media Server),必须用 Plex 账号联网登录,各种隐私数据收集拉满,后来还禁止托管在 Hetzner 上。加上 Plex 一直在向流媒体服务转型,混乱的社交名流主页,对自建用户的体验越来越不重视,所以一直没尝试。但前几天看到 Plex Pass 即将涨价和阿根廷区低价 Lifetime Plan 的消息后,还是按耐不住,顺手搭上了末班车,可以说这次购买几乎是冲着 Plexamp 去的。

几天体验下来,先说服务端 PMS,抛开我对 Plex 的「恶意」不谈,Plex 确实比 Emby/Jellyfin 更加好看和流畅,使用上也更省心,音乐库的管理功能上倒是都差不多。在歌词这一块,Plex 目前和 Navidrome 相反,不支持内嵌歌词,只支持外挂歌词,不过如果没有本地歌词 Plex 会自动通过 LyricFind 寻找(需要 Plex Pass),可惜对于中文歌曲支持一般。
再说客户端 Plexamp,基础功能大家都一样,Plexamp 的亮点在于 UI 设计、音乐无缝切换和基于音乐(库)分析的推荐/电台功能。手机端上的体验比较满意,但不多做夸奖。桌面端上就比较失望了,Electron 应用在我这里向来是扣分的,但也不是不能接受,除非太敷衍,Plexamp 桌面端几乎就是移动端的放大版,没做过多的适配。同时也遇到了不少 bug,比如左上角关闭窗口后,后台仍在运行,但无法恢复窗口显示,只能退出进程重新打开 怪不得默认隐藏窗口控件。也发现即使你下载了整个歌单,仍然只有从下载分栏进入歌单播放才会使用本地文件,如果从其他入口播放该歌单还是会再次下载缓存到硬盘(已在设置中开启始终优先选择下载的媒体),把缓存和下载功能分开看待的逻辑有点难以理解,于是我选择了直接把缓存拉满。更可惜的是我发现的不少 bug 都能在一些多年前的反馈帖子中找到,却不了了之或无人问津。
不过如果再次抛开我对 Plex 的「恶意」不谈,Plexamp 整体体验是不错的,对于多数想自建的用户来说算的上是比较出色的方案,无论是音乐库管理,UI 界面,还是功能性相比其他几个平台都有一定的优势。但 Plex Pass 会员现在并不便宜,如果只是为了音乐串流服务的话就不太值了。
总的来说,目前我应该会继续主力使用 Navidrome + Amperfy,等哪天 Plexamp macOS 客户端的体验更好了可能会全面切过去。其实对于自建音乐串流服务来说,选择平台往往是最简单的部分,最麻烦的还是资源获取与整理,无论是自购转录还是网上找都很花时间。好在我喜欢的歌不算太多,一年下来零零散散着整理也差不多了,不然还是建议直接订阅音乐流媒体更加舒畅。
小剧场:消失的 Plex 外挂字幕与 Plexamp 歌词
既然买了会员,也顺便再次试下 Plex 的影视媒体库,相比 Emby/Jellyfin 确实有独特的优点,但也有糟心的问题。测试网页播放时,发现 Plex 对于外挂 ASS 字幕的支持有个老问题,我的 PMS 搭建在 VPS 上,所以关闭了转码,直接通过串流播放,但 Plex 的逻辑是只要字幕包含不支持的特效就会强制转码烧录,在设置中修改 Plex Web 播放器的固化字幕选项为「仅图像模式」可以解决部分问题,但其他情况下还是会遇到错误提示「该服务器没有足够性能用于转化视频」,不加载字幕则可以正常播放,经测试同一个视频和字幕在 Jellyfin 网页播放没有问题 当然 Jellyfin 有他自己的祖传方块问题。
那我放弃网页播放,改用第三方客户端(Infuse/Vidhub)播放。但这时发现连字幕的选项都没有了,直接无法获取。搜索半天在 Plex 论坛上发现有人提到可能是 Nginx 反代问题,试着添加下面配置后终于可以获取字幕了。
location /library/streams/ {
proxy_pass_request_headers off;
proxy_pass http://127.0.0.1:32400;
}
解决问题后,满意的打开 Plexamp 准备听音乐放松下,却发现所有歌曲都无法显示歌词了… 一开始还以为是客户端的 bug,重启重装研究了好一会才想到可能是修改 Nginx 配置导致的问题,注释掉后果然又可以正常获取歌词了。
于是猜测可能是某个 header 导致了无法获取字幕,测试以下配置:
location /library/streams/ {
# 默认关闭转发 header
proxy_pass_request_headers off;
# 转发 Plex 自定义 header
proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
proxy_set_header X-Plex-Device $http_x_plex_device;
proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
proxy_set_header X-Plex-Platform $http_x_plex_platform;
proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
proxy_set_header X-Plex-Product $http_x_plex_product;
proxy_set_header X-Plex-Token $http_x_plex_token;
proxy_set_header X-Plex-Version $http_x_plex_version;
proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
proxy_set_header X-Plex-Provides $http_x_plex_provides;
proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
proxy_set_header X-Plex-Model $http_x_plex_model;
proxy_pass http://127.0.0.1:32400;
}
默认关闭 header 转发,只转发 Plex 自定义的 header,终于同时解决了两个问题。
EOF
如果你觉得这篇文章还不错,可以考虑支持作者。