Add back separate tasks as optional

This commit is contained in:
TwistedUmbrellaX 2024-03-30 18:22:54 -04:00
parent 2e67a4fb5e
commit 3cc9a66990
6 changed files with 258 additions and 58 deletions

View File

@ -30,17 +30,12 @@ public class PluginConfiguration : BasePluginConfiguration
/// <summary>
/// Gets or sets a value indicating whether to scan for intros during a scheduled task.
/// </summary>
public bool DetectIntros { get; set; } = true;
public bool AutoDetectIntros { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether to scan for credits during a scheduled task.
/// </summary>
public bool DetectCredits { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether to analyze automatically, when new Items are added.
/// </summary>
public bool AutomaticAnalysis { get; set; } = false;
public bool AutoDetectCredits { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether to analyze season 0.

View File

@ -29,40 +29,29 @@
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="DetectIntros" type="checkbox" is="emby-checkbox" />
<span>Detect Introductions</span>
<input id="AutoDetectIntros" type="checkbox" is="emby-checkbox" />
<span>Automatically Scan Intros</span>
</label>
<div class="fieldDescription">
This option enables scheduled introduction detection. Your videos will be scanned for introductions during a scheduled task.
If enabled, introductions will be automatically analyzed for new media
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="DetectCredits" type="checkbox" is="emby-checkbox" />
<span>Detect Credits</span>
<input id="AutoDetectCredits" type="checkbox" is="emby-checkbox" />
<span>Automatically Scan Credits</span>
</label>
<div class="fieldDescription">
This option enables scheduled credit detection. Your videos will be scanned for credits during a scheduled task.
If enabled, credits will be automatically analyzed for new media
</div>
<div class="fieldDescription">
Note: Selecting neither Intro nor Credit Detection will disable automatic scans. To configure the scheduled task, see <a is="emby-linkbutton" class="button-link" href="scheduledtasks.html">scheduled tasks</a>.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="AutomaticAnalysis" type="checkbox" is="emby-checkbox" />
<span>Automatic analysis</span>
</label>
<div class="fieldDescription">
If checked, newly added items will be automatically analyzed.
</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="AnalyzeSeasonZero" type="checkbox" is="emby-checkbox" />
@ -227,7 +216,7 @@
Noise tolerance
</label>
<input id="SilenceDetectionMaximumNoise" type="number" is="emby-input" min="-90"
max="0" />
max="0" />
<div class="fieldDescription">
Noise tolerance in negative decibels.
</div>
@ -238,7 +227,7 @@
Minimum silence duration
</label>
<input id="SilenceDetectionMinimumDuration" type="number" is="emby-input" min="0"
step="0.01" />
step="0.01" />
<div class="fieldDescription">
Minimum silence duration in seconds before adjusting introduction end time.
</div>
@ -248,7 +237,7 @@
<details id="detection">
<summary>Process Configuration</summary>
<br/>
<br />
<div class="checkboxContainer checkboxContainer-withDescription">
<label class="emby-checkbox-label">
<input id="UseChromaprint" type="checkbox" is="emby-checkbox" />
@ -316,7 +305,7 @@
ffmpeg Threads
</label>
<input id="ProcessThreads" type="number" is="emby-input" min="0"
max="16" />
max="16" />
<div class="fieldDescription">
Number of simultaneous processes to use for ffmpeg operations.
<br />
@ -622,9 +611,8 @@
]
var booleanConfigurationFields = [
"DetectIntros",
"DetectCredits",
"AutomaticAnalysis",
"AutoDetectIntros",
"AutoDetectCredits",
"AnalyzeSeasonZero",
"RegenerateEdlFiles",
"UseChromaprint",

View File

@ -62,7 +62,7 @@ public class Entrypoint : IServerEntryPoint
/// <returns>Task.</returns>
public Task RunAsync()
{
if (Plugin.Instance!.Configuration.AutomaticAnalysis)
if (Plugin.Instance!.Configuration.AutoDetectIntros || Plugin.Instance!.Configuration.AutoDetectCredits)
{
_libraryManager.ItemAdded += OnItemAdded;
_libraryManager.ItemUpdated += OnItemModified;
@ -196,22 +196,40 @@ public class Entrypoint : IServerEntryPoint
var progress = new Progress<double>();
var cancellationToken = new CancellationToken(false);
if (Plugin.Instance!.Configuration.DetectIntros)
if (Plugin.Instance!.Configuration.AutoDetectIntros && Plugin.Instance!.Configuration.AutoDetectCredits)
{
// This is where we can optimize a single scan
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosCreditsTask>(),
_loggerFactory,
_libraryManager);
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
_loggerFactory.CreateLogger<DetectIntrosCreditsTask>(),
_loggerFactory,
_libraryManager);
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
}
else if (Plugin.Instance!.Configuration.AutoDetectIntros)
{
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosAndCreditsTask>(),
_loggerFactory.CreateLogger<DetectIntrosTask>(),
_loggerFactory,
_libraryManager);
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
}
if (Plugin.Instance!.Configuration.DetectCredits)
else if (Plugin.Instance!.Configuration.AutoDetectCredits)
{
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
_loggerFactory.CreateLogger<DetectIntrosAndCreditsTask>(),
_loggerFactory.CreateLogger<DetectCreditsTask>(),
_loggerFactory,
_libraryManager);

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace ConfusedPolarBear.Plugin.IntroSkipper;
/// <summary>
/// Analyze all television episodes for credits.
/// TODO: analyze all media files.
/// </summary>
public class DetectCreditsTask : IScheduledTask
{
private readonly ILogger<DetectCreditsTask> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly ILibraryManager _libraryManager;
/// <summary>
/// Initializes a new instance of the <see cref="DetectCreditsTask"/> class.
/// </summary>
/// <param name="loggerFactory">Logger factory.</param>
/// <param name="libraryManager">Library manager.</param>
/// <param name="logger">Logger.</param>
public DetectCreditsTask(
ILogger<DetectCreditsTask> logger,
ILoggerFactory loggerFactory,
ILibraryManager libraryManager)
{
_logger = logger;
_loggerFactory = loggerFactory;
_libraryManager = libraryManager;
}
/// <summary>
/// Gets the task name.
/// </summary>
public string Name => "Detect Credits";
/// <summary>
/// Gets the task category.
/// </summary>
public string Category => "Intro Skipper";
/// <summary>
/// Gets the task description.
/// </summary>
public string Description => "Analyzes the audio and video of all television episodes to find credits.";
/// <summary>
/// Gets the task key.
/// </summary>
public string Key => "CPBIntroSkipperDetectCredits";
/// <summary>
/// Analyze all episodes in the queue. Only one instance of this task should be run at a time.
/// </summary>
/// <param name="progress">Task progress.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Task.</returns>
public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
if (_libraryManager is null)
{
throw new InvalidOperationException("Library manager was null");
}
// abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning)
{
return Task.CompletedTask;
}
else
{
Plugin.Instance!.AnalyzerTaskIsRunning = true;
}
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
_loggerFactory.CreateLogger<DetectCreditsTask>(),
_loggerFactory,
_libraryManager);
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
Plugin.Instance!.AnalyzerTaskIsRunning = false;
return Task.CompletedTask;
}
/// <summary>
/// Get task triggers.
/// </summary>
/// <returns>Task triggers.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return Array.Empty<TaskTriggerInfo>();
}
}

