# Anisong Organizer 一个简单易用的自动化整理程序:扫描音乐文件夹,自动识别每首歌的出处并分类整理——动漫歌按系列排列,非动漫歌按歌手地区与成立时间排列,歌词与封面同步归类。 - ✅ 零配置:工具包文件夹复制到任意音乐文件夹即可运行 - ✅ 零依赖:纯 Python 标准库(联网识别日文曲名时推荐安装可选的 pykakasi;ncm 解密已装 numpy 时自动加速) - ✅ 先预览后执行:默认只出预览,确认后才执行,绝不静默修改 - ✅ 幂等:重复运行不会重复处理,也不会破坏已整理好的结构 - ✅ 只动文件名:不修改音乐文件内容和内置标签 - ✅ 六分类输出:Anisong / 日韩 / 中国港澳台 / 中国大陆 / 欧美 / 其他(未被识别),没有内容的分类不创建文件夹 - ✅ 网易云 .ncm 一键解密:解密为 flac/mp3 后进入同一流水线,原 .ncm 保留到「加密原件」夹 - ✅ 歌词/封面同步:歌词与音乐同编号入「歌词」夹;封面按专辑名入「封面」夹 - ✅ 浏览器交互界面:`--web` 启动本地网页界面,可视化调整分类与顺序 --- ## 快速上手 0. **(可选)便携版无需安装 Python**:工具包已内置官方 Python 嵌入式运行时(`python\` 目录,约 11MB)。双击 `启动网页版.bat` 直接打开浏览器整理界面;命令行用户双击 `运行.bat`。本机已装 Python 时两套入口同样可用。 > 📦 **源码版注意**:从 git 仓库克隆的源码**不含**内置运行时(`python\` 目录)。需本机已装 Python 3.8+,或到 python.org 下载 [Windows embeddable package (64-bit)](https://www.python.org/downloads/windows/) 解压为 `python\` 目录,即可恢复免安装便携。 1. **放入工具包**:把本文件夹(`Anisong Organizer`)整个复制进你的音乐文件夹,例如: ``` D:\音乐\我的收藏\ ├── Anisong Organizer\ ← 本工具包 ├── 未闻花名 - 茅野爱衣.flac ├── Sexyback - Justin Timberlake,Timbaland.ncm └── ...(你的音乐文件) ``` 2. **双击运行**:双击 `运行.bat`(或执行 `python anime_sorter.py`)。程序自动处理**上级文件夹**里的音乐。 3. **看导览**:程序打印完整的整理预览(旧名 → 分类 → 新位置),并生成 `导览.txt`(也是撤销对照表)。确认后输入 `y` 执行。 4. **想要图形界面**:执行 `python anime_sorter.py --web`,浏览器里拖拽调整分类、点击应用。 5. **以后新增歌曲**:把新歌丢进音乐文件夹,再运行一次即可。新歌编号自动续接,识别结果缓存到 `识别缓存.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 ```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,歌越多收益越大) ## 命令行参数 ```bash python anime_sorter.py # 预览模式(默认),确认后执行 python anime_sorter.py --apply # 跳过确认直接执行 python anime_sorter.py --offline # 禁用联网,只查本地映射表/缓存 python anime_sorter.py --sources=animethemes,moegirl # 本次只用指定源 python anime_sorter.py D:\某文件夹 # 处理指定文件夹(缺省为工具包上级文件夹) python anime_sorter.py D:\下载目录 --recursive # 递归整理子目录(网易云下载结构),执行后清理空目录 python anime_sorter.py --web # 启动浏览器交互界面 ``` ## Web 界面 `python anime_sorter.py --web` 启动本地服务并自动打开浏览器(仅监听 127.0.0.1,数据不出本机): - 表单输入:**来源文件夹**(如网易云下载目录)+ **输出目录**(留空=来源文件夹)+ **递归整理子目录**(下载目录勾选,执行后自动清理源目录空壳);默认联网识别(**用户维护的 anime_map.json 始终第一优先**) - 顶部实时显示**数据源状态**(正常/失败/熔断/需代理) - 进度栏下方实时罗列**已识别的歌曲**(Anisong 标注所属动漫系列与首播年份,其他类标注乐队组建年份) - 每首歌的**所属动漫系列以蓝色下拉框直接展示**(与分类下拉同款样式):正常显示当前匹配系列,展开后第一行是「+ 新建系列…」(**点击即出现输入框可直接打字**,选现存系列则立即生效并带出首播年份);标注**应用后自动写入 anime_map.json**。也可改分类(下拉)、调整顺序(↑↓) - **勾选多行批量选择**后:可整体**拖拽**到其他分类或指定位置(也支持单选拖拽,拖动完成自动取消勾选);或通过批量工具栏一键移动 - 「应用全部移动」执行(执行前有确认弹窗);**应用后计划回到可编辑状态,可继续调整并再次应用**(反复整理直到满意) - 工具栏的「**📖 导览**」按钮:弹窗直接展示整理导览(完整移动对照/撤销日志),可复制或下载 `导览.txt` - 可中途「停止」;执行结果统计展示 ## 一键整理(网易云下载目录) 把网易云下载目录(`歌手\专辑\xxx.ncm` 嵌套结构)一键整理到指定路径: ```bash python anime_sorter.py D:\网易云下载 --recursive --apply # 输出目录: 设置.json 的 output(留空=下载目录本身);执行后自动清理空目录 ``` 或 Web 界面:来源填下载目录、输出填目标路径、勾选「递归整理子目录」→ 扫描 → 应用。 递归扫描自动跳过分类目录与工具包文件夹;子目录中的 .ncm 原位解密后统一移入输出目录分类。 **网易云下载设置全部适配**: | 设置项 | 适配方式 | |---|---| | 命名「歌曲名」 | .ncm 用内嵌元数据补全歌手;普通文件无歌手信息时归「其他」,可 ✎ 手动标注 | | 命名「歌手-歌曲名」 | 文件名双向解析,自动识别歌手在前还是曲名在前(优先取能命中映射表的方向) | | 命名「歌曲名-歌手」 | 默认解析 ✓ | | 保存「不分文件夹」 | 顶层扫描 ✓ | | 保存「按歌手」/「按歌手\专辑」 | 递归模式自动包含 ✓ | | VIP 曲目(VipSongsDownload 子文件夹) | 递归模式自动包含;非递归时检测到会提示勾选递归 | ## 常见问题与调试 ### 歌曲被归入「其他(未被识别)」 可能原因:本地表没有且动漫源查不到、歌手不在 MusicBrainz 缓存、MusicBrainz 连不上(需加速器)、或文件名/标签里没有歌手信息。处理办法: 1. 在 Web 界面手动调整分类; 2. 或打开 `anime_map.json`(动漫歌)/ `artist_map.json`(非动漫歌)仿照已有条目手工添加; 3. 重新运行。 ### 完全没网 / 联网超时 - 程序对每个接口都设了超时,网络不可用时自动跳过联网、只查本地表与缓存,不会卡死或崩溃。 - 想完全离线运行:加 `--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 记事本编辑不会导致崩溃)