Add inverted index shift amount
This commit is contained in:
parent
874f77f94c
commit
bbed34b0e7
@ -78,4 +78,10 @@ public class PluginConfiguration : BasePluginConfiguration
|
|||||||
/// Gets or sets the seconds after the intro starts to hide the skip prompt at.
|
/// Gets or sets the seconds after the intro starts to hide the skip prompt at.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int HidePromptAdjustment { get; set; } = 10;
|
public int HidePromptAdjustment { get; set; } = 10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the amount of intro to play (in seconds).
|
||||||
|
/// TODO: rename.
|
||||||
|
/// </summary>
|
||||||
|
public int AmountOfIntroToPlay { get; set; } = 5;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ public class SkipIntroController : ControllerBase
|
|||||||
var config = Plugin.Instance!.Configuration;
|
var config = Plugin.Instance!.Configuration;
|
||||||
intro.ShowSkipPromptAt = Math.Max(0, intro.IntroStart - config.ShowPromptAdjustment);
|
intro.ShowSkipPromptAt = Math.Max(0, intro.IntroStart - config.ShowPromptAdjustment);
|
||||||
intro.HideSkipPromptAt = intro.IntroStart + config.HidePromptAdjustment;
|
intro.HideSkipPromptAt = intro.IntroStart + config.HidePromptAdjustment;
|
||||||
|
intro.IntroEnd -= config.AmountOfIntroToPlay;
|
||||||
|
|
||||||
return intro;
|
return intro;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,11 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const double MaximumDistance = 3.5;
|
private const double MaximumDistance = 3.5;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Amount to shift inverted index offsets by.
|
||||||
|
/// </summary>
|
||||||
|
private const int InvertedIndexShift = 2;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seconds of audio in one fingerprint point. This value is defined by the Chromaprint library and should not be changed.
|
/// Seconds of audio in one fingerprint point. This value is defined by the Chromaprint library and should not be changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -275,18 +280,6 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Theory of operation:
|
|
||||||
* Episodes are analyzed in the same order that Jellyfin displays them in and are
|
|
||||||
* sorted into buckets based off of the intro sequence that the episode contains.
|
|
||||||
*
|
|
||||||
* Jellyfin's episode ordering is used because it is assumed that the introduction
|
|
||||||
* in each season of a show will likely either:
|
|
||||||
* - remain constant throughout the entire season
|
|
||||||
* - remain constant in subranges of the season (e.g. episodes 1 - 5 and 6 - 10 share intros)
|
|
||||||
* If the intros do not follow this pattern, the plugin should still find most
|
|
||||||
* of them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// While there are still episodes in the queue
|
// While there are still episodes in the queue
|
||||||
while (episodes.Count > 0)
|
while (episodes.Count > 0)
|
||||||
{
|
{
|
||||||
@ -304,15 +297,31 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
remainingEpisode.EpisodeId,
|
remainingEpisode.EpisodeId,
|
||||||
fingerprintCache[remainingEpisode.EpisodeId]);
|
fingerprintCache[remainingEpisode.EpisodeId]);
|
||||||
|
|
||||||
// If we found an intro, save it.
|
// If one of the intros isn't valid, ignore this comparison result.
|
||||||
if (currentIntro.Valid)
|
if (!currentIntro.Valid)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only save the discovered intro if it is:
|
||||||
|
// - the first intro discovered for this episode
|
||||||
|
// - longer than the previously discovered intro
|
||||||
|
if (
|
||||||
|
!seasonIntros.TryGetValue(currentIntro.EpisodeId, out var savedCurrentIntro) ||
|
||||||
|
currentIntro.Duration > savedCurrentIntro.Duration)
|
||||||
{
|
{
|
||||||
seasonIntros[currentIntro.EpisodeId] = currentIntro;
|
seasonIntros[currentIntro.EpisodeId] = currentIntro;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!seasonIntros.TryGetValue(remainingIntro.EpisodeId, out var savedRemainingIntro) ||
|
||||||
|
remainingIntro.Duration > savedRemainingIntro.Duration)
|
||||||
|
{
|
||||||
seasonIntros[remainingIntro.EpisodeId] = remainingIntro;
|
seasonIntros[remainingIntro.EpisodeId] = remainingIntro;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If no intro is found at this point, the popped episode is not reinserted into the queue.
|
// If no intro is found at this point, the popped episode is not reinserted into the queue.
|
||||||
}
|
}
|
||||||
@ -435,15 +444,20 @@ public class AnalyzeEpisodesTask : IScheduledTask
|
|||||||
// If an exact match is found, calculate the shift that must be used to align the points.
|
// If an exact match is found, calculate the shift that must be used to align the points.
|
||||||
foreach (var kvp in lhsIndex)
|
foreach (var kvp in lhsIndex)
|
||||||
{
|
{
|
||||||
var point = kvp.Key;
|
var originalPoint = kvp.Key;
|
||||||
|
|
||||||
if (rhsIndex.ContainsKey(point))
|
for (var i = -1 * InvertedIndexShift; i <= InvertedIndexShift; i++)
|
||||||
{
|
{
|
||||||
var lhsFirst = (int)lhsIndex[point];
|
var modifiedPoint = (uint)(originalPoint + i);
|
||||||
var rhsFirst = (int)rhsIndex[point];
|
|
||||||
|
if (rhsIndex.ContainsKey(modifiedPoint))
|
||||||
|
{
|
||||||
|
var lhsFirst = (int)lhsIndex[originalPoint];
|
||||||
|
var rhsFirst = (int)rhsIndex[modifiedPoint];
|
||||||
indexShifts.Add(rhsFirst - lhsFirst);
|
indexShifts.Add(rhsFirst - lhsFirst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Use all discovered shifts to compare the episodes.
|
// Use all discovered shifts to compare the episodes.
|
||||||
foreach (var shift in indexShifts)
|
foreach (var shift in indexShifts)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user