Allow customizing minimum intro duration

Closes #51
This commit is contained in:
ConfusedPolarBear 2022-07-03 01:59:16 -05:00
parent 055a851e27
commit a1a10874d3
4 changed files with 42 additions and 17 deletions

View File

@ -36,6 +36,11 @@ public class PluginConfiguration : BasePluginConfiguration
/// </summary> /// </summary>
public int AnalysisLengthLimit { get; set; } = 10; public int AnalysisLengthLimit { get; set; } = 10;
/// <summary>
/// Gets or sets the minimum length of similar audio that will be considered an introduction.
/// </summary>
public int MinimumIntroDuration { get; set; } = 15;
// ===== Playback settings ===== // ===== Playback settings =====
/// <summary> /// <summary>

View File

@ -64,17 +64,32 @@
</div> </div>
</div> </div>
<p> <div class="inputContainer">
The amount of each episode's audio that will be analyzed is determined by these two <label class="inputLabel inputLabelUnfocused" for="MinimumDuration">
settings. The minimum of (episode duration * percent, maximum runtime) is the amount of Minimum introduction duration (in seconds)
audio that will be analyzed. <br /> </label>
<input id="MinimumDuration" type="number" is="emby-input" min="1" />
<div class="fieldDescription">
Similar sounding audio which is shorter than this duration will not be considered an
introduction.
</div>
</div>
If these settings are changed after analyzing your media, the cached fingerprints and <p>
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. <br />
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. will have to be deleted.
</p> </p>
<strong>Increasing these settings will cause episode analysis to take much longer.</strong> <strong>
Increasing either of these settings will cause episode analysis to take much longer.
</strong>
</details> </details>
</fieldset> </fieldset>
@ -480,6 +495,7 @@
document.querySelector('#AnalysisPercent').value = config.AnalysisPercent; document.querySelector('#AnalysisPercent').value = config.AnalysisPercent;
document.querySelector('#AnalysisLengthLimit').value = config.AnalysisLengthLimit; document.querySelector('#AnalysisLengthLimit').value = config.AnalysisLengthLimit;
document.querySelector('#MinimumDuration').value = config.MinimumIntroDuration;
document.querySelector('#CacheFingerprints').checked = config.CacheFingerprints; document.querySelector('#CacheFingerprints').checked = config.CacheFingerprints;
document.querySelector('#ShowPromptAdjustment').value = config.ShowPromptAdjustment; document.querySelector('#ShowPromptAdjustment').value = config.ShowPromptAdjustment;
@ -498,6 +514,7 @@
config.AnalysisPercent = document.querySelector('#AnalysisPercent').value; config.AnalysisPercent = document.querySelector('#AnalysisPercent').value;
config.AnalysisLengthLimit = document.querySelector('#AnalysisLengthLimit').value; config.AnalysisLengthLimit = document.querySelector('#AnalysisLengthLimit').value;
config.MinimumIntroDuration = document.querySelector('#MinimumDuration').value;
config.CacheFingerprints = document.querySelector('#CacheFingerprints').checked; config.CacheFingerprints = document.querySelector('#CacheFingerprints').checked;
config.ShowPromptAdjustment = document.querySelector("#ShowPromptAdjustment").value; config.ShowPromptAdjustment = document.querySelector("#ShowPromptAdjustment").value;

View File

@ -48,12 +48,13 @@ public class QueueManager
var config = Plugin.Instance!.Configuration; var config = Plugin.Instance!.Configuration;
analysisPercent = Convert.ToDouble(config.AnalysisPercent) / 100; 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( _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.AnalysisPercent,
config.AnalysisLengthLimit); config.AnalysisLengthLimit,
config.MinimumIntroDuration);
} }
// For all TV show libraries, enqueue all contained items. // For all TV show libraries, enqueue all contained items.

View File

@ -15,11 +15,6 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper;
/// </summary> /// </summary>
public class FingerprinterTask : IScheduledTask public class FingerprinterTask : IScheduledTask
{ {
/// <summary>
/// Minimum time (in seconds) for a contiguous time range to be considered an introduction.
/// </summary>
private const int MinimumIntroDuration = 15;
/// <summary> /// <summary>
/// Maximum number of bits (out of 32 total) that can be different between segments before they are considered dissimilar. /// 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). /// 6 bits means the audio must be at least 81% similar (1 - 6 / 32).
@ -68,6 +63,11 @@ public class FingerprinterTask : IScheduledTask
/// </summary> /// </summary>
private Dictionary<Guid, ReadOnlyCollection<uint>> _fingerprintCache; private Dictionary<Guid, ReadOnlyCollection<uint>> _fingerprintCache;
/// <summary>
/// Minimum duration of similar audio that will be considered an introduction.
/// </summary>
private static int minimumIntroDuration = 15;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="FingerprinterTask"/> class. /// Initializes a new instance of the <see cref="FingerprinterTask"/> class.
/// </summary> /// </summary>
@ -143,6 +143,8 @@ public class FingerprinterTask : IScheduledTask
MaxDegreeOfParallelism = Plugin.Instance!.Configuration.MaxParallelism MaxDegreeOfParallelism = Plugin.Instance!.Configuration.MaxParallelism
}; };
minimumIntroDuration = Plugin.Instance!.Configuration.MinimumIntroDuration;
Parallel.ForEach(queue, options, (season) => Parallel.ForEach(queue, options, (season) =>
{ {
var first = season.Value[0]; 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. // 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(), MaximumDistance);
if (lContiguous is null || lContiguous.Duration < MinimumIntroDuration) if (lContiguous is null || lContiguous.Duration < minimumIntroDuration)
{ {
return (new TimeRange(), new TimeRange()); return (new TimeRange(), new TimeRange());
} }
@ -599,7 +601,7 @@ public class FingerprinterTask : IScheduledTask
var id = episode.EpisodeId; var id = episode.EpisodeId;
var duration = GetIntroDuration(id); var duration = GetIntroDuration(id);
if (duration < MinimumIntroDuration) if (duration < minimumIntroDuration)
{ {
continue; continue;
} }