惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

PCI Perspectives
PCI Perspectives
P
Proofpoint News Feed
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
T
Tenable Blog
I
Intezer
Scott Helme
Scott Helme
Hacker News - Newest:
Hacker News - Newest: "LLM"
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Security Latest
Security Latest
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
T
The Exploit Database - CXSecurity.com
The Last Watchdog
The Last Watchdog
N
News and Events Feed by Topic
Google DeepMind News
Google DeepMind News
S
Secure Thoughts
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Hacker News: Front Page
L
LINUX DO - 最新话题
U
Unit 42
宝玉的分享
宝玉的分享
Stack Overflow Blog
Stack Overflow Blog
L
LINUX DO - 热门话题
IT之家
IT之家
C
Cybersecurity and Infrastructure Security Agency CISA
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
博客园_首页
爱范儿
爱范儿
T
Threatpost
小众软件
小众软件
A
Arctic Wolf
Jina AI
Jina AI
H
Help Net Security
Webroot Blog
Webroot Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Cyberwarzone
Cyberwarzone
博客园 - 聂微东
月光博客
月光博客
The Register - Security
The Register - Security
Martin Fowler
Martin Fowler
博客园 - 司徒正美
V
V2EX
博客园 - Franky
B
Blog
B
Blog RSS Feed
H
Heimdal Security Blog
WordPress大学
WordPress大学
A
About on SuperTechFans

无梦梦游记

笔记·独立动画的基本工作流 | 无梦梦游记 随笔·相形见绌 | 无梦梦游记 随笔·浅谈四次方与中国动画 | 无梦梦游记 2025 | 无梦梦游记 昼梦·问天坠星辞 | 无梦梦游记 笔记·三大构成————色彩构成 | 无梦梦游记 笔记·三大构成————平面构成 | 无梦梦游记 影评·罗小黑战记2简评 | 无梦梦游记 近况·羊城行记 | 无梦梦游记 随笔·为了记念,所以忘却 | 无梦梦游记 笔记·《吊带袜天使》的视听语言风格分析 | 无梦梦游记 笔记·以《化物语》与《再见绝望先生》为例,分析新房昭之监督动画的视听语言风格 | 无梦梦游记 随笔·未竟之作 | 无梦梦游记 2024 | 无梦梦游记 笔记·RDP优化小记 | 无梦梦游记 随笔·夏日大三角、七月七与失恋 | 无梦梦游记 酒吧 | 无梦梦游记 关于爱的琐碎与观念 | 无梦梦游记 在Zerotier网络中加入DNS | 无梦梦游记 四月伪实习日志 | 无梦梦游记 2023 | 无梦梦游记
Navidrome + StreamMusic——你的下一个网易云 | 无梦梦游记
河城凌风 · 2025-03-15 · via 无梦梦游记

需求

原本我是一直使用iPod听歌的,然后通过iTunes + FreeFileSync经由NAS在两台电脑之间管理、同步曲库。随着高中毕业,iPod也到了退休的时候。

我一直有存歌的习惯,不只是因为iPod,还有对流媒体平台的会员制与版权争夺的厌倦。但iPod退休,我也就没有理由继续使用iTunes或者AppleMusic。纯粹使用文件夹管理歌曲是困难的,而市面上跨平台媒体播放器的曲库管理也一言难尽。

于是我找到了Navidrome。

环境

  1. 有一台服务器;
  2. 服务器有Docker;
  3. 通过Zerotier虚拟专用网连接;
    • 有公网IP可以忽略。除Zerotier外,还可以使用FRP等内网穿透服务;
    • 在国内使用Zerotier,对于网络带宽有比较高的要求,部署moon服务器往往会有更好的体验
    • 可以用iPerf测试,如果需要流畅播放320Kbps MP3音频建议iPerf测试结果达到10Mbps
    • 如果只是听歌最好不要部署ZeroNSD

部署

  1. 如果在国内没有可用的Dockerhub镜像,设置好代理
    修改/etc/docker/daemon.json
1
2
3
4
5
6
7
{
"proxies": {
"http-proxy": "http://proxy.example.com:3128",
"https-proxy": "https://proxy.example.com:3129",
"no-proxy": "*.test.example.com,.example.org,127.0.0.0/8"
}
}
  1. 创建/opt/navidrome并在该目录下编辑docker-compose.yml
    其中,volumes需要根据提示编辑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
