mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 23:47:41 +08:00
fix(music): 原声带电影名本体检索与合辑前缀拆分修复零命中
- musicbrainz: 原声带描述词(Original Motion Picture Soundtrack)剔除后 用电影名本体补充检索阶梯,候选比对支持本体与主标题弱匹配; 后缀定界防止 Ghost 类词内 ost 误剥,本体过短时不作独立检索目标 - musicbrainz: 尾部年份反复剥离,修复场景命名重复携带年份 (Live At Montreux 2011 2011)阻断精确匹配 - metamusic: Various Artists-Title 全拼合辑前缀拆分,未收录别名变体 统一归一为 Various Artists - 补充原声带/重复年份/合辑前缀测试案例
This commit is contained in:
@@ -200,6 +200,23 @@ class MusicBrainzModule(_ModuleBase):
|
||||
"""剔除标题尾部的卷号后缀,返回专辑本体名。"""
|
||||
return cls._normalize_text(cls._VOLUME_SUFFIX_RE.sub("", str(value or "")))
|
||||
|
||||
# 原声带资源标题的通用描述词尾部(条目本体是电影名);
|
||||
# 尾部描述词保留时作为原声带形态标记参与弱匹配判定
|
||||
_SOUNDTRACK_SUFFIX_RE = re.compile(
|
||||
r"\s*(?:original\s+motion\s+picture|motion\s+picture)?\s*"
|
||||
r"(?<![A-Za-z0-9])(?:original\s+)?(?:soundtrack|score|ost)$",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _soundtrack_body(cls, value: Optional[str]) -> str:
|
||||
"""剔除原声带标题尾部的通用描述词,返回电影名本体;无描述词返回空串。"""
|
||||
text = str(value or "").strip()
|
||||
body = cls._SOUNDTRACK_SUFFIX_RE.sub("", text)
|
||||
if not body or body == text:
|
||||
return ""
|
||||
return cls._normalize_text(body)
|
||||
|
||||
# 演唱会资源的标题常带演出后缀(S.H.E十七音乐会),条目仅保留演出名本体
|
||||
_PERFORMANCE_SUFFIX_RE = re.compile(
|
||||
r"\s*(?:音乐会|音樂會|演唱会|演唱會|巡回|巡演|Live|Tour)$", re.IGNORECASE)
|
||||
@@ -261,6 +278,12 @@ class MusicBrainzModule(_ModuleBase):
|
||||
# 专辑名开头的艺术家署名前缀同样是命名习惯,用主体名检索
|
||||
title = cls._strip_artist_prefix(title, meta.artists)
|
||||
bare_title = cls._strip_artist_prefix(bare_title, meta.artists)
|
||||
# 原声带标题的通用描述词(Original Motion Picture Soundtrack)在条目中常省略,
|
||||
# 用电影名本体补充一级检索(The Hateful Eight / Pulp Fiction);
|
||||
# 本体过短(The Score 类)时不作为独立检索目标避免噪声
|
||||
soundtrack_body = cls._soundtrack_body(bare_title)
|
||||
if len(cls._match_text(soundtrack_body)) < 4:
|
||||
soundtrack_body = ""
|
||||
queries: list[str] = []
|
||||
for query in [
|
||||
f'releasegroup:{cls._query_phrase(title)} AND artist:"{cls._escape_query(artist)}"'
|
||||
@@ -268,6 +291,9 @@ class MusicBrainzModule(_ModuleBase):
|
||||
f"releasegroup:{cls._query_phrase(title)}" if title else None,
|
||||
f'releasegroup:{cls._query_phrase(bare_title)} AND artist:"{cls._escape_query(artist)}"'
|
||||
if artist and bare_title and bare_title != title else None,
|
||||
f'releasegroup:{cls._query_phrase(soundtrack_body)} AND artist:"{cls._escape_query(artist)}"'
|
||||
if artist and soundtrack_body else None,
|
||||
f"releasegroup:{cls._query_phrase(soundtrack_body)}" if soundtrack_body else None,
|
||||
# 署名变体兜底:仅按去注释专辑名检索,挑选阶段要求艺术家同时命中
|
||||
f"releasegroup:{cls._query_phrase(bare_title)}" if bare_title else None,
|
||||
]:
|
||||
@@ -739,6 +765,15 @@ class MusicBrainzModule(_ModuleBase):
|
||||
cls._performance_title(bare_title)
|
||||
and cls._same_text(cls._performance_title(bare_title), album_title)
|
||||
)
|
||||
# 原声带资源的描述词在条目中常省略(Pulp Fiction: Music From the…),
|
||||
# 电影名本体与条目标题或主标题一致视为弱匹配
|
||||
or (
|
||||
len(cls._match_text(cls._soundtrack_body(bare_title))) >= 4
|
||||
and (
|
||||
cls._same_text(cls._soundtrack_body(bare_title), album_title)
|
||||
or cls._same_text(cls._soundtrack_body(bare_title), cls._main_title(album_title))
|
||||
)
|
||||
)
|
||||
)
|
||||
):
|
||||
# 「我爱夜 (新歌+精选)」对位条目「我爱夜」这类注释差异
|
||||
@@ -844,8 +879,14 @@ class MusicBrainzModule(_ModuleBase):
|
||||
# 格式标记后紧跟的场景发布组标签(如 ALAC-HHWEB),整体剔除
|
||||
text = re.sub(r"[-–—]\s*[A-Z0-9]{3,}\s*$", "", text)
|
||||
# 曲名尾部独立年份是发行线索不是曲名一部分(解析阶段通常已提取),
|
||||
# 检索时剥离避免年份文本造成精确短语零命中
|
||||
text = re.sub(r"(?<!\d)\s+(?:19|20)\d{2}$", "", cls._normalize_text(text))
|
||||
# 反复剥离尾部年份:场景命名可能重复携带(Live At Montreux 2011 2011)
|
||||
text = cls._normalize_text(text)
|
||||
while True:
|
||||
# 仅剔除空白分隔的尾部年份,纯年份标题(1999)无前导空白不受影响
|
||||
stripped = re.sub(r"\s+(?:19|20)\d{2}$", "", text)
|
||||
if stripped == text:
|
||||
break
|
||||
text = stripped
|
||||
return cls._normalize_text(text)
|
||||
|
||||
def recognize_music(self, source: str, media_id: str) -> Optional[MusicInfo]:
|
||||
|
||||
Reference in New Issue
Block a user