From 055a851e2793e4feb2ba652814f2d76242dfbd76 Mon Sep 17 00:00:00 2001 From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com> Date: Sun, 26 Jun 2022 22:54:47 -0500 Subject: [PATCH 1/2] Allow customizing analysis settings --- .../Configuration/PluginConfiguration.cs | 14 ++++++ .../Configuration/configPage.html | 45 +++++++++++++++++++ .../QueueManager.cs | 23 ++++++++-- README.md | 1 + 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs index 5a31357..d1854c7 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs @@ -14,6 +14,8 @@ public class PluginConfiguration : BasePluginConfiguration { } + // ===== Analysis settings ===== + /// /// Gets or sets a value indicating whether the episode's fingerprint should be cached to the filesystem. /// @@ -24,6 +26,18 @@ public class PluginConfiguration : BasePluginConfiguration /// public int MaxParallelism { get; set; } = 2; + /// + /// Gets or sets the percentage of each episode's audio track to analyze. + /// + public int AnalysisPercent { get; set; } = 25; + + /// + /// Gets or sets the upper limit (in minutes) on the length of each episode's audio track that will be analyzed. + /// + public int AnalysisLengthLimit { get; set; } = 10; + + // ===== Playback settings ===== + /// /// Gets or sets a value indicating whether introductions should be automatically skipped. /// diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html index 54d8930..3531b2d 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html @@ -37,6 +37,45 @@ Maximum degree of parallelism to use when analyzing episodes. + +
+ Modify introduction requirements + +
+ + +
+ Analysis will be limited to this percentage of each episode's audio. For example, a + value of 25 (the default) will limit analysis to the first quarter of each episode. +
+
+ +
+ + +
+ Analysis will be limited to this amount of each episode's audio. For example, a + value of 10 (the default) will limit analysis to the first 10 minutes of each + episode. +
+
+ +

+ The amount of each episode's audio that will be analyzed is determined by these two + settings. The minimum of (episode duration * percent, maximum runtime) is the amount of + audio that will be analyzed.
+ + If these settings are changed after analyzing your media, the cached fingerprints and + introduction timestamps for each season you want to analyze with the modified settings + will have to be deleted. +

+ + Increasing these settings will cause episode analysis to take much longer. +
@@ -439,6 +478,9 @@ document.querySelector('#AutoSkip').checked = config.AutoSkip; document.querySelector('#MaxParallelism').value = config.MaxParallelism; + document.querySelector('#AnalysisPercent').value = config.AnalysisPercent; + document.querySelector('#AnalysisLengthLimit').value = config.AnalysisLengthLimit; + document.querySelector('#CacheFingerprints').checked = config.CacheFingerprints; document.querySelector('#ShowPromptAdjustment').value = config.ShowPromptAdjustment; document.querySelector('#HidePromptAdjustment').value = config.HidePromptAdjustment; @@ -454,6 +496,9 @@ config.AutoSkip = document.querySelector('#AutoSkip').checked; config.MaxParallelism = document.querySelector('#MaxParallelism').value; + config.AnalysisPercent = document.querySelector('#AnalysisPercent').value; + config.AnalysisLengthLimit = document.querySelector('#AnalysisLengthLimit').value; + config.CacheFingerprints = document.querySelector('#CacheFingerprints').checked; config.ShowPromptAdjustment = document.querySelector("#ShowPromptAdjustment").value; config.HidePromptAdjustment = document.querySelector("#HidePromptAdjustment").value; diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs b/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs index 3996fbc..5946a62 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs @@ -17,6 +17,8 @@ public class QueueManager private ILibraryManager _libraryManager; private ILogger _logger; + private double analysisPercent; + /// /// Initializes a new instance of the class. /// @@ -42,6 +44,18 @@ public class QueueManager Plugin.Instance!.AnalysisQueue.Clear(); + // If analysis settings have been changed from the default, log the modified settings. + var config = Plugin.Instance!.Configuration; + analysisPercent = Convert.ToDouble(config.AnalysisPercent) / 100; + + if (config.AnalysisLengthLimit != 10 || config.AnalysisPercent != 25) + { + _logger.LogDebug( + "Introduction scan is limited to the first {Percent}% or the first {Minutes} minutes of each episode (whichever is smaller)", + config.AnalysisPercent, + config.AnalysisLengthLimit); + } + // For all TV show libraries, enqueue all contained items. foreach (var folder in _libraryManager.GetVirtualFolders()) { @@ -132,14 +146,17 @@ public class QueueManager Plugin.Instance.AnalysisQueue[episode.SeasonId] = new List(); } - // Only fingerprint up to 25% of the episode and at most 10 minutes. + var config = Plugin.Instance!.Configuration; + + // Limit analysis to the first X% of the episode and at most Y minutes. + // X and Y default to 25% and 10 minutes. var duration = TimeSpan.FromTicks(episode.RunTimeTicks ?? 0).TotalSeconds; if (duration >= 5 * 60) { - duration /= 4; + duration *= analysisPercent; } - duration = Math.Min(duration, 10 * 60); + duration = Math.Min(duration, 60 * config.AnalysisLengthLimit); Plugin.Instance.AnalysisQueue[episode.SeasonId].Add(new QueuedEpisode() { diff --git a/README.md b/README.md index 877beba..29ebe30 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Plugin versions v0.1.0 and older require `fpcalc` to be installed. Show introductions will only be detected if they are: * Located within the first 25% of an episode, or the first 10 minutes, whichever is smaller + * Both of these settings are customizable * At least 20 seconds long ## Step 1: Optional: use the modified web interface From a1a10874d353a7084a0ec08138dcada7069d0fd2 Mon Sep 17 00:00:00 2001 From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com> Date: Sun, 3 Jul 2022 01:59:16 -0500 Subject: [PATCH 2/2] Allow customizing minimum intro duration Closes #51 --- .../Configuration/PluginConfiguration.cs | 5 +++ .../Configuration/configPage.html | 31 ++++++++++++++----- .../QueueManager.cs | 7 +++-- .../ScheduledTasks/FingerprinterTask.cs | 16 +++++----- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs index d1854c7..cd5007e 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs @@ -36,6 +36,11 @@ public class PluginConfiguration : BasePluginConfiguration /// public int AnalysisLengthLimit { get; set; } = 10; + /// + /// Gets or sets the minimum length of similar audio that will be considered an introduction. + /// + public int MinimumIntroDuration { get; set; } = 15; + // ===== Playback settings ===== /// diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html index 3531b2d..c0639a4 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html @@ -64,17 +64,32 @@ -