services:
navidrome:
image: deluan/navidrome:latest
user: 1000:1000
ports:
- "4533:4533"
restart: unless-stopped
environment:

ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: ""
volumes:
- "/path/to/data:/data"
- "/path/to/your/music/folder:/music:ro"
  1. 部署运行
1
docker-compose up -d

浏览器访问服务器的4533端口,根据提示一步步设置,就可以进入web主界面。

曲库

iTunes导入

如果是从零开始存歌本章可以忽略。

下面以iTunes为例。对于其他不同的播放器,一般需要导出为m3u格式的播放列表,再存入navidrome的音频文件目录。

这是我一年前的操作方法,仅供参考。

  1. 在曲库目录下创建plist目录便于管理播放列表(可选);

  2. 在iTunes中,于工具栏->“偏好设置”->“高级”选项卡,勾选“与其他应用共享iTunes资料库XML”选项;

  3. 安装Python3与pip,通过itunesLibrary导出为m3u播放列表。基于Python3交互式客户端进行操作,一些方法如下:

    • 初始化:
      1
      2
      3
      4
      5
      import os
      from itunesLibrary import library

      path = os.path.join("PathTo/iTunes/iTunes Music Library.xml")
      lib = library.parse(path)
    • 查询已有播放列表:
      1
      2
      for playlist in lib.playlists:
      print(playlist.title)
    • 选择播放列表并查询当前播放列表下的所有项目:
      1
      2
      playlist=lib.getPlaylist("PlaylistName")	
      print(playlist.items)
    • playlist.items字典的一些键:
      Key Comment
      Track ID 音轨的唯一标识符
      Size 音轨文件的大小(通常以字节为单位)
      Total Time 音轨的总时长(通常以毫秒为单位)
      Track Number 音轨在专辑中的编号
      Year 音轨发布的年份
      Date Modified 音轨文件最后一次修改的日期
      Date Added 音轨被添加到播放列表的日期
      Bit Rate 音轨的比特率(通常以kbps为单位),表示音质
      Sample Rate 音轨的采样率(通常以Hz为单位),表示音频的清晰度
      Play Count 音轨被播放的次数
      Play Date 音轨最后一次播放的日期
      Play Date UTC 音轨最后一次播放的日期(UTC时间)
      Skip Count 音轨被跳过的次数
      Skip Date 音轨最后一次被跳过的日期
      Artwork Count 音轨关联的封面艺术数量
      Persistent ID 音轨的持久化唯一标识符,即使文件移动或重命名也不会改变
      Track Type 音轨的类型(如音乐、播客等)
      File Folder Count 音轨文件所在的文件夹数量
      Library Folder Count 音轨在音乐库中的文件夹数量
      Name 音轨的名称
      Artist 音轨的艺术家或表演者
      Album 音轨所属的专辑名称
      Kind 音轨的文件类型(如MP3、AAC等)
      Location 音轨文件的存储位置。
      使用的是URI的格式,需要用urllib.parse.unquote转码。
    • 举例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      >>> playlist.items[0].keys()
      dict_keys(['Track ID', 'Size', 'Total Time', 'Track Number', 'Year', 'Date Modified', 'Date Added', 'Bit Rate', 'Sample Rate', 'Play Count', 'Play Date', 'Play Date UTC', 'Skip Count', 'Skip Date', 'Artwork Count', 'Persistent ID', 'Track Type', 'File Folder Count', 'Library Folder Count', 'Name', 'Artist', 'Album', 'Kind', 'Location'])

      >>> playlist.items[0].getItunesAttribute('Name')
      '運命 (はるまきごはん×煮ル果実)'

      >>> playlist.items[0].getItunesAttribute('Artist')
      'はるまきごはん/煮ル果実'

      >>> playlist.items[0].getItunesAttribute('Location')
      'file://localhost/C:/Users/bkryofu/Music/PlaylistA/%E3%81%AF%E3%82%8B%E3%81%BE%E3%81%8D%E3%81%94%E3%81%AF%E3%82%93%3B%E7%85%AE%E3%83%AB%E6%9E%9C%E5%AE%9F%20-%20%E9%81%8B%E5%91%BD%20(%E3%81%AF%E3%82%8B%E3%81%BE%E3%81%8D%E3%81%94%E3%81%AF%E3%82%93%C3%97%E7%85%AE%E3%83%AB%E6%9E%9C%E5%AE%9F).mp3'
  4. 在读取资料库并选取好要导出的播放列表后,就可以通过以下方法从控制台得到m3u播放列表:

    1
    2
    3
    4
    5
    6
    7
    8
    def export(playlist):
    from urllib.parse import unquote
    print('#EXTM3U\n#PLAYLIST:' + playlist.title)
    for n in range(len(playlist.items)):
    print("#EXTINF:" + str(n) + "," + playlist.items[n].getItunesAttribute('Artist') + ' - '+playlist.items[n].getItunesAttribute('Name'))
    print('/music/'+unquote(playlist.items[n].getItunesAttribute('Location')).split('/')[-1])

    export(playlist)

    控制台输出的格式应该像是这样的:

    1
    2
    3
    4
    5
    6
    7
    8
    #EXTM3U
    #PLAYLIST:[S]はるまきごはん
    #EXTINF:0,はるまきごはん - 約束 (はるまきごはんVocal ver)
    /music/はるまきごはん - 約束 (はるまきごはんVocal ver).mp3
    #EXTINF:1,はるまきごはん - 再会 (はるまきごはんVocal ver)
    /music/はるまきごはん - 再会 (はるまきごはんVocal ver).mp3
    #EXTINF:2,はるまきごはん/初音ミク - メルティランドナイトメア
    /music/はるまきごはん;初音ミク - メルティランドナイトメア.mp3

    将输出的字符串拷贝至一个文本文档,以m3u为后缀命名。进入navidrome走一遍资料库完全扫描,就能出现刚导入的播放列表。

    image

