diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs
index 6311298..46d3652 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs
@@ -62,17 +62,6 @@ public class PluginConfiguration : BasePluginConfiguration
///
public int MinimumIntroDuration { get; set; } = 15;
- ///
- /// Gets or sets the maximum amount of noise (in dB) that is considered silent.
- /// Lowering this number will increase the filter's sensitivity to noise.
- ///
- public int SilenceDetectionMaximumNoise { get; set; } = -50;
-
- ///
- /// Gets or sets the minimum duration of audio (in seconds) that is considered silent.
- ///
- public double SilenceDetectionMinimumDuration { get; set; } = 0.50;
-
// ===== Playback settings =====
///
@@ -93,5 +82,34 @@ public class PluginConfiguration : BasePluginConfiguration
///
/// Gets or sets the amount of intro to play (in seconds).
///
- public int SecondsOfIntroToPlay { get; set; } = 2;
+ public int SecondsOfIntroToPlay { get; set; } = 3;
+
+ // ===== Internal algorithm settings =====
+
+ ///
+ /// Gets or sets the maximum number of bits (out of 32 total) that can be different between two Chromaprint points before they are considered dissimilar.
+ /// Defaults to 6 (81% similar).
+ ///
+ public int MaximumFingerprintPointDifferences { get; set; } = 6;
+
+ ///
+ /// Gets or sets the maximum number of seconds that can pass between two similar fingerprint points before a new time range is started.
+ ///
+ public double MaximumTimeSkip { get; set; } = 3.5;
+
+ ///
+ /// Gets or sets the amount to shift inverted indexes by.
+ ///
+ public int InvertedIndexShift { get; set; } = 2;
+
+ ///
+ /// Gets or sets the maximum amount of noise (in dB) that is considered silent.
+ /// Lowering this number will increase the filter's sensitivity to noise.
+ ///
+ public int SilenceDetectionMaximumNoise { get; set; } = -50;
+
+ ///
+ /// Gets or sets the minimum duration of audio (in seconds) that is considered silent.
+ ///
+ public double SilenceDetectionMinimumDuration { get; set; } = 0.33;
}
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html
index 377eb03..99981cf 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/configPage.html
@@ -154,6 +154,32 @@
Increasing either of these settings will cause episode analysis to take much longer.
+
+
+ Silence detection options
+
+
+
+
+
+ Noise tolerance in negative decibels.
+
+
+
+
+
+
+
+ Minimum silence duration in seconds before adjusting introduction end time.
+
+
+
@@ -201,12 +237,6 @@
-
-
- Erasing introduction timestamps is only necessary after upgrading the plugin if specifically
- requested to do so in the plugin's changelog. After the timestamps are erased, run the
- Analyze episodes scheduled task to re-analyze all media on the server.
-
@@ -337,14 +367,20 @@
// all plugin configuration fields that can be get or set with .value (i.e. strings or numbers).
var configurationFields = [
+ // analysis
"MaxParallelism",
"SelectedLibraries",
"AnalysisPercent",
"AnalysisLengthLimit",
"MinimumIntroDuration",
"EdlAction",
+ // playback
"ShowPromptAdjustment",
- "HidePromptAdjustment"
+ "HidePromptAdjustment",
+ "SecondsOfIntroToPlay",
+ // internals
+ "SilenceDetectionMaximumNoise",
+ "SilenceDetectionMinimumDuration",
]
// visualizer elements
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/AnalyzeEpisodesTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/AnalyzeEpisodesTask.cs
index 5edc7a9..fcd3e89 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/AnalyzeEpisodesTask.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/AnalyzeEpisodesTask.cs
@@ -15,22 +15,6 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper;
///
public class AnalyzeEpisodesTask : IScheduledTask
{
- ///
- /// 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).
- ///
- private const double MaximumDifferences = 6;
-
- ///
- /// Maximum time (in seconds) permitted between timestamps before they are considered non-contiguous.
- ///
- private const double MaximumDistance = 3.5;
-
- ///
- /// Amount to shift inverted index offsets by.
- ///
- private const int InvertedIndexShift = 2;
-
///
/// Seconds of audio in one fingerprint point. This value is defined by the Chromaprint library and should not be changed.
///
@@ -57,6 +41,14 @@ public class AnalyzeEpisodesTask : IScheduledTask
///
private static int minimumIntroDuration = 15;
+ private static int maximumDifferences = 6;
+
+ private static int invertedIndexShift = 2;
+
+ private static double maximumTimeSkip = 3.5;
+
+ private static double silenceDetectionMinimumDuration = 0.33;
+
///
/// Initializes a new instance of the class.
///
@@ -124,6 +116,13 @@ public class AnalyzeEpisodesTask : IScheduledTask
"No episodes to analyze. If you are limiting the list of libraries to analyze, check that all library names have been spelled correctly.");
}
+ // Load analysis settings from configuration
+ var config = Plugin.Instance?.Configuration ?? new Configuration.PluginConfiguration();
+ maximumDifferences = config.MaximumFingerprintPointDifferences;
+ invertedIndexShift = config.InvertedIndexShift;
+ maximumTimeSkip = config.MaximumTimeSkip;
+ silenceDetectionMinimumDuration = config.SilenceDetectionMinimumDuration;
+
// Log EDL settings
EdlManager.LogConfiguration();
@@ -448,7 +447,7 @@ public class AnalyzeEpisodesTask : IScheduledTask
{
var originalPoint = kvp.Key;
- for (var i = -1 * InvertedIndexShift; i <= InvertedIndexShift; i++)
+ for (var i = -1 * invertedIndexShift; i <= invertedIndexShift; i++)
{
var modifiedPoint = (uint)(originalPoint + i);
@@ -542,7 +541,7 @@ public class AnalyzeEpisodesTask : IScheduledTask
var diff = lhs[lhsPosition] ^ rhs[rhsPosition];
// If the difference between the samples is small, flag both times as similar.
- if (CountBits(diff) > MaximumDifferences)
+ if (CountBits(diff) > maximumDifferences)
{
continue;
}
@@ -559,25 +558,25 @@ public class AnalyzeEpisodesTask : IScheduledTask
rhsTimes.Add(double.MaxValue);
// 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);
+ var lContiguous = TimeRangeHelpers.FindContiguous(lhsTimes.ToArray(), maximumTimeSkip);
if (lContiguous is null || lContiguous.Duration < minimumIntroDuration)
{
return (new TimeRange(), new TimeRange());
}
// Since LHS had a contiguous time range, RHS must have one also.
- var rContiguous = TimeRangeHelpers.FindContiguous(rhsTimes.ToArray(), MaximumDistance)!;
+ var rContiguous = TimeRangeHelpers.FindContiguous(rhsTimes.ToArray(), maximumTimeSkip)!;
// Tweak the end timestamps just a bit to ensure as little content as possible is skipped over.
if (lContiguous.Duration >= 90)
{
- lContiguous.End -= 2 * MaximumDistance;
- rContiguous.End -= 2 * MaximumDistance;
+ lContiguous.End -= 2 * maximumTimeSkip;
+ rContiguous.End -= 2 * maximumTimeSkip;
}
else if (lContiguous.Duration >= 30)
{
- lContiguous.End -= MaximumDistance;
- rContiguous.End -= MaximumDistance;
+ lContiguous.End -= maximumTimeSkip;
+ rContiguous.End -= maximumTimeSkip;
}
return (lContiguous, rContiguous);
@@ -612,9 +611,8 @@ public class AnalyzeEpisodesTask : IScheduledTask
continue;
}
- // Since we only want to adjust the end timestamp of the intro, create a new TimeRange
- // that covers the last few seconds.
- var originalIntroEnd = new TimeRange(originalIntro.IntroEnd - 10, originalIntro.IntroEnd);
+ // Only adjust the end timestamp of the intro
+ var originalIntroEnd = new TimeRange(originalIntro.IntroEnd - 15, originalIntro.IntroEnd);
_logger.LogTrace(
"{Name} original intro: {Start} - {End}",
@@ -636,8 +634,10 @@ public class AnalyzeEpisodesTask : IScheduledTask
// Ignore any silence that:
// * doesn't intersect the ending of the intro, or
- // * is less than half a second long
- if (!originalIntroEnd.Intersects(currentRange) || currentRange.Duration < 0.5)
+ // * is shorter than the user defined minimum duration
+ if (
+ !originalIntroEnd.Intersects(currentRange) ||
+ currentRange.Duration < silenceDetectionMinimumDuration)
{
continue;
}