Search credits from the end of episode
This commit is contained in:
parent
dfe28b7080
commit
c6bb3dbad5
@ -96,6 +96,11 @@ public class ChapterAnalyzer : IMediaFileAnalyzer
|
|||||||
config.MaximumIntroDuration :
|
config.MaximumIntroDuration :
|
||||||
config.MaximumEpisodeCreditsDuration;
|
config.MaximumEpisodeCreditsDuration;
|
||||||
|
|
||||||
|
if (chapters.Count == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == AnalysisMode.Credits)
|
if (mode == AnalysisMode.Credits)
|
||||||
{
|
{
|
||||||
// Since the ending credits chapter may be the last chapter in the file, append a virtual
|
// Since the ending credits chapter may be the last chapter in the file, append a virtual
|
||||||
@ -104,8 +109,57 @@ public class ChapterAnalyzer : IMediaFileAnalyzer
|
|||||||
{
|
{
|
||||||
StartPositionTicks = TimeSpan.FromSeconds(episode.Duration).Ticks
|
StartPositionTicks = TimeSpan.FromSeconds(episode.Duration).Ticks
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check all chapters in reverse order, skipping the virtual chapter
|
||||||
|
for (int i = chapters.Count - 2; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var current = chapters[i];
|
||||||
|
var next = chapters[i + 1];
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(current.Name))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentRange = new TimeRange(
|
||||||
|
TimeSpan.FromTicks(current.StartPositionTicks).TotalSeconds,
|
||||||
|
TimeSpan.FromTicks(next.StartPositionTicks).TotalSeconds);
|
||||||
|
|
||||||
|
var baseMessage = string.Format(
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
"{0}: Chapter \"{1}\" ({2} - {3})",
|
||||||
|
episode.Path,
|
||||||
|
current.Name,
|
||||||
|
currentRange.Start,
|
||||||
|
currentRange.End);
|
||||||
|
|
||||||
|
if (currentRange.Duration < minDuration || currentRange.Duration > maxDuration)
|
||||||
|
{
|
||||||
|
_logger.LogTrace("{Base}: ignoring (invalid duration)", baseMessage);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regex.IsMatch() is used here in order to allow the runtime to cache the compiled regex
|
||||||
|
// between function invocations.
|
||||||
|
var match = Regex.IsMatch(
|
||||||
|
current.Name,
|
||||||
|
expression,
|
||||||
|
RegexOptions.None,
|
||||||
|
TimeSpan.FromSeconds(1));
|
||||||
|
|
||||||
|
if (!match)
|
||||||
|
{
|
||||||
|
_logger.LogTrace("{Base}: ignoring (does not match regular expression)", baseMessage);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
matchingChapter = new(episode.EpisodeId, currentRange);
|
||||||
|
_logger.LogTrace("{Base}: okay", baseMessage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Check all chapters
|
// Check all chapters
|
||||||
for (int i = 0; i < chapters.Count - 1; i++)
|
for (int i = 0; i < chapters.Count - 1; i++)
|
||||||
{
|
{
|
||||||
@ -168,6 +222,7 @@ public class ChapterAnalyzer : IMediaFileAnalyzer
|
|||||||
_logger.LogTrace("{Base}: okay", baseMessage);
|
_logger.LogTrace("{Base}: okay", baseMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return matchingChapter;
|
return matchingChapter;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ public class PluginConfiguration : BasePluginConfiguration
|
|||||||
/// Gets or sets the regular expression used to detect ending credit chapters.
|
/// Gets or sets the regular expression used to detect ending credit chapters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ChapterAnalyzerEndCreditsPattern { get; set; } =
|
public string ChapterAnalyzerEndCreditsPattern { get; set; } =
|
||||||
@"(^|\s)(Credits?|Ending)(\s|$)";
|
@"(^|\s)(Credits?|ED|Ending)(\s|$)";
|
||||||
|
|
||||||
// ===== Playback settings =====
|
// ===== Playback settings =====
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user