AutoSkip: allow to adjust the intro/credit playback duration (#238)

Co-authored-by: rlauu <46294892+rlauu@users.noreply.github.com>
Co-authored-by: rlauuzo <46294892+rlauuzo@users.noreply.github.com>
Co-authored-by: CasuallyFilthy <adamsdeloach@yahoo.com>
This commit is contained in:
Kilian von Pflugk 2024-08-02 13:41:03 +00:00 committed by GitHub
parent 50ea8955d6
commit e8fcdf53de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 18 deletions

View File

@ -133,15 +133,16 @@ public class AutoSkip : IHostedService, IDisposable
}
// Seek is unreliable if called at the very start of an episode.
var adjustedStart = Math.Max(5, intro.IntroStart);
var adjustedStart = Math.Max(5, intro.IntroStart + Plugin.Instance.Configuration.SecondsOfIntroStartToPlay);
var adjustedEnd = intro.IntroEnd - Plugin.Instance.Configuration.RemainingSecondsOfIntro;
_logger.LogTrace(
"Playback position is {Position}, intro runs from {Start} to {End}",
position,
adjustedStart,
intro.IntroEnd);
adjustedEnd);
if (position < adjustedStart || position > intro.IntroEnd)
if (position < adjustedStart || position > adjustedEnd)
{
continue;
}
@ -164,8 +165,6 @@ public class AutoSkip : IHostedService, IDisposable
_logger.LogDebug("Sending seek command to {Session}", deviceId);
var introEnd = (long)intro.IntroEnd - Plugin.Instance.Configuration.SecondsOfIntroToPlay;
_sessionManager.SendPlaystateCommand(
session.Id,
session.Id,
@ -173,7 +172,7 @@ public class AutoSkip : IHostedService, IDisposable
{
Command = PlaystateCommand.Seek,
ControllingUserId = session.UserId.ToString(),
SeekPositionTicks = introEnd * TimeSpan.TicksPerSecond,
SeekPositionTicks = (long)adjustedEnd * TimeSpan.TicksPerSecond,
},
CancellationToken.None);

View File

@ -132,16 +132,17 @@ public class AutoSkipCredits : IHostedService, IDisposable
continue;
}
// Seek is unreliable if called at the very start of an episode.
var adjustedStart = Math.Max(5, credit.IntroStart);
// Seek is unreliable if called at the very end of an episode.
var adjustedStart = credit.IntroStart + Plugin.Instance.Configuration.SecondsOfCreditsStartToPlay;
var adjustedEnd = credit.IntroEnd - Plugin.Instance.Configuration.RemainingSecondsOfIntro;
_logger.LogTrace(
"Playback position is {Position}, credits run from {Start} to {End}",
position,
adjustedStart,
credit.IntroEnd);
adjustedEnd);
if (position < adjustedStart || position > credit.IntroEnd)
if (position < adjustedStart || position > adjustedEnd)
{
continue;
}
@ -164,8 +165,6 @@ public class AutoSkipCredits : IHostedService, IDisposable
_logger.LogDebug("Sending seek command to {Session}", deviceId);
var creditEnd = (long)credit.IntroEnd;
_sessionManager.SendPlaystateCommand(
session.Id,
session.Id,
@ -173,7 +172,7 @@ public class AutoSkipCredits : IHostedService, IDisposable
{
Command = PlaystateCommand.Seek,
ControllingUserId = session.UserId.ToString(),
SeekPositionTicks = creditEnd * TimeSpan.TicksPerSecond,
SeekPositionTicks = (long)adjustedEnd * TimeSpan.TicksPerSecond,
},
CancellationToken.None);

View File

@ -156,7 +156,17 @@ public class PluginConfiguration : BasePluginConfiguration
/// <summary>
/// Gets or sets the amount of intro to play (in seconds).
/// </summary>
public int SecondsOfIntroToPlay { get; set; } = 2;
public int RemainingSecondsOfIntro { get; set; } = 2;
/// <summary>
/// Gets or sets the amount of intro at start to play (in seconds).
/// </summary>
public int SecondsOfIntroStartToPlay { get; set; } = 0;
/// <summary>
/// Gets or sets the amount of credit at start to play (in seconds).
/// </summary>
public int SecondsOfCreditsStartToPlay { get; set; } = 0;
// ===== Internal algorithm settings =====

