Files
MoviePilot/docs/refactor/music-pt-benchmark.md

6.8 KiB
Raw Blame History

音乐真实 PT 样本回归(2026-09-30)

本次基于 v3@fcd4cd172553ee55d39bed52d3abc59e56ee93c5 对比音乐关键词提取和 MusicBrainz 专辑识别。改动位于公共解析入口,Python 与 Rust 使用相同预处理, 无需重建 Rust wheel。没有放宽自动下载的严格匹配条件。

数据来源与口径

通过本地 MoviePilot PostgreSQL 的只读连接取得站点认证,在内存中交给既有 SiteSpider 浏览音乐分区;读取文件列表页取得文件名。没有下载种子文件或音频。 测试语料只保留标题、副标题、相对音频路径和命名标注,不包含 Cookie、密码、 Passkey、下载地址、追踪器地址、账户资料或页面 HTML。

站点 去重后的音乐分区条目
音乐乌托邦(musopia) 250
憨憨(hhanclub) 250
春天(springsunday) 250
观众(audiences) 250
红豆饭(hdfans) 250
冬樱(wintersakura) 26
合计 1,276

最多浏览每站 5 页、每站保留 250 条。烧包乐园、家园本次返回空列表,学校和自由农场 没有匹配到配置域名的 Cookie,均未计入成功采样站点;空列表不能证明站点没有音乐。 音乐分区包含演唱会、合集等,并混入至少一条置顶电视剧,保留这些条目用于抗噪和引擎一致性测试。

另取音乐乌托邦 12 个种子的文件列表,得到 2,598 条不同的相对音频路径,其中 2,596 条带曲序、2 条为整轨 WAV。文件主要覆盖流行合集、古典套装和分轨抓取, 不是所有命名习惯的随机样本。

  • tests/fixtures/music_pt_corpus.json:1,276 个种子名与 2,598 个文件名。
  • 300 条种子名有独立预期值:250 条按站点明确的结构化主标题标注,50 条按命名证据人工标注; 每条只核验 expected 中列出的字段,不能视为全部元数据均已标注。
  • 2,596 条文件曲序直接从原始文件名的显式前缀标注,不从被测解析器生成。
  • 未标注的字段和条目用于稳定性及 Python/Rust 对照,不能计为识别正确。

同输入前后对照

检查对象 修改前 修改后
300 条种子名的已标注字段全部正确 254/300 300/300
2,596 条裸文件名提取曲序 35/2,596 2,596/2,596
2,596 条实际文件读取入口提取曲序 2,487/2,596 2,596/2,596
3,874 条输入的 Python/Rust 关键字段差异 0 0
60 条定向样本返回 MusicBrainz 专辑身份 20/60 33/60

裸文件名入口原先没有统一去除曲序,实际文件读取入口原先已有独立处理,因此两者的 基准相差很大,不能用 35/2596 描述实际文件整理能力。现在两条入口统一处理扩展名和曲序。

MusicBrainz 对照选取覆盖复杂命名的 60 条资源,限定 music_type=album,使用真实 公开 JSON 响应,同一请求复用快照以固定候选集。有效结果须有源 ID,并核对作品与艺人; 不是 3,874 条数据全部在线识别,更不是总体命中率。新增 13 个专辑身份,原有 20 个身份未改变。 剩余 27 条中,9 条保留多候选歧义,18 条未取得足够证据。

新增命中包括 Querido Pablo、Poètes au Sud、刘若英《在一起》、Taylor Swift 同名专辑、 Johann Pachelbel, Vol. II、10 Songs、邓丽君《淡淡幽情》、周杰伦《依然范特西》《七里香》 《叶惠美》、许巍《无尽光芒》《在别处》及飞儿乐团 F.I.R.。

这里核验的是 release-group 作品身份,不是某一张 CD、再版或地区版本:例如 Querido Pablo 资源名为 2000 年,目录首版为 1985 年;《淡淡幽情》资源名为 2005 年, 目录首版为 1983 年。没有据此宣称具体发行版本已核验。

修复范围

  1. 有格式证据时去除 CD FLAC、点分 Album.FLAC 和尾部规格/目录编号; 点分类型清理还须有年份及足够的点分结构,保留普通作品名中的 Album、CD、Vinyl。
  2. 保留 Deluxe/Remastered 等版本语义,避免方括号版本名被扔掉;不把“专辑 FLAC 豪华版” 当作作品名,明确的“专辑:WAV”仍优先作为真实标签。
  3. 主副标题独立确认艺人与作品后,去除重复艺人前缀;正确处理 Radiohead.OK.Computer 等命名。
  4. 明确整专证据下恢复 12 Memories、10 Songs 的数字前缀,不再当作曲序。
  5. 音频文件先解析扩展名和曲序,保护 911 等数字艺人、1812 Overture 等数字曲名。 有古典作品证据时保留完整乐章名称,同时兼容 01 - Artist - First.flac。
  6. 文件名只补空字段,保留真实标签的优先级;M4A 容器本身不能证明编码为 AAC。

订阅/资源匹配仍要求可靠身份,错误作品、艺人、年份、现场版本不能因清理而变成严格命中。 Lover、Starboy、By the Horns 等多候选样本仍需确认。目录没有收录、艺人别名/检索召回不足、 中文新发行作品和完整唱片版本对齐仍是后续工作,不能靠放松匹配阈值掩盖。

可重复验证

离线测试不连接生产数据库或外部服务:

.venv/bin/python -m pytest tests/test_music_pt_corpus.py tests/test_music_lifecycle_audit.py -q
.venv/bin/python tests/run.py

test_music_pt_corpus.py 强制验证实际 Python/Rust 两条路径,并禁止 Rust 测试静默回退。 music_pt_musicbrainz.json 保存 17 个已核对样本所需的 27 个公开请求响应,其中包括全部 13 个新增命中、1 个原有命中和 3 个多候选样本。同步/异步识别都重放真实候选集, 保留请求上限和歧义短路,缺少录制的请求立即失败。

重新采样使用专门的在线诊断脚本,与 pytest 的隔离环境分开:

.venv/bin/python scripts/music_recognize_batch_test.py --fetch-only \
  --config-dir /path/to/moviepilot-config \
  --sites musopia,hhanclub,springsunday,audiences,hdfans,wintersakura \
  --pages 5 --samples-per-site 250

--config-dir 只读 app.env 中的 PostgreSQL/SQLite 凭据,运行配置和采样结果存到仓库 config/temp,不修改生产库。该脚本重新抓取的是当前标题,不会保证重现本次时间点的站点列表; 对照基准应使用随代码保存的脱敏 fixture。

最终本地验证:全量四分片共 12,504 passed、9 skipped;变更文件 Pylint 10.00/10; 宿主架构快照、strict mypy、mypy/Ruff/复杂度 ratchet 与 git diff --check 均通过。 apply_path_context 删除重复曲序处理后 C901 从 16 降至阈值以内,基线仅移除此已消除的超限项。

本次未改变界面、配置项或操作流程,未触及 Wiki、前端构建和 Rust 发布;这里只记录识别行为 与测试证据。代码仍为本地改动,生产 MoviePilot 尚未切换到本次实现。