View File

@ -11,18 +11,18 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper;
/// <summary>
/// Analyze all television episodes for introduction sequences.
/// </summary>
public class DetectIntrosAndCreditsTask : IScheduledTask
public class DetectIntrosCreditsTask : IScheduledTask
{
private readonly ILoggerFactory _loggerFactory;
private readonly ILibraryManager _libraryManager;
/// <summary>
/// Initializes a new instance of the <see cref="DetectIntrosAndCreditsTask"/> class.
/// Initializes a new instance of the <see cref="DetectIntrosCreditsTask"/> class.
/// </summary>
/// <param name="loggerFactory">Logger factory.</param>
/// <param name="libraryManager">Library manager.</param>
public DetectIntrosAndCreditsTask(
public DetectIntrosCreditsTask(
ILoggerFactory loggerFactory,
ILibraryManager libraryManager)
{
@ -73,27 +73,21 @@ public class DetectIntrosAndCreditsTask : IScheduledTask
Plugin.Instance!.AnalyzerTaskIsRunning = true;
}
if (Plugin.Instance!.Configuration.DetectIntros)
{
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosAndCreditsTask>(),
_loggerFactory,
_libraryManager);
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosCreditsTask>(),
_loggerFactory,
_libraryManager);
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
}
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
if (Plugin.Instance!.Configuration.DetectCredits)
{
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
_loggerFactory.CreateLogger<DetectIntrosAndCreditsTask>(),
_loggerFactory,
_libraryManager);
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Credits,
_loggerFactory.CreateLogger<DetectIntrosCreditsTask>(),
_loggerFactory,
_libraryManager);
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
}
baseCreditAnalyzer.AnalyzeItems(progress, cancellationToken);
Plugin.Instance!.AnalyzerTaskIsRunning = false;

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace ConfusedPolarBear.Plugin.IntroSkipper;
/// <summary>
/// Analyze all television episodes for introduction sequences.
/// </summary>
public class DetectIntrosTask : IScheduledTask
{
private readonly ILogger<DetectIntrosTask> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly ILibraryManager _libraryManager;
/// <summary>
/// Initializes a new instance of the <see cref="DetectIntrosTask"/> class.
/// </summary>
/// <param name="loggerFactory">Logger factory.</param>
/// <param name="libraryManager">Library manager.</param>
/// <param name="logger">Logger.</param>
public DetectIntrosTask(
ILogger<DetectIntrosTask> logger,
ILoggerFactory loggerFactory,
ILibraryManager libraryManager)
{
_logger = logger;
_loggerFactory = loggerFactory;
_libraryManager = libraryManager;
}
/// <summary>
/// Gets the task name.
/// </summary>
public string Name => "Detect Introductions";
/// <summary>
/// Gets the task category.
/// </summary>
public string Category => "Intro Skipper";
/// <summary>
/// Gets the task description.
/// </summary>
public string Description => "Analyzes the audio of all television episodes to find introduction sequences.";
/// <summary>
/// Gets the task key.
/// </summary>
public string Key => "CPBIntroSkipperDetectIntroductions";
/// <summary>
/// Analyze all episodes in the queue. Only one instance of this task should be run at a time.
/// </summary>
/// <param name="progress">Task progress.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Task.</returns>
public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
if (_libraryManager is null)
{
throw new InvalidOperationException("Library manager was null");
}
// abort if analyzer is already running
if (Plugin.Instance!.AnalyzerTaskIsRunning)
{
return Task.CompletedTask;
}
else
{
Plugin.Instance!.AnalyzerTaskIsRunning = true;
}
var baseIntroAnalyzer = new BaseItemAnalyzerTask(
AnalysisMode.Introduction,
_loggerFactory.CreateLogger<DetectIntrosTask>(),
_loggerFactory,
_libraryManager);
baseIntroAnalyzer.AnalyzeItems(progress, cancellationToken);
Plugin.Instance!.AnalyzerTaskIsRunning = false;
return Task.CompletedTask;
}
/// <summary>
/// Get task triggers.
/// </summary>
/// <returns>Task triggers.</returns>
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return Array.Empty<TaskTriggerInfo>();
}
}