diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12f05d6..c0db679 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - name: Restore dependencies run: dotnet restore diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e84d5b0..cd0bd75 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,7 +22,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - name: Restore dependencies run: dotnet restore diff --git a/ConfusedPolarBear.Plugin.IntroSkipper.Tests/ConfusedPolarBear.Plugin.IntroSkipper.Tests.csproj b/ConfusedPolarBear.Plugin.IntroSkipper.Tests/ConfusedPolarBear.Plugin.IntroSkipper.Tests.csproj index e03bf28..7984d29 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper.Tests/ConfusedPolarBear.Plugin.IntroSkipper.Tests.csproj +++ b/ConfusedPolarBear.Plugin.IntroSkipper.Tests/ConfusedPolarBear.Plugin.IntroSkipper.Tests.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable false diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/AutoSkip.cs b/ConfusedPolarBear.Plugin.IntroSkipper/AutoSkip.cs index d77b922..b703ab5 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/AutoSkip.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/AutoSkip.cs @@ -9,6 +9,7 @@ using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Session; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace ConfusedPolarBear.Plugin.IntroSkipper; @@ -17,7 +18,7 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper; /// Automatically skip past introduction sequences. /// Commands clients to seek to the end of the intro as soon as they start playing it. /// -public class AutoSkip : IServerEntryPoint +public class AutoSkip : IHostedService, IDisposable { private readonly object _sentSeekCommandLock = new(); @@ -44,26 +45,6 @@ public class AutoSkip : IServerEntryPoint _sentSeekCommand = new Dictionary(); } - /// - /// If introduction auto skipping is enabled, set it up. - /// - /// Task. - public Task RunAsync() - { - _logger.LogDebug("Setting up automatic skipping"); - - _userDataManager.UserDataSaved += UserDataManager_UserDataSaved; - Plugin.Instance!.AutoSkipChanged += AutoSkipChanged; - - // Make the timer restart automatically and set enabled to match the configuration value. - _playbackTimer.AutoReset = true; - _playbackTimer.Elapsed += PlaybackTimer_Elapsed; - - AutoSkipChanged(null, EventArgs.Empty); - - return Task.CompletedTask; - } - private void AutoSkipChanged(object? sender, EventArgs e) { var newState = Plugin.Instance!.Configuration.AutoSkip; @@ -222,8 +203,31 @@ public class AutoSkip : IServerEntryPoint return; } - _userDataManager.UserDataSaved -= UserDataManager_UserDataSaved; _playbackTimer.Stop(); _playbackTimer.Dispose(); } + + /// + public Task StartAsync(CancellationToken cancellationToken) + { + _logger.LogDebug("Setting up automatic skipping"); + + _userDataManager.UserDataSaved += UserDataManager_UserDataSaved; + Plugin.Instance!.AutoSkipChanged += AutoSkipChanged; + + // Make the timer restart automatically and set enabled to match the configuration value. + _playbackTimer.AutoReset = true; + _playbackTimer.Elapsed += PlaybackTimer_Elapsed; + + AutoSkipChanged(null, EventArgs.Empty); + + return Task.CompletedTask; + } + + /// + public Task StopAsync(CancellationToken cancellationToken) + { + _userDataManager.UserDataSaved -= UserDataManager_UserDataSaved; + return Task.CompletedTask; + } } diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/inject.js b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/inject.js index ff59976..95bdd65 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/inject.js +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/inject.js @@ -41,7 +41,7 @@ introSkipper.fetchWrapper = async function (...args) { introSkipper.viewShow = function () { const location = window.location.hash; introSkipper.d("Location changed to " + location); - if (location !== "#!/video") { + if (location !== "#/video") { introSkipper.d("Ignoring location change"); return; } diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ConfusedPolarBear.Plugin.IntroSkipper.csproj b/ConfusedPolarBear.Plugin.IntroSkipper/ConfusedPolarBear.Plugin.IntroSkipper.csproj index bc5fb38..8fbdaa4 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/ConfusedPolarBear.Plugin.IntroSkipper.csproj +++ b/ConfusedPolarBear.Plugin.IntroSkipper/ConfusedPolarBear.Plugin.IntroSkipper.csproj @@ -1,6 +1,6 @@ - net6.0 + net8.0 ConfusedPolarBear.Plugin.IntroSkipper 0.1.16.3 0.1.16.3 @@ -11,8 +11,8 @@ ../jellyfin.ruleset - - + + diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs index 4ef12b3..91a95e6 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Entrypoint.cs @@ -1,8 +1,8 @@ using System; -using System.IO; +using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace ConfusedPolarBear.Plugin.IntroSkipper; @@ -10,7 +10,7 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper; /// /// Server entrypoint. /// -public class Entrypoint : IServerEntryPoint +public class Entrypoint : IHostedService { private readonly IUserManager _userManager; private readonly IUserViewManager _userViewManager; @@ -40,39 +40,12 @@ public class Entrypoint : IServerEntryPoint _loggerFactory = loggerFactory; } - /// - /// Registers event handler. - /// - /// Task. - public Task RunAsync() - { - FFmpegWrapper.Logger = _logger; - - // TODO: when a new item is added to the server, immediately analyze the season it belongs to - // instead of waiting for the next task interval. The task start should be debounced by a few seconds. - - try - { - // Enqueue all episodes at startup to ensure any FFmpeg errors appear as early as possible - _logger.LogInformation("Running startup enqueue"); - var queueManager = new QueueManager(_loggerFactory.CreateLogger(), _libraryManager); - queueManager.GetMediaItems(); - } - catch (Exception ex) - { - _logger.LogError("Unable to run startup enqueue: {Exception}", ex); - } - - return Task.CompletedTask; - } - /// /// Dispose. /// public void Dispose() { Dispose(true); - GC.SuppressFinalize(this); } /// @@ -86,4 +59,33 @@ public class Entrypoint : IServerEntryPoint return; } } + + /// + public Task StartAsync(CancellationToken cancellationToken) + { + FFmpegWrapper.Logger = _logger; + + // TODO: when a new item is added to the server, immediately analyze the season it belongs to + // instead of waiting for the next task interval. The task start should be debounced by a few seconds. + + try + { + // Enqueue all episodes at startup to ensure any FFmpeg errors appear as early as possible + _logger.LogInformation("Running startup enqueue"); + var queueManager = new QueueManager(_loggerFactory.CreateLogger(), _libraryManager); + queueManager?.GetMediaItems(); + } + catch (Exception ex) + { + _logger.LogError("Unable to run startup enqueue: {Exception}", ex); + } + + return Task.CompletedTask; + } + + /// + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } } diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/PluginServiceRegistrator.cs b/ConfusedPolarBear.Plugin.IntroSkipper/PluginServiceRegistrator.cs new file mode 100644 index 0000000..6bc818c --- /dev/null +++ b/ConfusedPolarBear.Plugin.IntroSkipper/PluginServiceRegistrator.cs @@ -0,0 +1,18 @@ +using MediaBrowser.Controller; +using MediaBrowser.Controller.Plugins; +using Microsoft.Extensions.DependencyInjection; + +namespace ConfusedPolarBear.Plugin.IntroSkipper +{ + /// + /// Register Intro Skipper services. + /// + public class PluginServiceRegistrator : IPluginServiceRegistrator + { + /// + public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost) + { + serviceCollection.AddHostedService(); + } + } +} diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs b/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs index c27ff62..0129dd3 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/QueueManager.cs @@ -129,13 +129,13 @@ public class QueueManager { // Order by series name, season, and then episode number so that status updates are logged in order ParentId = id, - OrderBy = new[] + OrderBy = new List<(ItemSortBy, SortOrder)> { - ("SeriesSortName", SortOrder.Ascending), - ("ParentIndexNumber", SortOrder.Ascending), - ("IndexNumber", SortOrder.Ascending), + new(ItemSortBy.SeriesSortName, SortOrder.Ascending), + new(ItemSortBy.ParentIndexNumber, SortOrder.Ascending), + new(ItemSortBy.IndexNumber, SortOrder.Ascending), }, - IncludeItemTypes = new BaseItemKind[] { BaseItemKind.Episode }, + IncludeItemTypes = [BaseItemKind.Episode], Recursive = true, IsVirtualItem = false };