MangTool —— 音乐文件一键导入工具

面向 Navidrome 音乐服务器的音频文件智能导入管线。

一键导入工作流

将待处理的音频文件放入 Input/ 目录,点击「开始一键导入」即可自动完成:

  1. 扫描 — 递归扫描 Input 目录下的所有音频文件
  2. 校验 — 检查 Title/Artist/Album 元数据是否完整,缺失文件移入 Rejected/MissingMetadata
  3. 繁简转换 — 将繁体中文标签自动转为简体
  4. 格式转换 — 将 WAV/APE/AIFF/WV/TTA 转为 FLAC(需 FFmpeg),失败文件移入 Rejected/ConversionFailed
  5. 去重 — 基于 Artist+Album+Disc+Track+Title 归一化身份标识对比 Library 已有文件,重复移入 Rejected/Duplicate
  6. 封面 — 专辑目录须有 cover.jpg/png 或音频含内嵌封面,二者皆无移入 Rejected/MissingCover
  7. 入库 — 有效文件按 Artist/Album (year)/NN - Title.ext 布局移入 Library
  8. 歌词(可选) — 从侧车 .lrc、内嵌歌词或远程接口补齐歌词;歌词的有/无/失败绝不影响音频入库,仅计入报告统计

目录结构

BasePath/
├── Input/              ← 放入待处理的音频文件
├── Library/            ← 整理后的 Navidrome 兼容曲库
├── .mangtool/          ← 任务生命周期状态(重启恢复用,勿手动改动)
└── Rejected/           ← 被拒绝的文件按原因分类
    ├── MissingMetadata/
    ├── MissingCover/
    ├── Duplicate/
    ├── ConversionFailed/
    ├── Unreadable/
    ├── Other/
    └── Reports/        ← 每次导入的结构化 JSON 报告(逐文件结果 + 歌词统计)

可观测性与报告

  • 导入报告:每次导入在 Rejected/Reports/ 写入一份结构化 JSON,含逐文件结果(outcome)与歌词来源/状态(lyricSource/lyricStatus),以及汇总的 lyricsFound/lyricsMissing/lyricsFailed 等计数。既有字段保持向后兼容。
  • UI 下载:一键导入页可查看歌词「有/无/失败」实时统计,并「下载导入报告」(GET /api/ingest/report/{taskId}taskIdlatest 取最近一份)。
  • 依赖自检GET /api/health/dependencies 报告 FFmpeg/FFprobe 是否可用及版本,便于部署自检与排障。

任务生命周期、取消与恢复

  • 取消POST /api/ingest/cancel 取消当前任务;取消只停止后续文件处理,已入库(已移动)的文件不会被删除,未处理文件保留在 Input/ 供下次导入。
  • 重启恢复:任务生命周期与逐文件完成情况持久化在 BasePath/.mangtool/ingest-tasks.json。服务重启后,仍处于运行中的任务会被标记为 interrupted;由于已完成文件已移出 Input/,重新导入自然只处理未完成文件,不会重复搬运。

Library 健康检查(只读,修复需确认)

  • 只读扫描POST /api/library/health/scan(可选 ?checkDecode=true 执行完整解码校验)统计缺元数据、缺封面、缺歌词、孤立侧车(无对应音频的 .lrc)与重复曲目,绝不修改任何文件
  • 确认后修复POST /api/library/health/repair 需请求体 confirm=true 才会执行(歌词回填、封面回填、删除孤立侧车、可选删除解码失败音频);confirm=false 仅演练,不改动磁盘。匹配到音频的侧车永不删除。

修复示例(含封面回填)

# 默认配置下不修改磁盘。加上 confirm=true 与 backfillCovers=true 即可安全回填封面与修复曲库
curl -X POST -H "Content-Type: application/json" -d '{"confirm": true, "backfillCovers": true}' http://localhost:8080/api/library/health/repair

备份与恢复

导入是「移动」语义,请在批量导入前对关键目录做快照备份:

  • 必备Library/(成品曲库,含 cover.jpg/png.lrc)。
  • 建议Rejected/(含 Reports/ 报告,便于追溯)与 BasePath/.mangtool/(任务状态)。
# 简易快照(示例)
tar czf mangtool-backup-$(date +%Y%m%d).tgz -C /path/to/BasePath Library Rejected .mangtool

恢复时将快照解压回原 BasePath 即可;Navidrome 直接扫描 Library/ 目录,无需额外数据库。

构建与运行

# 后端
cd backend && mvn clean package -DskipTests && mvn spring-boot:run

# 前端(开发模式)
cd frontend && npm ci && npm run dev

# Docker
cd docker && docker compose up -d --build

一次性清理历史曲库

正常导入不会扫描或删除 Library 中的历史文件。升级后如需清理旧数据,先运行默认的预览模式:

./scripts/cleanup-library.sh --library /path/to/Library --dry-run

确认输出后再显式执行:

./scripts/cleanup-library.sh --library /path/to/Library --execute

脚本会优先把音频内嵌封面提取为专辑目录的 cover.jpg/png。只有目录和音频都没有封面时,才删除音频及同 basename 的 .lrc.cue.json.txt 和图片 sidecar;不会删除公共 cover.jpg/png 或其他曲目文件。

技术栈

  • 后端:Spring Boot 2.7 + Java 8 + Maven
  • 前端:Vue 3 + Vite + TypeScript + Element Plus
  • 音频元数据:jaudiotagger
  • 繁简转换:opencc4j
  • 格式转换:FFmpeg

Cover Art Settings

S
Description
我的工具箱
Readme Apache-2.0
1.1 MiB
Languages
Java 69%
Vue 25.9%
TypeScript 2.8%
Shell 1%
CSS 0.9%
Other 0.2%