diff --git a/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs b/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs
index 4c5fc8f..c8bd63a 100644
--- a/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs
+++ b/Jellyfin.Plugin.MetaShark.Test/ParseNameTest.cs
@@ -174,19 +174,20 @@ namespace Jellyfin.Plugin.MetaShark.Test
Assert.AreEqual(parseResult.Name, "New World");
Assert.AreEqual(parseResult.Year, 2013);
- // 只英文S01E01
+ // 只英文 S01E01
fileName = "She-Hulk.Attorney.At.Law.S01E01.1080p.WEBRip.x265-RARBG";
parseResult = NameParser.Parse(fileName);
Assert.AreEqual(parseResult.Name, "She-Hulk Attorney At Law");
Assert.AreEqual(parseResult.ParentIndexNumber, 1);
Assert.AreEqual(parseResult.IndexNumber, 1);
- // 只英文S01EP01
- fileName = "Detective.Dee.S01EP18.2004.1080p.WEB-DL.x264.AAC-HQCS";
+ // 测试 SXXEPXX 格式
+ fileName = "神探狄仁杰2 Detective.Dee.Ⅱ.S02EP02.2006.2160p.WEB-DL.x264.AAC-HQC";
parseResult = NameParser.Parse(fileName);
- Assert.AreEqual(parseResult.Name, "Detective Dee");
- Assert.AreEqual(parseResult.ParentIndexNumber, 1);
- Assert.AreEqual(parseResult.IndexNumber, 18);
+ Assert.AreEqual(parseResult.ChineseName, "神探狄仁杰2");
+ Assert.AreEqual(parseResult.Name, "Detective Dee Ⅱ");
+ Assert.AreEqual(parseResult.ParentIndexNumber, 2);
+ Assert.AreEqual(parseResult.IndexNumber, 2);
// 日文
diff --git a/Jellyfin.Plugin.MetaShark/Core/NameParser.cs b/Jellyfin.Plugin.MetaShark/Core/NameParser.cs
index c7690c1..e8bf797 100644
--- a/Jellyfin.Plugin.MetaShark/Core/NameParser.cs
+++ b/Jellyfin.Plugin.MetaShark/Core/NameParser.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using Emby.Naming.TV;
using Jellyfin.Plugin.MetaShark.Model;
namespace Jellyfin.Plugin.MetaShark.Core
@@ -110,7 +111,7 @@ namespace Jellyfin.Plugin.MetaShark.Core
// 假如Anitomy解析不到year,尝试使用jellyfin默认parser,看能不能解析成功
if (parseResult.Year == null && !isAnime)
{
- var nativeParseResult = ParseMovie(fileName);
+ var nativeParseResult = ParseMovieByDefault(fileName);
if (nativeParseResult.Year != null)
{
parseResult = nativeParseResult;
@@ -143,8 +144,10 @@ namespace Jellyfin.Plugin.MetaShark.Core
return name.Replace(".", " ").Trim();
}
- // emby原始电影解析
- public static ParseNameResult ParseMovie(string fileName)
+ ///
+ /// emby原始电影解析
+ ///
+ public static ParseNameResult ParseMovieByDefault(string fileName)
{
// 默认解析器会错误把分辨率当年份,先删除
fileName = resolutionReg.Replace(fileName, "");
@@ -165,6 +168,16 @@ namespace Jellyfin.Plugin.MetaShark.Core
return parseResult;
}
+ ///
+ /// emby原始剧集解析
+ ///
+ public static EpisodePathParserResult ParseEpisodeByDefault(string fileName)
+ {
+ var nameOptions = new Emby.Naming.Common.NamingOptions();
+ return new EpisodePathParser(nameOptions)
+ .Parse(fileName, false);
+ }
+
private static int ParseYear(string val)
{
diff --git a/Jellyfin.Plugin.MetaShark/Providers/EpisodeProvider.cs b/Jellyfin.Plugin.MetaShark/Providers/EpisodeProvider.cs
index 0bbb34d..04f688d 100644
--- a/Jellyfin.Plugin.MetaShark/Providers/EpisodeProvider.cs
+++ b/Jellyfin.Plugin.MetaShark/Providers/EpisodeProvider.cs
@@ -44,8 +44,8 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// 刷新元数据四种模式差别:
// 自动扫描匹配:info的Name、IndexNumber和ParentIndexNumber是从文件名解析出来的,假如命名不规范,就会导致解析出错误值
// 识别:info的Name、IndexNumber和ParentIndexNumber是从文件名解析出来的,provinceIds有指定选择项的ProvinceId
+ // 覆盖所有元数据:info的Name、IndexNumber和ParentIndexNumber是从文件名解析出来的,provinceIds保留所有旧值
// 搜索缺少的元数据:info的Name、IndexNumber和ParentIndexNumber是从当前的元数据获取,provinceIds保留所有旧值
- // 覆盖所有元数据:info的Name、IndexNumber和ParentIndexNumber是从当前的元数据获取,provinceIds保留所有旧值
this.Log($"GetEpisodeMetadata of [name]: {info.Name} number: {info.IndexNumber} ParentIndexNumber: {info.ParentIndexNumber} IsAutomated: {info.IsAutomated}");
var result = new MetadataResult();
@@ -139,6 +139,14 @@ namespace Jellyfin.Plugin.MetaShark.Providers
info.Year = parseResult.Year;
info.Name = parseResult.ChineseName ?? parseResult.Name;
+ // 修正文件名有特殊命名SXXEPXX时,默认解析到错误季数的问题,如神探狄仁杰 Detective.Dee.S01EP01.2006.2160p.WEB-DL.x264.AAC-HQC
+ // TODO: 会导致覆盖用户手动修改元数据的季数
+ if (info.ParentIndexNumber.HasValue && parseResult.ParentIndexNumber.HasValue && parseResult.ParentIndexNumber > 0 && info.ParentIndexNumber != parseResult.ParentIndexNumber)
+ {
+ this.Log("FixSeasonNumber by anitomy. old: {0} new: {1}", info.ParentIndexNumber, parseResult.ParentIndexNumber);
+ info.ParentIndexNumber = parseResult.ParentIndexNumber;
+ }
+
// 没有season级目录(即虚拟季)ParentIndexNumber默认是1,季文件夹命名不规范时,ParentIndexNumber默认是null
if (info.ParentIndexNumber is null)
{
@@ -152,11 +160,10 @@ namespace Jellyfin.Plugin.MetaShark.Providers
var season = episodeItem != null ? ((Episode)episodeItem).Season : null;
if (season != null && season.IndexNumber.HasValue && info.ParentIndexNumber != season.IndexNumber)
{
- this.Log("FixSeasonNumber: old: {0} new: {1}", info.ParentIndexNumber, season.IndexNumber);
+ this.Log("FixSeasonNumber by season. old: {0} new: {1}", info.ParentIndexNumber, season.IndexNumber);
info.ParentIndexNumber = season.IndexNumber;
}
-
// // 当没有season级目录时,默认为1,即当成只有一季(不需要处理,虚拟季jellyfin默认传的ParentIndexNumber=1)
// if (info.ParentIndexNumber is null && season != null && season.LocationType == LocationType.Virtual)
// {
@@ -172,7 +179,6 @@ namespace Jellyfin.Plugin.MetaShark.Providers
info.ParentIndexNumber = this.GuessSeasonNumberByDirectoryName(seasonFolderPath);
}
-
// 识别特典
if (info.ParentIndexNumber is null && NameParser.IsAnime(fileName) && (parseResult.IsSpecial || NameParser.IsSpecialDirectory(info.Path)))
{
@@ -186,17 +192,16 @@ namespace Jellyfin.Plugin.MetaShark.Providers
// info.ParentIndexNumber = 1;
// }
-
// 特典优先使用文件名(特典除了前面特别设置,还有SXX/Season XX等默认的)
if (info.ParentIndexNumber.HasValue && info.ParentIndexNumber == 0)
{
info.Name = parseResult.SpecialName == info.Name ? fileName : parseResult.SpecialName;
}
-
// 大于1000,可能错误解析了分辨率
- if (parseResult.IndexNumber.HasValue && parseResult.IndexNumber < 1000)
+ if (parseResult.IndexNumber.HasValue && parseResult.IndexNumber < 1000 && info.IndexNumber != parseResult.IndexNumber)
{
+ this.Log("FixEpisodeNumber by anitomy. old: {0} new: {1}", info.IndexNumber, parseResult.IndexNumber);
info.IndexNumber = parseResult.IndexNumber;
}