diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs
index c3c414c..e42540b 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Configuration/PluginConfiguration.cs
@@ -1,23 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
using MediaBrowser.Model.Plugins;
namespace ConfusedPolarBear.Plugin.IntroSkipper.Configuration;
-///
-/// The configuration options.
-///
-public enum SomeOptions
-{
- ///
- /// Option one.
- ///
- OneOption,
-
- ///
- /// Second option.
- ///
- AnotherOption
-}
-
///
/// Plugin configuration.
///
@@ -28,30 +16,38 @@ public class PluginConfiguration : BasePluginConfiguration
///
public PluginConfiguration()
{
- // set default options here
- Options = SomeOptions.AnotherOption;
- TrueFalseSetting = true;
- AnInteger = 2;
- AString = "string";
+ AnalysisResults = new Collection();
}
///
- /// Gets or sets a value indicating whether some true or false setting is enabled..
+ /// Save timestamps to disk.
///
- public bool TrueFalseSetting { get; set; }
+ public void SaveTimestamps()
+ {
+ AnalysisResults.Clear();
+
+ foreach (var intro in Plugin.Instance!.Intros)
+ {
+ AnalysisResults.Add(intro.Value);
+ }
+
+ Plugin.Instance!.SaveConfiguration();
+ }
///
- /// Gets or sets an integer setting.
+ /// Restore previous analysis results from disk.
///
- public int AnInteger { get; set; }
+ public void RestoreTimestamps()
+ {
+ // Since dictionaries can't be easily serialized, analysis results are stored on disk as a list.
+ foreach (var intro in AnalysisResults)
+ {
+ Plugin.Instance!.Intros[intro.EpisodeId] = intro;
+ }
+ }
///
- /// Gets or sets a string setting.
+ /// Previous analysis results.
///
- public string AString { get; set; }
-
- ///
- /// Gets or sets an enum option.
- ///
- public SomeOptions Options { get; set; }
+ public Collection AnalysisResults { get; private set; }
}
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs
index 43f9f1c..e917e11 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs
@@ -1,17 +1,7 @@
using System;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.Linq;
using System.Net.Mime;
-using System.Text.Json;
-using Jellyfin.Data.Entities;
-using Jellyfin.Extensions.Json;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Logging;
namespace ConfusedPolarBear.Plugin.IntroSkipper.Controllers;
@@ -33,18 +23,18 @@ public class SkipIntroController : ControllerBase
///
/// Returns the timestamps of the introduction in a television episode.
///
- /// ID of the episode. Required.
+ /// ID of the episode. Required.
/// Episode contains an intro.
/// Failed to find an intro in the provided episode.
[HttpGet("Episode/{id}/IntroTimestamps")]
- public ActionResult GetIntroTimestamps([FromRoute] Guid episodeId)
+ public ActionResult GetIntroTimestamps([FromRoute] Guid id)
{
- if (!Plugin.Instance!.Intros.ContainsKey(episodeId))
+ if (!Plugin.Instance!.Intros.ContainsKey(id))
{
return NotFound();
}
- var intro = Plugin.Instance!.Intros[episodeId];
+ var intro = Plugin.Instance!.Intros[id];
// Check that the episode was analyzed successfully.
if (!intro.Valid)
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Data/Intro.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Data/Intro.cs
index d6302fd..d3f8bbd 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Data/Intro.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Data/Intro.cs
@@ -6,8 +6,12 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper;
/// Result of fingerprinting and analyzing two episodes in a season.
/// All times are measured in seconds relative to the beginning of the media file.
///
-[Serializable]
public class Intro {
+ ///
+ /// Episode ID.
+ ///
+ public Guid EpisodeId { get; set; }
+
///
/// If this introduction is valid or not. Invalid results should not be returned through the API.
///
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
index b015dea..94e4b08 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/Plugin.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Globalization;
using ConfusedPolarBear.Plugin.IntroSkipper.Configuration;
@@ -11,10 +10,25 @@ using MediaBrowser.Model.Serialization;
namespace ConfusedPolarBear.Plugin.IntroSkipper;
///
-/// The main plugin.
+/// Intro skipper plugin. Uses audio analysis to find common sequences of audio shared between episodes.
///
public class Plugin : BasePlugin, IHasWebPages
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Instance of the interface.
+ /// Instance of the interface.
+ public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
+ : base(applicationPaths, xmlSerializer)
+ {
+ Intros = new Dictionary();
+ AnalysisQueue = new Dictionary>();
+ Instance = this;
+
+ Configuration.RestoreTimestamps();
+ }
+
///
/// Results of fingerprinting all episodes.
///
@@ -30,29 +44,13 @@ public class Plugin : BasePlugin, IHasWebPages
///
public int TotalQueued { get; set; }
- ///
- /// Initializes a new instance of the class.
- ///
- /// Instance of the interface.
- /// Instance of the interface.
- public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
- : base(applicationPaths, xmlSerializer)
- {
- Intros = new Dictionary();
- AnalysisQueue = new Dictionary>();
-
- Instance = this;
- }
-
///
public override string Name => "Intro Skipper";
///
public override Guid Id => Guid.Parse("c83d86bb-a1e0-4c35-a113-e2101cf4ee6b");
- ///
- /// Gets the current plugin instance.
- ///
+ ///
public static Plugin? Instance { get; private set; }
///
diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs
index 184cc3c..d1b0501 100644
--- a/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs
+++ b/ConfusedPolarBear.Plugin.IntroSkipper/ScheduledTasks/FingerprinterTask.cs
@@ -119,7 +119,7 @@ public class FingerprinterTask : IScheduledTask {
}
}
- // TODO: after every season completes, serialize fingerprints to disk somewhere
+ Plugin.Instance!.Configuration.SaveTimestamps();
}
return Task.CompletedTask;
@@ -248,10 +248,11 @@ public class FingerprinterTask : IScheduledTask {
// and that it disappears 10 seconds after the intro begins.
Plugin.Instance!.Intros[episode] = new Intro()
{
+ EpisodeId = episode,
Valid = (introStart > 0) && (introEnd > 0),
IntroStart = introStart,
IntroEnd = introEnd,
- ShowSkipPromptAt = Math.Min(0, introStart - 5),
+ ShowSkipPromptAt = Math.Max(0, introStart - 5),
HideSkipPromptAt = introStart + 10
};
}