管理

增删歌曲可以在webUI中操作,修改播放顺序在webUI中通过拖拽实现,但对于一条100+的歌单而言,拖拽管理显然低效。

目前似乎没有更好的解决方法。我的做法是:

  1. 在WebUI的播放列表页,导出m3u播放列表;
  2. 修改m3u播放列表的文本;
  3. 将新修改的播放列表替换掉旧的播放列表。

智能播放列表

Navidrome支持智能播放列表。保存为以snp为后缀的json文本文件。

比如,我想要在我的所有歌曲中,筛选出ずっと真夜中でいいのに。的歌曲,artist元数据要包含ずっと真夜中でいいのに。ACAね,智能播放列表JSON就应该是这样的:

1
2
3
4
5
6
7
8
9
10
11
{
"all": [
{"any":
[
{"contains": {"artist": "ずっと真夜中でいいのに。"}},
{"contains": {"artist": "ACAね"}}
]
}
],
"sort": "album"
}

参见How to Use Smart Playlists in Navidrome (Beta)

播放

除了可以在网页端播放,还可以使用音流 - Stream Music客户端。

音流是目前唯一跨Windows、Apple、Android的navidrome客户端。不开源,可以长期免费使用,也可以内购永久买断解锁更多功能。

音流由国人开发,在交互界面上也符合国人的使用习惯。

image

但在一些方面,仍有一些小问题。比如:

  • v1.3+ 只能联网读取播放列表;
  • 本地存储的元数据不包括封面逼死强迫症
  • 早先某个版本出现过播放时卡顿的问题(现已修正);
  • etc.

简评

不得不承认,即使有极其友好的用户界面,Navidrome也不适合一般的消费者。

一年的使用下来,我的评价是,Navidrome与StreamMusic的方案作为iTunes+iPod的替代品,是合格的。但并不是所有人都有技术和资源去折腾。

从去年到今年,我的服务器也经历了几次软硬件更新。旧的H110M主机替换掉了原本的酷睿2小电脑,作为我的土豆服务器;双网卡链路聚合的网络方案一定程度上拓展了网络带宽;通过natfrp部署zerotier-moon服务器曲线救国,解决公网peer不到的问题。也因此,navidrome听歌的体验也随着软硬件更新迭代而不断变好。

虽然我还是有网易云的学生黑胶VIP,但网易云对于我来讲已经是可有可无的存在了。

Navidrome + StreamMusic——你的下一个网易云

p/837d5407.html