feat(music): 增强无标签音频识别,支持文件名/目录解析与专辑级匹配

- 新增 MusicNameParser:剥离曲序/碟号前缀、拆分歌手与曲名、解析专辑目录名(歌手/专辑/年份/音质)和 CD1 等碟片目录
- MetaInfoPath 与 MusicChain.read_path_meta 接入路径上下文,WAV 及标签不全的 FLAC/MP3 可补齐识别线索
- MusicBrainz 新增 match_music_album:按专辑名/歌手/曲名搜索候选发行版本,用曲目数、总时长、逐曲时长和曲名重合度打分对位
- MusicChain 新增 recognize_album_directory 目录级批量识别(按目录缓存),单曲识别未命中时自动兜底
- transfer 整理链路接入专辑匹配,命中后回填曲目身份用于重命名与刮削
This commit is contained in:
jxxghp
2026-08-10 20:11:23 +08:00
parent 85a7f98a94
commit 07ea99442e
8 changed files with 1022 additions and 13 deletions
+4 -1
View File
@@ -12,6 +12,7 @@ from app.core.meta.infopath import (
should_use_parent_title_for_file_stem,
)
from app.core.meta.words import WordsMatcher
from app.helper.music_name import MusicNameParser
from app.log import logger
from app.schemas.types import MediaType
from app.utils import rust_accel
@@ -463,11 +464,13 @@ def MetaInfoPath(path: Path, custom_words: List[str] = None, force_video: bool =
# 音频文件直接构造音乐元数据,不参与父目录季集合并,影视附加音轨强制走视频解析
audio_suffix = path.suffix.lower()
if not force_video and audio_suffix in settings.RMT_AUDIOEXT:
return MetaMusic(
music_meta = MetaMusic(
org_string=path.name,
title=path.stem,
audio_format=audio_suffix.lstrip(".").upper() or None,
)
# 无标签音频只能依靠文件名和目录结构,补充曲序、碟号、歌手和专辑线索
return MusicNameParser.apply_path_context(music_meta, path)
path_context = " ".join(
[path.name, path.parent.name, path.parent.parent.name]
)