MoviePilot-Plugins中BGM打格子插件的问题分析与解决方案
背景介绍
在动漫媒体库管理中,BGM打格子是一个重要的功能,它能够帮助用户标记已观看的剧集。然而在使用MoviePilot-Plugins项目中的BGM打格子插件时,用户遇到了一个典型问题:当播放《从零开始的异世界生活》第三季第一集时,插件错误地识别为第一季的内容。
问题分析
经过深入的技术讨论和代码审查,我们发现这个问题源于以下几个技术点:
-
TMDB数据源匹配问题:插件主要依赖TMDB的API获取剧集信息,但TMDB对于续作剧集有两种处理方式:
- 常规分季处理(如Clannad)
- 剧集组处理(如Re:从零开始的异世界生活)
-
剧集编号偏移问题:对于使用剧集组的番剧,TMDB返回的剧集编号是累计的绝对编号(如第三季第一集为E51),而用户媒体库中可能使用的是相对编号(S03E01)。
-
数据获取逻辑缺陷:当前插件在TMDB查询失败时,会默认回退到查询第一季内容,这是导致错误匹配的根本原因。
解决方案
针对上述问题,我们提出了多层次的解决方案:
1. 增强TMDB查询逻辑
def get_tv_season_detail(tmdbid, season):
# 首先尝试常规季查询
url = f"https://api.tmdb.org/3/tv/{tmdbid}/season/{season}?api_key={key}"
resp = requests.get(url).json()
# 如果常规查询失败,尝试剧集组查询
if not resp or resp.get("success") is False:
group_url = f"https://api.tmdb.org/3/tv/{tmdbid}/episode_groups"
groups = requests.get(group_url).json()
# 查找包含所有季的"Seasons"组
seasons_group = next((g for g in groups["results"] if g["name"] == "Seasons"), None)
if seasons_group:
group_detail = requests.get(f"https://api.tmdb.org/3/tv/episode_group/{seasons_group['id']}").json()
# 处理返回的剧集信息
...
return resp
2. 改进剧集匹配策略
我们实现了双重匹配机制:
- 优先使用TMDB返回的绝对剧集编号(episode_number)进行匹配
- 如果绝对编号匹配失败,则使用相对顺序(order+1)作为备选方案
3. 数据类型处理优化
针对Webhook返回的数据类型不一致问题,我们增加了健壮的类型处理:
try:
unique_id = int(tmdb_id)
except (ValueError, TypeError):
unique_id = None
技术实现细节
-
剧集组数据处理:通过TMDB的剧集组API获取完整季信息,正确处理累计剧集编号。
-
标题匹配增强:增加了对原始日文标题的匹配支持,提高匹配准确率。
-
错误处理机制:完善了各种边界条件的处理,包括:
- TMDB ID为"None"字符串的情况
- 剧集组不包含"Seasons"字段的情况
- 季/集信息缺失时的备选处理
最佳实践建议
-
媒体库命名规范:建议采用"SXXEYY"的命名格式,保持一致性。
-
刮削策略选择:对于有续作的番剧,优先使用TMDB的"Seasons"剧集组进行刮削。
-
测试验证:在使用前,建议通过插件日志验证匹配结果是否正确。
总结
通过对MoviePilot-Plugins中BGM打格子插件的深入分析和改进,我们解决了续作动漫剧集匹配错误的问题。新的实现不仅提高了匹配准确率,还增强了插件的健壮性,能够更好地适应各种特殊情况的处理。
这次改进也为我们提供了宝贵的经验:在处理动漫媒体库时,需要特别注意不同数据源对续作剧集的不同处理方式,以及各种边界条件的完善处理。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考