From 0b27b6e297b7cf4e00a7a55c827143fde0351375 Mon Sep 17 00:00:00 2001 From: Kilian von Pflugk Date: Mon, 21 Oct 2024 09:19:51 +0200 Subject: [PATCH] remove EDL function and point to endrl's EDL plugin (#352) Co-authored-by: rlauu <46294892+rlauu@users.noreply.github.com> --- IntroSkipper.Tests/TestEdl.cs | 47 ------- IntroSkipper.Tests/e2e_tests/README.md | 1 - .../Configuration/PluginConfiguration.cs | 20 +-- IntroSkipper/Configuration/configPage.html | 33 +---- IntroSkipper/Data/EdlAction.cs | 32 ----- IntroSkipper/Data/Segment.cs | 18 --- IntroSkipper/Manager/EdlManager.cs | 117 ------------------ .../ScheduledTasks/BaseItemAnalyzerTask.cs | 20 +-- docs/edl.md | 16 --- 9 files changed, 7 insertions(+), 297 deletions(-) delete mode 100644 IntroSkipper.Tests/TestEdl.cs delete mode 100644 IntroSkipper/Data/EdlAction.cs delete mode 100644 IntroSkipper/Manager/EdlManager.cs delete mode 100644 docs/edl.md diff --git a/IntroSkipper.Tests/TestEdl.cs b/IntroSkipper.Tests/TestEdl.cs deleted file mode 100644 index c47b9ba..0000000 --- a/IntroSkipper.Tests/TestEdl.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using IntroSkipper.Data; -using IntroSkipper.Manager; -using Xunit; - -namespace IntroSkipper.Tests; - -public class TestEdl -{ - // Test data is from https://kodi.wiki/view/Edit_decision_list#MPlayer_EDL - [Theory] - [InlineData(5.3, 7.1, EdlAction.Cut, "5.3 7.1 0")] - [InlineData(15, 16.7, EdlAction.Mute, "15 16.7 1")] - [InlineData(420, 822, EdlAction.CommercialBreak, "420 822 3")] - [InlineData(1, 255.3, EdlAction.SceneMarker, "1 255.3 2")] - [InlineData(1.123456789, 5.654647987, EdlAction.CommercialBreak, "1.12 5.65 3")] - public void TestEdlSerialization(double start, double end, EdlAction action, string expected) - { - var intro = MakeIntro(start, end); - var actual = intro.ToEdl(action); - - Assert.Equal(expected, actual); - } - - [Fact] - public void TestEdlInvalidSerialization() - { - Assert.Throws(() => - { - var intro = MakeIntro(0, 5); - intro.ToEdl(EdlAction.None); - }); - } - - [Theory] - [InlineData("Death Note - S01E12 - Love.mkv", "Death Note - S01E12 - Love.edl")] - [InlineData("/full/path/to/file.rm", "/full/path/to/file.edl")] - public void TestEdlPath(string mediaPath, string edlPath) - { - Assert.Equal(edlPath, EdlManager.GetEdlPath(mediaPath)); - } - - private static Segment MakeIntro(double start, double end) - { - return new Segment(Guid.Empty, new TimeRange(start, end)); - } -} diff --git a/IntroSkipper.Tests/e2e_tests/README.md b/IntroSkipper.Tests/e2e_tests/README.md index d0361be..ec41fb7 100644 --- a/IntroSkipper.Tests/e2e_tests/README.md +++ b/IntroSkipper.Tests/e2e_tests/README.md @@ -39,7 +39,6 @@ Selenium is used to verify that the plugin's web interface works as expected. It * Changing settings (will be added in the future) * Maximum degree of parallelism * Selecting libraries for analysis - * EDL settings * Introduction requirements * Auto skip * Show/hide skip prompt diff --git a/IntroSkipper/Configuration/PluginConfiguration.cs b/IntroSkipper/Configuration/PluginConfiguration.cs index ba81da4..0107fe8 100644 --- a/IntroSkipper/Configuration/PluginConfiguration.cs +++ b/IntroSkipper/Configuration/PluginConfiguration.cs @@ -76,26 +76,12 @@ public class PluginConfiguration : BasePluginConfiguration public bool UpdateMediaSegments { get; set; } = true; /// - /// Gets or sets a value indicating whether to regenerate all EDL files during the next scan. - /// By default, EDL files are only written for a season if the season had at least one newly analyzed episode. - /// If this is set, all EDL files will be regenerated and overwrite any existing EDL file. + /// Gets or sets a value indicating whether to regenerate all Media Segments during the next scan. + /// By default, Media Segments are only written for a season if the season had at least one newly analyzed episode. + /// If this is set, all Media Segments will be regenerated and overwrite any existing Media Segemnts. /// public bool RegenerateMediaSegments { get; set; } = true; - // ===== EDL handling ===== - - /// - /// Gets or sets a value indicating the action to write to created EDL files. - /// - public EdlAction EdlAction { get; set; } = EdlAction.None; - - /// - /// Gets or sets a value indicating whether to regenerate all EDL files during the next scan. - /// By default, EDL files are only written for a season if the season had at least one newly analyzed episode. - /// If this is set, all EDL files will be regenerated and overwrite any existing EDL file. - /// - public bool RegenerateEdlFiles { get; set; } - // ===== Custom analysis settings ===== /// diff --git a/IntroSkipper/Configuration/configPage.html b/IntroSkipper/Configuration/configPage.html index 1424402..d215626 100644 --- a/IntroSkipper/Configuration/configPage.html +++ b/IntroSkipper/Configuration/configPage.html @@ -186,35 +186,7 @@
- - - -
- If set to a value other than None, specifies which action to write to - MPlayer compatible EDL files - alongside your episode files.
- - If this value is changed after EDL files are generated, you must check the "Regenerate EDL files" checkbox below. -
-
- -
- - -
If checked, the plugin will overwrite all EDL files associated with your episodes with the currently discovered introduction/credit timestamps and EDL action.
+ The EDL file generation has been removed. Please use endrl's EDL plugin.
@@ -680,7 +652,6 @@ "MinimumCreditsDuration", "MaximumCreditsDuration", "MaximumMovieCreditsDuration", - "EdlAction", "ProcessPriority", "ProcessThreads", // playback @@ -699,7 +670,7 @@ "AutoSkipCreditsNotificationText", ]; - var booleanConfigurationFields = ["AutoDetectIntros", "AutoDetectCredits", "AnalyzeMovies", "AnalyzeSeasonZero", "SelectAllLibraries", "UpdateMediaSegments", "RegenerateMediaSegments", "RegenerateEdlFiles", "CacheFingerprints", "AutoSkip", "AutoSkipCredits", "SkipFirstEpisode", "PersistSkipButton", "SkipButtonVisible"]; + var booleanConfigurationFields = ["AutoDetectIntros", "AutoDetectCredits", "AnalyzeMovies", "AnalyzeSeasonZero", "SelectAllLibraries", "UpdateMediaSegments", "RegenerateMediaSegments", "CacheFingerprints", "AutoSkip", "AutoSkipCredits", "SkipFirstEpisode", "PersistSkipButton", "SkipButtonVisible"]; // visualizer elements var ignorelistSection = document.querySelector("div#ignorelistSection"); diff --git a/IntroSkipper/Data/EdlAction.cs b/IntroSkipper/Data/EdlAction.cs deleted file mode 100644 index a6393ac..0000000 --- a/IntroSkipper/Data/EdlAction.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace IntroSkipper.Data; - -/// -/// Taken from https://kodi.wiki/view/Edit_decision_list#MPlayer_EDL. -/// -public enum EdlAction -{ - /// - /// Do not create EDL files. - /// - None = -1, - - /// - /// Completely remove the segment from playback as if it was never in the original video. - /// - Cut = 0, - - /// - /// Mute audio, continue playback. - /// - Mute = 1, - - /// - /// Inserts a new scene marker. - /// - SceneMarker = 2, - - /// - /// Automatically skip once during playback. - /// - CommercialBreak = 3 -} diff --git a/IntroSkipper/Data/Segment.cs b/IntroSkipper/Data/Segment.cs index 7ec3606..e97eedf 100644 --- a/IntroSkipper/Data/Segment.cs +++ b/IntroSkipper/Data/Segment.cs @@ -93,22 +93,4 @@ public class Segment ///
[JsonIgnore] public double Duration => End - Start; - - /// - /// Convert this Intro object to a Kodi compatible EDL entry. - /// - /// User specified configuration EDL action. - /// String. - public string ToEdl(EdlAction action) - { - if (action == EdlAction.None) - { - throw new ArgumentException("Cannot serialize an EdlAction of None"); - } - - var start = Math.Round(Start, 2); - var end = Math.Round(End, 2); - - return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", start, end, (int)action); - } } diff --git a/IntroSkipper/Manager/EdlManager.cs b/IntroSkipper/Manager/EdlManager.cs deleted file mode 100644 index 9160ca0..0000000 --- a/IntroSkipper/Manager/EdlManager.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using IntroSkipper.Data; -using Microsoft.Extensions.Logging; - -namespace IntroSkipper.Manager -{ - /// - /// Update EDL files associated with a list of episodes. - /// - public static class EdlManager - { - private static ILogger? _logger; - - /// - /// Initialize EDLManager with a logger. - /// - /// ILogger. - public static void Initialize(ILogger logger) - { - _logger = logger; - } - - /// - /// Logs the configuration that will be used during EDL file creation. - /// - public static void LogConfiguration() - { - if (_logger is null) - { - throw new InvalidOperationException("Logger must not be null"); - } - - var config = Plugin.Instance!.Configuration; - - if (config.EdlAction == EdlAction.None) - { - _logger.LogDebug("EDL action: None - taking no further action"); - return; - } - - _logger.LogDebug("EDL action: {Action}", config.EdlAction); - _logger.LogDebug("Regenerate EDL files: {Regenerate}", config.RegenerateEdlFiles); - } - - /// - /// If the EDL action is set to a value other than None, update EDL files for the provided episodes. - /// - /// Episodes to update EDL files for. - public static void UpdateEDLFiles(IReadOnlyList episodes) - { - var regenerate = Plugin.Instance!.Configuration.RegenerateEdlFiles; - var action = Plugin.Instance.Configuration.EdlAction; - if (action == EdlAction.None) - { - _logger?.LogDebug("EDL action is set to none, not updating EDL files"); - return; - } - - _logger?.LogDebug("Updating EDL files with action {Action}", action); - - foreach (var episode in episodes) - { - var id = episode.EpisodeId; - - bool hasIntro = Plugin.Instance!.Intros.TryGetValue(id, out var intro) && intro.Valid; - bool hasCredit = Plugin.Instance!.Credits.TryGetValue(id, out var credit) && credit.Valid; - - if (!hasIntro && !hasCredit) - { - _logger?.LogDebug("Episode {Id} has neither a valid intro nor credit, skipping", id); - continue; - } - - var edlPath = GetEdlPath(Plugin.Instance.GetItemPath(id)); - - _logger?.LogTrace("Episode {Id} has EDL path {Path}", id, edlPath); - - if (!regenerate && File.Exists(edlPath)) - { - _logger?.LogTrace("Refusing to overwrite existing EDL file {Path}", edlPath); - continue; - } - - var edlContent = string.Empty; - - if (hasIntro) - { - edlContent += intro?.ToEdl(action); - } - - if (hasCredit) - { - if (edlContent.Length > 0) - { - edlContent += Environment.NewLine; - } - - edlContent += credit?.ToEdl(action); - } - - File.WriteAllText(edlPath, edlContent); - } - } - - /// - /// Given the path to an episode, return the path to the associated EDL file. - /// - /// Full path to episode. - /// Full path to EDL file. - public static string GetEdlPath(string mediaPath) - { - return Path.ChangeExtension(mediaPath, "edl"); - } - } -} diff --git a/IntroSkipper/ScheduledTasks/BaseItemAnalyzerTask.cs b/IntroSkipper/ScheduledTasks/BaseItemAnalyzerTask.cs index 075bbfb..0451f7b 100644 --- a/IntroSkipper/ScheduledTasks/BaseItemAnalyzerTask.cs +++ b/IntroSkipper/ScheduledTasks/BaseItemAnalyzerTask.cs @@ -43,11 +43,6 @@ public class BaseItemAnalyzerTask _loggerFactory = loggerFactory; _libraryManager = libraryManager; _mediaSegmentUpdateManager = mediaSegmentUpdateManager; - - if (Plugin.Instance!.Configuration.EdlAction != EdlAction.None) - { - EdlManager.Initialize(_logger); - } } /// @@ -89,11 +84,6 @@ public class BaseItemAnalyzerTask "No libraries selected for analysis. Please visit the plugin settings to configure."); } - if (Plugin.Instance!.Configuration.EdlAction != EdlAction.None) - { - EdlManager.LogConfiguration(); - } - var totalProcessed = 0; var options = new ParallelOptions { @@ -169,18 +159,12 @@ public class BaseItemAnalyzerTask { await _mediaSegmentUpdateManager.UpdateMediaSegmentsAsync(episodes, ct).ConfigureAwait(false); } - - if (Plugin.Instance.Configuration.RegenerateEdlFiles || (updateManagers && Plugin.Instance.Configuration.EdlAction != EdlAction.None)) - { - EdlManager.UpdateEDLFiles(episodes); - } }).ConfigureAwait(false); - if (Plugin.Instance.Configuration.RegenerateMediaSegments || Plugin.Instance.Configuration.RegenerateEdlFiles) + if (Plugin.Instance.Configuration.RegenerateMediaSegments) { - _logger.LogInformation("Turning Mediasegment/EDL file regeneration flag off"); + _logger.LogInformation("Turning Mediasegment"); Plugin.Instance.Configuration.RegenerateMediaSegments = false; - Plugin.Instance.Configuration.RegenerateEdlFiles = false; Plugin.Instance.SaveConfiguration(); } } diff --git a/docs/edl.md b/docs/edl.md deleted file mode 100644 index 81f5d0c..0000000 --- a/docs/edl.md +++ /dev/null @@ -1,16 +0,0 @@ -# EDL support - -The timestamps of discovered introductions can be written to [EDL](https://kodi.wiki/view/Edit_decision_list) files alongside your media files. EDL files are saved when: -* Scanning an episode for the first time, or -* If requested with the regenerate checkbox - -## Configuration - -Jellyfin must have read/write access to your TV show libraries in order to make use of this feature. - -## Usage - -To have the plugin create EDL files: -1. Change the EDL action from the default of None to any of the other supported EDL actions -2. Check the "Regenerate EDL files during next analysis" checkbox - 1. If this option is not selected, only seasons with a newly analyzed episode will have EDL files created.