- The amount of each episode's audio that will be analyzed is determined by these two - settings. The minimum of (episode duration * percent, maximum runtime) is the amount of - audio that will be analyzed.
+

+ + +
+ Similar sounding audio which is shorter than this duration will not be considered an + introduction. +
+
- If these settings are changed after analyzing your media, the cached fingerprints and - introduction timestamps for each season you want to analyze with the modified settings +

+ The amount of each episode's audio that will be analyzed is determined using both + the percentage of audio and maximum runtime of audio to analyze. The minimum of + (episode duration * percent, maximum runtime) is the amount of audio that will + be analyzed.
+ + If the audio percentage or maximum runtime settings are changed after analyzing your + media, the cached fingerprints and introduction timestamps for each season you want to + analyze with the modified settings will have to be deleted.

- Increasing these settings will cause episode analysis to take much longer. + + Increasing either of these settings will cause episode analysis to take much longer. +
@@ -480,6 +495,7 @@ document.querySelector('#AnalysisPercent').value = config.AnalysisPercent; document.querySelector('#AnalysisLengthLimit').value = config.AnalysisLengthLimit; + document.querySelector('#MinimumDuration').value = config.MinimumIntroDuration; document.querySelector('#CacheFingerprints').checked = config.CacheFingerprints; document.querySelector('#ShowPromptAdjustment').value = config.ShowPromptAdjustment; @@ -498,6 +514,7 @@ config.AnalysisPercent = document.querySelector('#AnalysisPercent').value; config.AnalysisLengthLimit = document.querySelector('#AnalysisLengthLimit').value; + config.MinimumIntroDuration = document.querySelector('#MinimumDuration').value; config.CacheFingerprints = document.querySelector('#CacheFingerprints').checked; config.ShowPromptAdjustment = document.querySelector("#ShowPromptAdjustment").value; diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs b/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs index 5946a62..c8f371c 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs @@ -48,12 +48,13 @@ public class QueueManager var config = Plugin.Instance!.Configuration; analysisPercent = Convert.ToDouble(config.AnalysisPercent) / 100; - if (config.AnalysisLengthLimit != 10 || config.AnalysisPercent != 25) + if (config.AnalysisLengthLimit != 10 || config.AnalysisPercent != 25 || config.MinimumIntroDuration != 15) { _logger.LogDebug( - "Introduction scan is limited to the first {Percent}% or the first {Minutes} minutes of each episode (whichever is smaller)", + "Analysis settings have been changed to: {Percent}%/{Minutes}m and a minimum of {Minimum}s", config.AnalysisPercent, - config.AnalysisLengthLimit); + config.AnalysisLengthLimit, + config.MinimumIntroDuration); } // For all TV show libraries, enqueue all contained items. diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs index 0520f20..20e5e2f 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs @@ -15,11 +15,6 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper; /// public class FingerprinterTask : IScheduledTask { - /// - /// Minimum time (in seconds) for a contiguous time range to be considered an introduction. - /// - private const int MinimumIntroDuration = 15; - /// /// Maximum number of bits (out of 32 total) that can be different between segments before they are considered dissimilar. /// 6 bits means the audio must be at least 81% similar (1 - 6 / 32). @@ -68,6 +63,11 @@ public class FingerprinterTask : IScheduledTask /// private Dictionary> _fingerprintCache; + /// + /// Minimum duration of similar audio that will be considered an introduction. + /// + private static int minimumIntroDuration = 15; + /// /// Initializes a new instance of the class. /// @@ -143,6 +143,8 @@ public class FingerprinterTask : IScheduledTask MaxDegreeOfParallelism = Plugin.Instance!.Configuration.MaxParallelism }; + minimumIntroDuration = Plugin.Instance!.Configuration.MinimumIntroDuration; + Parallel.ForEach(queue, options, (season) => { var first = season.Value[0]; @@ -533,7 +535,7 @@ public class FingerprinterTask : IScheduledTask // Now that both fingerprints have been compared at this shift, see if there's a contiguous time range. var lContiguous = TimeRangeHelpers.FindContiguous(lhsTimes.ToArray(), MaximumDistance); - if (lContiguous is null || lContiguous.Duration < MinimumIntroDuration) + if (lContiguous is null || lContiguous.Duration < minimumIntroDuration) { return (new TimeRange(), new TimeRange()); } @@ -599,7 +601,7 @@ public class FingerprinterTask : IScheduledTask var id = episode.EpisodeId; var duration = GetIntroDuration(id); - if (duration < MinimumIntroDuration) + if (duration < minimumIntroDuration) { continue; }