View File

@ -365,6 +365,17 @@
<br />
</div>
<div id="divSecondsOfIntroStartToPlay" class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="SecondsOfIntroStartToPlay">
Intro playback duration (in seconds)
</label>
<input id="SecondsOfIntroStartToPlay" type="number" is="emby-input" min="0" />
<div class="fieldDescription">
Seconds of introduction start that should be played. Defaults to 0.
</div>
<br />
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="AutoSkipCredits" type="checkbox" is="emby-checkbox" />
@ -378,6 +389,17 @@
</div>
</div>
<div id="divSecondsOfCreditsStartToPlay" class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="SecondsOfCreditsStartToPlay">
Credit playback duration (in seconds)
</label>
<input id="SecondsOfCreditsStartToPlay" type="number" is="emby-input" min="0" />
<div class="fieldDescription">
Seconds of credits start that should be played. Defaults to 0.
</div>
<br />
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="SkipButtonVisible" type="checkbox" is="emby-checkbox" />
@ -427,10 +449,10 @@
<br />
<div class="inputContainer">
<label class="inputLabel inputLabelUnfocused" for="SecondsOfIntroToPlay">
<label class="inputLabel inputLabelUnfocused" for="RemainingSecondsOfIntro">
Intro playback duration (in seconds)
</label>
<input id="SecondsOfIntroToPlay" type="number" is="emby-input" min="0" />
<input id="RemainingSecondsOfIntro" type="number" is="emby-input" min="0" />
<div class="fieldDescription">
Seconds of introduction ending that should be played. Defaults to 2.
</div>
@ -681,7 +703,9 @@
// playback
"ShowPromptAdjustment",
"HidePromptAdjustment",
"SecondsOfIntroToPlay",
"RemainingSecondsOfIntro",
"SecondsOfIntroStartToPlay",
"SecondsOfCreditsStartToPlay",
// internals
"SilenceDetectionMaximumNoise",
"SilenceDetectionMinimumDuration",
@ -725,6 +749,8 @@
var autoSkip = document.querySelector("input#AutoSkip");
var skipFirstEpisode = document.querySelector("div#divSkipFirstEpisode");
var secondsOfIntroStartToPlay = document.querySelector("div#divSecondsOfIntroStartToPlay");
var secondsOfCreditsStartToPlay = document.querySelector("div#divSecondsOfCreditsStartToPlay");
var autoSkipNotificationText = document.querySelector("div#divAutoSkipNotificationText");
var autoSkipCredits = document.querySelector("input#AutoSkipCredits");
var autoSkipCreditsNotificationText = document.querySelector("div#divAutoSkipCreditsNotificationText");
@ -733,9 +759,11 @@
if (autoSkip.checked) {
skipFirstEpisode.style.display = 'unset';
autoSkipNotificationText.style.display = 'unset';
secondsOfIntroStartToPlay.style.display = 'unset';
} else {
skipFirstEpisode.style.display = 'none';
autoSkipNotificationText.style.display = 'none';
secondsOfIntroStartToPlay.style.display = 'none';
}
}
@ -744,8 +772,10 @@
async function autoSkipCreditsChanged() {
if (autoSkipCredits.checked) {
autoSkipCreditsNotificationText.style.display = 'unset';
secondsOfCreditsStartToPlay.style.display = 'unset';
} else {
autoSkipCreditsNotificationText.style.display = 'none';
secondsOfCreditsStartToPlay.style.display = 'none';
}
}

View File

@ -156,7 +156,7 @@ public class SkipIntroController : ControllerBase
var segment = new Intro(timestamp);
var config = Plugin.Instance.Configuration;
segment.IntroEnd -= config.SecondsOfIntroToPlay;
segment.IntroEnd -= config.RemainingSecondsOfIntro;
if (config.PersistSkipButton)
{
segment.ShowSkipPromptAt = segment.IntroStart;