diff --git a/IntroSkipper/Analyzers/BlackFrameAnalyzer.cs b/IntroSkipper/Analyzers/BlackFrameAnalyzer.cs
index aad9eac..bb8f1ec 100644
--- a/IntroSkipper/Analyzers/BlackFrameAnalyzer.cs
+++ b/IntroSkipper/Analyzers/BlackFrameAnalyzer.cs
@@ -22,6 +22,8 @@ public class BlackFrameAnalyzer : IMediaFileAnalyzer
private readonly int _maximumCreditsDuration;
+ private readonly int _maximumMovieCreditsDuration;
+
private readonly int _blackFrameMinimumPercentage;
///
@@ -32,7 +34,8 @@ public class BlackFrameAnalyzer : IMediaFileAnalyzer
{
var config = Plugin.Instance?.Configuration ?? new PluginConfiguration();
_minimumCreditsDuration = config.MinimumCreditsDuration;
- _maximumCreditsDuration = 2 * config.MaximumCreditsDuration;
+ _maximumCreditsDuration = config.MaximumCreditsDuration;
+ _maximumMovieCreditsDuration = config.MaximumMovieCreditsDuration;
_blackFrameMinimumPercentage = config.BlackFrameMinimumPercentage;
_logger = logger;
@@ -66,7 +69,21 @@ public class BlackFrameAnalyzer : IMediaFileAnalyzer
break;
}
- // Pre-check to find reasonable starting point.
+ var creditDuration = episode.IsMovie ? _maximumMovieCreditsDuration : _maximumCreditsDuration;
+
+ var chapters = Plugin.Instance!.GetChapters(episode.EpisodeId);
+ var lastSuitableChapter = chapters.LastOrDefault(c =>
+ {
+ var start = TimeSpan.FromTicks(c.StartPositionTicks).TotalSeconds;
+ return start >= _minimumCreditsDuration && start <= creditDuration;
+ });
+
+ if (lastSuitableChapter is not null)
+ {
+ searchStart = TimeSpan.FromTicks(lastSuitableChapter.StartPositionTicks).TotalSeconds;
+ isFirstEpisode = false;
+ }
+
if (isFirstEpisode)
{
var scanTime = episode.Duration - searchStart;
@@ -83,9 +100,9 @@ public class BlackFrameAnalyzer : IMediaFileAnalyzer
frames = FFmpegWrapper.DetectBlackFrames(episode, tr, _blackFrameMinimumPercentage);
- if (searchStart > _maximumCreditsDuration)
+ if (searchStart > creditDuration)
{
- searchStart = _maximumCreditsDuration;
+ searchStart = creditDuration;
break;
}
}
@@ -143,6 +160,8 @@ public class BlackFrameAnalyzer : IMediaFileAnalyzer
var end = TimeSpan.FromSeconds(lowerLimit);
var firstFrameTime = 0.0;
+ var creditDuration = episode.IsMovie ? _maximumMovieCreditsDuration : _maximumCreditsDuration;
+
// Continue bisecting the end of the file until the range that contains the first black
// frame is smaller than the maximum permitted error.
while (start - end > _maximumError)
@@ -189,7 +208,7 @@ public class BlackFrameAnalyzer : IMediaFileAnalyzer
if (TimeSpan.FromSeconds(upperLimit) - midpoint < _maximumError)
{
- upperLimit = Math.Min(upperLimit + (0.5 * searchDistance), _maximumCreditsDuration);
+ upperLimit = Math.Min(upperLimit + (0.5 * searchDistance), creditDuration);
// Reset start for a new search with the increased duration
start = TimeSpan.FromSeconds(upperLimit);
diff --git a/IntroSkipper/Analyzers/ChapterAnalyzer.cs b/IntroSkipper/Analyzers/ChapterAnalyzer.cs
index 5fe2ffa..6cf832b 100644
--- a/IntroSkipper/Analyzers/ChapterAnalyzer.cs
+++ b/IntroSkipper/Analyzers/ChapterAnalyzer.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
@@ -92,9 +91,10 @@ public class ChapterAnalyzer(ILogger logger) : IMediaFileAnalyz
}
var config = Plugin.Instance?.Configuration ?? new PluginConfiguration();
+ var creditDuration = episode.IsMovie ? config.MaximumMovieCreditsDuration : config.MaximumCreditsDuration;
var reversed = mode != AnalysisMode.Introduction;
var (minDuration, maxDuration) = reversed
- ? (config.MinimumCreditsDuration, config.MaximumCreditsDuration)
+ ? (config.MinimumCreditsDuration, creditDuration)
: (config.MinimumIntroDuration, config.MaximumIntroDuration);
// Check all chapters
diff --git a/IntroSkipper/Configuration/PluginConfiguration.cs b/IntroSkipper/Configuration/PluginConfiguration.cs
index 852da07..968fd92 100644
--- a/IntroSkipper/Configuration/PluginConfiguration.cs
+++ b/IntroSkipper/Configuration/PluginConfiguration.cs
@@ -33,6 +33,11 @@ public class PluginConfiguration : BasePluginConfiguration
///
public bool SelectAllLibraries { get; set; } = true;
+ ///
+ /// Gets or sets a value indicating whether movies should be analyzed.
+ ///
+ public bool AnalyzeMovies { get; set; }
+
///
/// Gets or sets the list of client to auto skip for.
///
@@ -107,7 +112,12 @@ public class PluginConfiguration : BasePluginConfiguration
///
/// Gets or sets the upper limit (in seconds) on the length of each episode's audio track that will be analyzed when searching for ending credits.
///
- public int MaximumCreditsDuration { get; set; } = 300;
+ public int MaximumCreditsDuration { get; set; } = 450;
+
+ ///
+ /// Gets or sets the upper limit (in seconds) on the length of a movie segment that will be analyzed when searching for ending credits.
+ ///
+ public int MaximumMovieCreditsDuration { get; set; } = 900;
///
/// Gets or sets the minimum percentage of a frame that must consist of black pixels before it is considered a black frame.
diff --git a/IntroSkipper/Configuration/configPage.html b/IntroSkipper/Configuration/configPage.html
index bd2965d..5d9a567 100644
--- a/IntroSkipper/Configuration/configPage.html
+++ b/IntroSkipper/Configuration/configPage.html
@@ -52,6 +52,15 @@
+
+
+
+
If checked, movies will be included in analysis.
+
+
- Select the first episode
-
- Select the second episode
-
-
+
+ Select the first episode
+
+ Select the second episode
+
+
+
Introduction timestamp editor
@@ -465,33 +485,35 @@
-
-
-
-
- Intro Start
-
-
+
+
+
+
+
+ Intro Start
+
+
+
+
+ Intro End
+
+
+
-
- Intro End
-
-
+
+
+ Credits Start
+
+
+
+
+ Credits End
+
+
+
+
-
-
- Credits Start
-
-
-
-
- Credits End
-
-
-
-
-
@@ -502,51 +524,56 @@
-
Fingerprint Visualizer
-
- Interactively compare the audio fingerprints of two episodes.
- The blue and red bar to the right of the fingerprint diff turns blue when the corresponding fingerprint points are at least 80% similar.
-
-
-
-
-
Key
-
Function
-
-
-
-
-
Up arrow
-
Shift the left episode up by 0.1238 seconds. Holding control will shift the episode by 10 seconds.
-
-
-
Down arrow
-
Shift the left episode down by 0.1238 seconds. Holding control will shift the episode by 10 seconds.
-
-
-
Right arrow
-
Advance to the next pair of episodes.
-
-
-
Left arrow
-
Go back to the previous pair of episodes.
-
-
-
-
+
- Shift amount:
-
-
- Suggested shifts:
-
-
+
Fingerprint Visualizer
+
+ Interactively compare the audio fingerprints of two episodes.
+ The blue and red bar to the right of the fingerprint diff turns blue when the corresponding fingerprint points are at least 80% similar.
+
+
+
+
+
Key
+
Function
+
+
+
+
+
Up arrow
+
Shift the left episode up by 0.1238 seconds. Holding control will shift the episode by 10 seconds.
+
+
+
Down arrow
+
Shift the left episode down by 0.1238 seconds. Holding control will shift the episode by 10 seconds.