sudravirodhin/dadtool-importer
GitHub: sudravirodhin/dadtool-importer
一款针对节奏游戏 Dead as Disco 的离线节拍分析与歌曲导入工具,通过 transformer 节拍追踪器自动生成精确的节拍同步数据并直接写入游戏存档,取代手动敲击校准。
Stars: 0 | Forks: 0
# dadtool — *Dead as Disco* 的离线节拍同步与歌曲导入工具
这是一个 Windows CLI 工具,能够**离线**分析曲目的节拍,并将同步数据
**直接写入 *Dead as Disco* 的单曲保存元数据中** —— 因此你再也不必使用
游戏内的敲击校准工具。它还可以端到端地导入歌曲(转码 →
自动命名 → 响度标准化 → 节拍同步),让游戏内的导入器变得可有可无。
离线生成的网格比手动敲击精确大约 **2 倍**,并且在一整首歌中都不会出现漂移。
## 功能说明
- **直接写入节拍同步数据** 到每首歌曲的 `Meta.json` 中 —— 包括节拍、节拍偏移量、
变速段落以及静音修剪 —— 替代手动敲击校准。
- **端到端导入歌曲:** 将任何音频转码为游戏所需的 48 kHz Ogg Vorbis,
构建游戏所需的歌曲文件夹,并写入同步好的 `Meta.json`。
- **准确追踪节拍**,使用 transformer 节拍追踪器(beat_this),包括真正的
强拍、分段的节拍变化,以及自动的半拍偏移校正。
- **为歌曲命名**,基于 AcoustID 音频指纹(通过 MusicBrainz 获取规范标题/艺术家),
并支持回退到文件标签 + 文件名。
- **响度标准化** 至统一的 −14 LUFS。
- **作为守护进程运行**,可自动导入任何放入指定文件夹的内容。
- **安全第一:** 拒绝在游戏运行时操作,带有时间戳的完整备份、版本/格式
校验门控、通过重新读取进行验证,以及针对任何错误提供的单曲覆盖文件。
## 环境要求
- **Windows**(使用 Windows 存档路径 + 进程检查)和 **Python 3.12**。
- 为节拍追踪器准备**独立的 conda/Miniforge 环境** —— `beat_this` 需要 PyTorch
(仅使用 CPU 即可)。
- 通过 `imageio-ffmpeg` **内置 ffmpeg**;无需在系统中单独安装。
- *可选,用于自动命名:* **AcoustID API key** 和 **Chromaprint `fpcalc`**
可执行文件。
## 初始设置
```
# 1. main 环境
python -m venv .venv
.\.venv\Scripts\pip install -r requirements.txt
# 2. 在隔离的 conda env 中的 beat tracker(CPU torch 即可)
conda create -n dad-beat python=3.11
conda activate dad-beat
pip install beat_this torch soundfile
# 3. config — 复制 example 并填入你的路径
copy dad_config.example.json dad_config.json
```
然后编辑 `dad_config.json`:`saved_dir`,游戏 exe 路径,`beat_this_python`(即
`dad-beat` 解释器),以及可选的 `acoustid_api_key` 和 `fpcalc_path`。该文件已被
git-ignore(其中包含本机路径 + 你的 API key)。游戏目录**仅**在 `dadtool/paths.py` 中,通过 `dad_config.json` 或 `DAD_SAVED_DIR` 环境变量进行解析。
## 用法
通过 venv(或内置的 `dad.cmd` / `watch.cmd` 启动器)运行:
```
.\.venv\Scripts\python.exe -m dadtool.cli
```
| 命令 | 功能说明 |
|---|---|
| `status` | 解析路径、游戏运行状态、当前游戏版本 |
| `revalidate` | 在写入前检查游戏构建版本 + 格式金丝雀 |
| `analyze ""` | 打印 ImportedSongs 名称或音频文件的分析 JSON |
| `preview ""` | 将节拍音轨渲染为 WAV 到 `previews/` 以便试听同步效果 |
| `write ""` | 分析 + 写入单首歌曲(`--dry-run`, `--tempo/--offset/--start`) |
| `batch` | 分析 + 写入所有已导入的歌曲(`--dry-run`, `--force`, `--limit N`) |
| `import-song ` | 从源文件构建完整的 ImportedSongs 条目 |
| `list` | 列出所有已导入的歌曲及其索引(即 `remove --index` 的选择器) |
| `remove` | 按名称、`--index 2,4,6-9`、`--match '*pattern*'` 或 `--all` 批量删除歌曲 |
| `playlist list` | 列出播放列表及其包含的歌曲 |
| `playlist create "" ` | 根据歌曲名称匹配创建播放列表 |
| `playlist auto` | 为包含 3 首以上歌曲的专辑自动创建播放列表(`--min N`, `--dry-run`) |
| `playlist delete ""` | 删除播放列表 |
| `challenge plan ""` | 预览程序化的波次/难度规划(不写入) |
| `challenge generate ""` | 生成并写入挑战(`--difficulty`, `--boss`/`--no-boss`, `--arena`) |
| `challenge sync` | 为整个曲库生成自动挑战(`--purge`, `--dry-run`) |
| `watch` | 守护进程:自动导入放入 `audio/pending/` 的音频(`--once`, `--interval N`) |
| `normalize` | 将所有 `Audio.ogg` 进行 LUFS 标准化至 −14(`--force`) |
| `rename` | 通过 AcoustID 为所有歌曲设置歌曲名称/艺术家(`--dry-run`) |
| `relabel` | 将所有歌曲名称重写为 `Artist - Title`,使游戏内列表按艺术家排序(`--dry-run`) |
| `restore` | 在游戏补丁清除元数据后重新写入缓存的元数据 |
| `collect` / `ingest` | 将源音频归档至 `audio/processed/` |
| `snapshot 标签:Python, Transformer, 凭据扫描, 无后门, 游戏模组, 节拍同步, 逆向工具, 音乐游戏, 音频分析