Anisong Organizer
一个简单易用的自动化整理程序:扫描音乐文件夹,自动识别每首歌的出处并分类整理——动漫歌按系列排列,非动漫歌按歌手地区与成立时间排列,歌词与封面同步归类。
- ✅ 零配置:工具包文件夹复制到任意音乐文件夹即可运行
- ✅ 零依赖:纯 Python 标准库(联网识别日文曲名时推荐安装可选的 pykakasi;ncm 解密已装 numpy 时自动加速)
- ✅ 先预览后执行:默认只出预览,确认后才执行,绝不静默修改
- ✅ 幂等:重复运行不会重复处理,也不会破坏已整理好的结构
- ✅ 只动文件名:不修改音乐文件内容和内置标签
- ✅ 六分类输出:Anisong / 日韩 / 中国港澳台 / 中国大陆 / 欧美 / 其他(未被识别),没有内容的分类不创建文件夹
- ✅ 网易云 .ncm 一键解密:解密为 flac/mp3 后进入同一流水线,原 .ncm 保留到「加密原件」夹
- ✅ 歌词/封面同步:歌词与音乐同编号入「歌词」夹;封面按专辑名入「封面」夹
- ✅ 浏览器交互界面:
--web启动本地网页界面,可视化调整分类与顺序
快速上手
-
(可选)便携版无需安装 Python:工具包已内置官方 Python 嵌入式运行时(
python\目录,约 21MB)。双击启动网页版.bat直接打开浏览器整理界面;命令行用户双击命令行运行.bat。本机已装 Python 时两套入口同样可用。📦 源码版注意:从 git 仓库克隆的源码不含内置运行时(
python\目录)。需本机已装 Python 3.8+,或到 python.org 下载 Windows embeddable package (64-bit) 解压为python\目录,即可恢复免安装便携。 -
放入工具包:把本文件夹(
Anisong Organizer)整个复制进你的音乐文件夹,例如:D:\音乐\我的收藏\ ├── Anisong Organizer\ ← 本工具包 ├── 未闻花名 - 茅野爱衣.flac ├── Sexyback - Justin Timberlake,Timbaland.ncm └── ...(你的音乐文件) -
双击运行:双击
命令行运行.bat(或执行python app\anime_sorter.py)。程序自动处理上级文件夹里的音乐。 -
看导览:程序打印完整的整理预览(旧名 → 分类 → 新位置),并生成
导览.txt(分类\歌曲\编号_曲名 ← 原名的对照清单,可按它手工移回)。确认后输入y执行。 -
想要图形界面:执行
python app\anime_sorter.py --web,浏览器里拖拽调整分类、点击应用。 -
以后新增歌曲:把新歌丢进音乐文件夹,再运行一次即可。新歌编号自动续接,识别结果缓存到
识别缓存.json/artist_map.json,下次离线也能用。
整理结果示例
D:\音乐\我的收藏\
├── Anisong\ ← 识别到动漫的歌(按系列首播年份排序)
│ ├── 歌曲\01_疾風の如く.flac
│ ├── 加密原件\02_プランA.ncm
│ ├── 歌词\01_疾風の如く.lrc
│ └── 封面\プランA.jpg
├── 日韩\ ← 非动漫、歌手地区为日韩(按歌手成立年份排序)
│ ├── 歌曲\01_Power.flac
│ ├── 加密原件\01_Power.ncm
│ └── 歌词\01_Power.lrc
├── 中国港澳台\
│ └── 歌曲\01_海阔天空.mp3
├── 中国大陆\
│ └── 歌曲\01_平凡之路.mp3
├── 欧美\
│ └── 歌曲\01_Sexyback.flac
├── 其他(未被识别)\ ← 兜底:查不到出处的歌
│ └── 歌曲\01_未知之歌.mp3
└── Anisong Organizer\
(没有内容的分类不会创建文件夹。)
工作原理
音乐文件夹(.flac/.mp3/.ncm/.lrc…)
│
├─ ⓪ 解密与自愈 ─────── .ncm 解密为 flac/mp3(幂等);「加密原件」夹中
│ 缺失解密音频的 .ncm 自动恢复;封面提取待分类后入夹
│
├─ ① 提取曲名与歌手 ── FLAC 读内置标签(TITLE/ARTIST)
│ 其他格式或无标签时回退解析文件名「曲名 - 歌手」
│
├─ ② 曲名规范化 ─────── 简中混入修正(谜→謎 风→風)、全角空格、
│ 去注释尾巴(feat. XXX / Director's Edit. 等)
│
├─ ③ 分类判定 ──────── 1) 本地映射表 anime_map.json(含历史联网缓存)
│ 2) 四动漫源**并行**联网查询,按曲名语言调整优先级:
│ 假名→anison 优先 / 汉字→萌娘优先 / 英文→animethemes 优先
│ 命中 → Anisong;源连续失败 2 次自动熔断(本次运行停用)
│ 3) MusicBrainz 查歌手地区 → 日韩/中国港澳台/中国大陆/欧美
│ 4) 都查不到 → 其他(未被识别)
│
├─ ④ 排序 ──────────── Anisong: 系列按首播年份(老→新),系列内按 OP/ED 顺序
│ 日韩/港澳台/大陆/欧美: 按歌手分组(同歌手相邻),
│ 歌手按成立年份(未知置后),组内按曲名
│ 其他: 按 (歌手, 曲名)
│
├─ ⑤ 编号 ──────────── 每分类独立编号(01,02,03…),续接该分类现有最大号;
│ 歌词与加密原件与歌曲永远同号
│
├─ ⑥ 文件名清理 ────── Windows 禁用字符转全角、尾随点转全角、重名加 (2)
│
└─ ⑦ 预览确认后执行 ── 移动到分类文件夹(导览.txt 含完整绝对路径对照,可回退);
联网结果写入 识别缓存.json(每次联网运行重新生成) / artist_map.json 缓存
文件说明(分层结构)
Anisong Organizer\
├── 启动网页版.bat / 命令行运行.bat ← 入口层(双击即用)
├── app\ ← 程序层
├── data\ ← 数据层(用户维护/缓存/导览)
├── python\ ← 运行时层(内置 Python,免安装)
└── README.md
| 文件 | 作用 |
|---|---|
app\anime_sorter.py |
主程序(命令行入口 + 全部流水线逻辑) |
app\ncm_decrypt.py |
网易云 .ncm 解密模块(纯标准库,numpy 可选加速;可单独 import 使用) |
app\web_server.py |
--web 模式的本地服务(127.0.0.1 随机端口;关闭网页即自动退出) |
app\web_ui.html |
Web 界面页面(纯静态无 CDN,全离线可用) |
data\anime_map.json |
本地曲目→动漫系列映射表(用户维护:种子数据 + ✎ 手动标注;不再自动追加联网结果) |
data\识别缓存.json |
联网识别结果缓存(每次联网运行自动重新生成,不累积历史,可安全删除) |
data\artist_map.json |
MusicBrainz 歌手地区/成立时间缓存(自动生成,可手工编辑/预填,离线生效) |
data\设置.json |
数据源开关 + 分类/输出/解密等全部选项 |
data\导览.txt |
每次运行自动生成的整理导览(编号_曲名 ← 原名 对照,可据此手工撤销;Web 界面有「📖 导览」按钮直接查看) |
命令行运行.bat |
双击运行入口(命令行界面;自动优先使用内置 python\ 运行时) |
启动网页版.bat |
双击启动浏览器整理界面(关闭网页即自动退出进程;仅出错时窗口停留) |
python\ |
内置的官方 Python 嵌入式运行时(便携版核心,免安装 Python) |
README.md |
本说明文档 |
设置.json
{
"sources": {
"animethemes": {"enabled": true},
"anison": {"enabled": true},
"wikipedia": {"enabled": true},
"moegirl": {"enabled": true}
},
"musicbrainz": {
"enabled": true,
"rate_limit": 1.05,
"user_agent": "AnisongOrganizer/1.0 ( contact )",
"max_failures": 3
},
"decrypt": {"enabled": true, "save_cover": true},
"output": "",
"categories": {
"anisong": "Anisong",
"jp_kr": "日韩",
"hk_mo_tw": "中国港澳台",
"cn_mainland": "中国大陆",
"western": "欧美",
"other": "其他(未被识别)"
},
"folders": {"songs": "歌曲", "originals": "加密原件", "lyrics": "歌词", "covers": "封面"}
}
sources:各动漫识别源的启停(anison / wikipedia 需要加速器/代理)musicbrainz:歌手地区分类源(需要加速器/代理;user_agent必填自定义格式,默认 UA 会被官方封 IP;连续失败max_failures次后本次运行自动禁用,剩余歌曲归「其他」)decrypt:ncm 解密与封面提取开关output:分类输出根目录,空 = 被处理文件夹本身;可填其他盘路径(自动跨盘移动)categories/folders:六分类与四子文件夹的名称,均可自定义
数据源(联网识别)
| 顺序 | 数据源 | 擅长 | 需要加速器/代理 |
|---|---|---|---|
| 1 | AnimeThemes.moe | 英文/罗马字曲名,自带年份与季度;日文曲名自动转罗马字后再查 | 否 |
| 2 | anison.info | 日文曲名,专门的动漫歌曲数据库(结果行直接含动漫名与 OP/ED 类型) | 是 |
| 3 | 日语维基百科 | 从歌曲条目的「テレビアニメ『X』のOP/ED」句式精确提取动漫 | 是 |
| 4 | 萌娘百科 | 中日文曲名,国内直连 | 否 |
| 5 | MusicBrainz | 歌手地区/成立年份(非动漫曲分类排序用),官方限速 1 次/秒,结果本地缓存 | 是 |
连不上的源不会卡死程序:运行结束统一汇总状态并提示(「✗ 数据源 anison 连接失败 2 次 —— 该源需要加速器/代理,请确认已开启后重试」)。MusicBrainz 查询失败时歌曲自动归入「其他(未被识别)」。Web 界面顶部有同样的数据源状态面板。
动漫歌曲独特适配(v4.1):
- 语言感知优先级:假名标题(日文曲名)以日文曲库 anison 优先、纯汉字以中日文覆盖的萌娘百科优先、纯英文/罗马字以 AnimeThemes 优先——各取所长
- 并行查询:启用源同时查询,按优先级取首个命中(耗时 = 最慢的源而非各源之和)
- 源熔断:某源连续失败 2 次后本次运行自动停用,不再每首歌白等超时(无梯子实测 2 首歌 81.8s → 36s,歌越多收益越大)
命令行参数
python app\anime_sorter.py # 预览模式(默认),确认后执行
python app\anime_sorter.py --apply # 跳过确认直接执行
python app\anime_sorter.py --offline # 禁用联网,只查本地映射表/缓存
python app\anime_sorter.py --sources=animethemes,moegirl # 本次只用指定源
python app\anime_sorter.py D:\某文件夹 # 处理指定文件夹(缺省为工具包上级文件夹)
python app\anime_sorter.py D:\下载目录 --recursive # 递归整理子目录(网易云下载结构),执行后清理空目录
python app\anime_sorter.py --web # 启动浏览器交互界面
Web 界面
python app\anime_sorter.py --web 启动本地服务并自动打开浏览器(仅监听 127.0.0.1,数据不出本机):
- 表单输入:来源文件夹(如网易云下载目录)+ 输出目录(留空=来源文件夹)+ 递归整理子目录(下载目录勾选,执行后自动清理源目录空壳);默认联网识别(用户维护的 anime_map.json 始终第一优先)
- 顶部实时显示数据源状态(正常/失败/熔断/需代理)
- 进度栏下方实时罗列已识别的歌曲(Anisong 标注所属动漫系列与首播年份,其他类标注乐队组建年份)
- 每首歌的所属动漫系列以蓝色下拉框直接展示(与分类下拉同款样式):正常显示当前匹配系列,展开后第一行是「+ 新建系列…」(点击即出现输入框可直接打字,选现存系列则立即生效并带出首播年份);标注应用后自动写入 anime_map.json。也可改分类(下拉)、调整顺序(↑↓)
- 勾选多行批量选择后:可整体拖拽到其他分类或指定位置(也支持单选拖拽,拖动完成自动取消勾选);或通过批量工具栏一键移动
- 「应用全部移动」执行(执行前有确认弹窗);应用后计划回到可编辑状态,可继续调整并再次应用(反复整理直到满意)
- 工具栏的「📖 导览」按钮:弹窗直接展示整理导览(
编号_曲名 ← 原名对照),可复制或下载导览.txt - 可中途「停止」;执行结果统计展示
一键整理(网易云下载目录)
把网易云下载目录(歌手\专辑\xxx.ncm 嵌套结构)一键整理到指定路径:
python app\anime_sorter.py D:\网易云下载 --recursive --apply
# 输出目录: 设置.json 的 output(留空=下载目录本身);执行后自动清理空目录
或 Web 界面:来源填下载目录、输出填目标路径、勾选「递归整理子目录」→ 扫描 → 应用。 递归扫描自动跳过分类目录与工具包文件夹;子目录中的 .ncm 原位解密后统一移入输出目录分类。
网易云下载设置全部适配:
| 设置项 | 适配方式 |
|---|---|
| 命名「歌曲名」 | .ncm 用内嵌元数据补全歌手;普通文件无歌手信息时归「其他」,可 ✎ 手动标注 |
| 命名「歌手-歌曲名」 | 文件名双向解析,自动识别歌手在前还是曲名在前(优先取能命中映射表的方向) |
| 命名「歌曲名-歌手」 | 默认解析 ✓ |
| 保存「不分文件夹」 | 顶层扫描 ✓ |
| 保存「按歌手」/「按歌手\专辑」 | 递归模式自动包含 ✓ |
| VIP 曲目(VipSongsDownload 子文件夹) | 递归模式自动包含;非递归时检测到会提示勾选递归 |
常见问题与调试
歌曲被归入「其他(未被识别)」
可能原因:本地表没有且动漫源查不到、歌手不在 MusicBrainz 缓存、MusicBrainz 连不上(需加速器)、或文件名/标签里没有歌手信息。处理办法:
- 在 Web 界面手动调整分类;
- 或打开
anime_map.json(动漫歌)/artist_map.json(非动漫歌)仿照已有条目手工添加; - 重新运行。
完全没网 / 联网超时
- 程序对每个接口都设了超时,网络不可用时自动跳过联网、只查本地表与缓存,不会卡死或崩溃。
- 想完全离线运行:加
--offline(本地映射与缓存仍生效)。
日文曲名识别率低
联网识别日文曲名依赖 pykakasi 做罗马字转写:pip install pykakasi。未安装时程序仍可运行,只是日文曲名的联网命中率会明显下降。
重复运行会怎样?
安全幂等。整理完成的文件都在分类文件夹里,顶层没有文件时运行直接显示「无需处理」;新增文件按分类现有最大号续接编号;「加密原件」夹中缺失解密音频的 .ncm 会自动重新解密恢复。
改错了想撤销?
导览.txt 里每首歌都是 分类\歌曲\编号_曲名 ← 原名 的对照,按它手工移回即可(Web 界面点「📖 导览」按钮直接查看/复制/下载)。
旧版本(v3.1)整理过的文件夹
自动迁移:顶层平铺编号的文件与旧「歌词」文件夹里的 .lrc 会重新归类进新结构(编号变为分类内编号,属预期);旧顶层「封面」文件夹无法可靠对应分类,保持原位并在运行时提示。
已知限制与设计取舍
- 联网源覆盖:animethemes.moe 主要收录 OP/ED 主题曲;纯 OST/插入曲或冷门歌曲可能查不到 → 归「其他」,属预期兜底而非故障。
- 识别不是 100% 准确:动漫识别采用「高置信才采用」策略;地区分类依赖 MusicBrainz 数据;预览确认与 Web 手动调整就是最后一道人工保险。
- 系列归属的合并粒度:同世界观多季动画默认归为一个系列(如「とあるシリーズ」含魔禁+超炮)。想拆开就在
anime_map.json里手动分成多个系列。 - 歌手名不写入文件名:最终格式为
编号_曲名,歌手信息保留在文件内置标签中(本程序不修改标签)。 - 不写标签:音乐文件本身只改名移动;如需写入 ALBUM=系列名 等标签,可在此基础上扩展。
- 只扫描文件夹第一层:不递归处理子文件夹(分类文件夹内部不参与重复整理)。
- .ncm 解密后原件保留:解密是「另存新文件」而非替换,磁盘占用会翻倍;确认无误后可自行删除「加密原件」夹中的 .ncm。
依赖
- 无需安装任何环境:工具包内置官方 Python 3.12 嵌入式运行时(
python\目录);本机已装 Python 3.8+ 时也可直接用(启动脚本自动优先内置运行时)。源码版不含该运行时,获取方式见「快速上手」第 0 步 - 零第三方强制依赖(纯标准库)
- 可选:pykakasi(提升日文曲名联网识别率)、numpy(ncm 解密加速,无则自动用纯 Python 路径)
测试情况
- ncm 解密:4 个真实网易云 .ncm 全部解密成功,输出与开源参考实现(ncmdump-py)sha256 字节级一致;numpy 与纯标准库两条路径均验证通过;AES 模块通过 NIST 标准测试向量
- 六分类(v4):本地映射/动漫源/MusicBrainz 缓存三类判定路径分别验证;日韩/港澳台/大陆/欧美/其他归属正确;地区分类按歌手成立年份排序正确
- 结构与幂等(v4):分类内编号独立、歌词/加密原件同号、空分类不创建文件夹、旧 v3.1 结构自动迁移、复跑「无需处理」且文件零改动(快照对比)
- 增量与自愈(v4):新增文件编号续接;删除解密产物后从「加密原件」自动恢复
- Web 界面(v4):扫描/计划/改分类/调顺序/应用/停止/参数校验/源状态面板 20 项 API 测试全部通过(自动化)
- 源策略(v4.1):熔断机制(连续失败 2 次停用)、并行查询、语言感知优先级;无梯子计时实测 81.8s → 36s;MusicBrainz 失败计数与提示验证通过
- 兼容性:映射表/设置文件兼容带 BOM 的 UTF-8(Windows 记事本编辑不会导致崩溃)