cleanup
This commit is contained in:
parent
5e08381ed5
commit
5beaf35198
@ -124,12 +124,12 @@ public class TestAudioFingerprinting
|
||||
|
||||
var expected = new TimeRange[]
|
||||
{
|
||||
new TimeRange(44.6310, 44.8072),
|
||||
new TimeRange(53.5905, 53.8070),
|
||||
new TimeRange(53.8458, 54.2024),
|
||||
new TimeRange(54.2611, 54.5935),
|
||||
new TimeRange(54.7098, 54.9293),
|
||||
new TimeRange(54.9294, 55.2590),
|
||||
new(44.6310, 44.8072),
|
||||
new(53.5905, 53.8070),
|
||||
new(53.8458, 54.2024),
|
||||
new(54.2611, 54.5935),
|
||||
new(54.7098, 54.9293),
|
||||
new(54.9294, 55.2590),
|
||||
};
|
||||
|
||||
var range = new TimeRange(0, 60);
|
||||
|
@ -19,7 +19,7 @@ public class TestBlackFrames
|
||||
expected.AddRange(CreateFrameSequence(5, 6));
|
||||
expected.AddRange(CreateFrameSequence(8, 9.96));
|
||||
|
||||
var actual = FFmpegWrapper.DetectBlackFrames(queueFile("rainbow.mp4"), new(0, 10), 85);
|
||||
var actual = FFmpegWrapper.DetectBlackFrames(QueueFile("rainbow.mp4"), new(0, 10), 85);
|
||||
|
||||
for (var i = 0; i < expected.Count; i++)
|
||||
{
|
||||
@ -37,7 +37,7 @@ public class TestBlackFrames
|
||||
|
||||
var analyzer = CreateBlackFrameAnalyzer();
|
||||
|
||||
var episode = queueFile("credits.mp4");
|
||||
var episode = QueueFile("credits.mp4");
|
||||
episode.Duration = (int)new TimeSpan(0, 5, 30).TotalSeconds;
|
||||
|
||||
var result = analyzer.AnalyzeMediaFile(episode, 240, 30, 85);
|
||||
@ -45,7 +45,7 @@ public class TestBlackFrames
|
||||
Assert.InRange(result.Start, 300 - range, 300 + range);
|
||||
}
|
||||
|
||||
private QueuedEpisode queueFile(string path)
|
||||
private static QueuedEpisode QueueFile(string path)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
@ -55,7 +55,7 @@ public class TestBlackFrames
|
||||
};
|
||||
}
|
||||
|
||||
private BlackFrame[] CreateFrameSequence(double start, double end)
|
||||
private static BlackFrame[] CreateFrameSequence(double start, double end)
|
||||
{
|
||||
var frames = new List<BlackFrame>();
|
||||
|
||||
@ -64,10 +64,10 @@ public class TestBlackFrames
|
||||
frames.Add(new(100, i));
|
||||
}
|
||||
|
||||
return frames.ToArray();
|
||||
return [.. frames];
|
||||
}
|
||||
|
||||
private BlackFrameAnalyzer CreateBlackFrameAnalyzer()
|
||||
private static BlackFrameAnalyzer CreateBlackFrameAnalyzer()
|
||||
{
|
||||
var logger = new LoggerFactory().CreateLogger<BlackFrameAnalyzer>();
|
||||
return new(logger);
|
||||
|
@ -74,7 +74,7 @@ public class TestChapterAnalyzer
|
||||
/// <param name="name">Chapter name.</param>
|
||||
/// <param name="position">Chapter position (in seconds).</param>
|
||||
/// <returns>ChapterInfo.</returns>
|
||||
private ChapterInfo CreateChapter(string name, int position)
|
||||
private static ChapterInfo CreateChapter(string name, int position)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ public class TestEdl
|
||||
Assert.Equal(edlPath, EdlManager.GetEdlPath(mediaPath));
|
||||
}
|
||||
|
||||
private Segment MakeIntro(double start, double end)
|
||||
private static Segment MakeIntro(double start, double end)
|
||||
{
|
||||
return new Segment(Guid.Empty, new TimeRange(start, end));
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ public class ChromaprintAnalyzer : IMediaFileAnalyzer
|
||||
/// <param name="rhsId">Second episode id.</param>
|
||||
/// <param name="rhsRanges">Second episode shared timecodes.</param>
|
||||
/// <returns>Intros for the first and second episodes.</returns>
|
||||
private (Segment Lhs, Segment Rhs) GetLongestTimeRange(
|
||||
private static (Segment Lhs, Segment Rhs) GetLongestTimeRange(
|
||||
Guid lhsId,
|
||||
List<TimeRange> lhsRanges,
|
||||
Guid rhsId,
|
||||
|
@ -22,7 +22,7 @@ namespace ConfusedPolarBear.Plugin.IntroSkipper;
|
||||
/// <summary>
|
||||
/// Intro skipper plugin. Uses audio analysis to find common sequences of audio shared between episodes.
|
||||
/// </summary>
|
||||
public partial class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
{
|
||||
private readonly object _serializationLock = new();
|
||||
private readonly object _introsLock = new();
|
||||
@ -488,7 +488,7 @@ public partial class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
|
||||
// Inject a link to the script at the end of the <head> section.
|
||||
// A regex is used here to ensure the replacement is only done once.
|
||||
Regex headEnd = HeadRegex();
|
||||
Regex headEnd = new Regex(@"</head>", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1));
|
||||
contents = headEnd.Replace(contents, scriptTag + "</head>", 1);
|
||||
|
||||
// Write the modified file contents
|
||||
@ -496,7 +496,4 @@ public partial class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
|
||||
_logger.LogInformation("Skip intro button successfully added");
|
||||
}
|
||||
|
||||
[GeneratedRegex("</head>", RegexOptions.IgnoreCase)]
|
||||
private static partial Regex HeadRegex();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class BaseItemAnalyzerTask
|
||||
public void AnalyzeItems(
|
||||
IProgress<double> progress,
|
||||
CancellationToken cancellationToken,
|
||||
HashSet<Guid>? seasonsToAnalyze = null)
|
||||
IReadOnlyCollection<Guid>? seasonsToAnalyze = null)
|
||||
{
|
||||
var ffmpegValid = FFmpegWrapper.CheckFFmpegVersion();
|
||||
// Assert that ffmpeg with chromaprint is installed
|
||||
@ -74,20 +74,12 @@ public class BaseItemAnalyzerTask
|
||||
var queue = queueManager.GetMediaItems();
|
||||
|
||||
// Filter the queue based on seasonsToAnalyze
|
||||
if (seasonsToAnalyze != null && seasonsToAnalyze.Count > 0)
|
||||
if (seasonsToAnalyze is { Count: > 0 })
|
||||
{
|
||||
queue = queue.Where(kvp => seasonsToAnalyze.Contains(kvp.Key))
|
||||
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value).AsReadOnly();
|
||||
queue = queue.Where(kvp => seasonsToAnalyze.Contains(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
}
|
||||
|
||||
var totalQueued = 0;
|
||||
foreach (var kvp in queue)
|
||||
{
|
||||
totalQueued += kvp.Value.Count;
|
||||
}
|
||||
|
||||
totalQueued *= _analysisModes.Count;
|
||||
|
||||
int totalQueued = queue.Sum(kvp => kvp.Value.Count) * _analysisModes.Count;
|
||||
if (totalQueued == 0)
|
||||
{
|
||||
throw new FingerprintException(
|
||||
@ -100,7 +92,6 @@ public class BaseItemAnalyzerTask
|
||||
}
|
||||
|
||||
var totalProcessed = 0;
|
||||
var modeCount = _analysisModes.Count;
|
||||
var options = new ParallelOptions
|
||||
{
|
||||
MaxDegreeOfParallelism = Plugin.Instance.Configuration.MaxParallelism
|
||||
@ -116,32 +107,28 @@ public class BaseItemAnalyzerTask
|
||||
season.Value,
|
||||
_analysisModes.Where(m => !Plugin.Instance!.IsIgnored(season.Key, m)).ToList());
|
||||
|
||||
var episodeCount = episodes.Count;
|
||||
|
||||
if (episodeCount == 0)
|
||||
if (episodes.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var first = episodes.First();
|
||||
var requiredModeCount = requiredModes.Count;
|
||||
|
||||
if (requiredModeCount == 0)
|
||||
if (requiredModes.Count == 0)
|
||||
{
|
||||
_logger.LogDebug(
|
||||
"All episodes in {Name} season {Season} have already been analyzed",
|
||||
first.SeriesName,
|
||||
first.SeasonNumber);
|
||||
|
||||
Interlocked.Add(ref totalProcessed, episodeCount * modeCount); // Update total Processed directly
|
||||
Interlocked.Add(ref totalProcessed, episodes.Count * _analysisModes.Count); // Update total Processed directly
|
||||
progress.Report(totalProcessed * 100 / totalQueued);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (modeCount != requiredModeCount)
|
||||
if (_analysisModes.Count != requiredModes.Count)
|
||||
{
|
||||
Interlocked.Add(ref totalProcessed, episodeCount);
|
||||
Interlocked.Add(ref totalProcessed, episodes.Count);
|
||||
progress.Report(totalProcessed * 100 / totalQueued); // Partial analysis some modes have already been analyzed
|
||||
}
|
||||
|
||||
@ -223,9 +210,8 @@ public class BaseItemAnalyzerTask
|
||||
{
|
||||
new ChapterAnalyzer(_loggerFactory.CreateLogger<ChapterAnalyzer>())
|
||||
};
|
||||
if (first.IsAnime)
|
||||
{
|
||||
if (Plugin.Instance!.Configuration.UseChromaprint)
|
||||
|
||||
if (first.IsAnime && Plugin.Instance!.Configuration.UseChromaprint)
|
||||
{
|
||||
analyzers.Add(new ChromaprintAnalyzer(_loggerFactory.CreateLogger<ChromaprintAnalyzer>()));
|
||||
}
|
||||
@ -234,19 +220,11 @@ public class BaseItemAnalyzerTask
|
||||
{
|
||||
analyzers.Add(new BlackFrameAnalyzer(_loggerFactory.CreateLogger<BlackFrameAnalyzer>()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == AnalysisMode.Credits)
|
||||
{
|
||||
analyzers.Add(new BlackFrameAnalyzer(_loggerFactory.CreateLogger<BlackFrameAnalyzer>()));
|
||||
}
|
||||
|
||||
if (Plugin.Instance!.Configuration.UseChromaprint)
|
||||
if (!first.IsAnime && Plugin.Instance!.Configuration.UseChromaprint)
|
||||
{
|
||||
analyzers.Add(new ChromaprintAnalyzer(_loggerFactory.CreateLogger<ChromaprintAnalyzer>()));
|
||||
}
|
||||
}
|
||||
|
||||
// Use each analyzer to find skippable ranges in all media files, removing successfully
|
||||
// analyzed items from the queue.
|
||||
|
@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ConfusedPolarBear.Plugin.IntroSkipper.Configuration;
|
||||
using ConfusedPolarBear.Plugin.IntroSkipper.Data;
|
||||
using ConfusedPolarBear.Plugin.IntroSkipper.ScheduledTasks;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
@ -24,6 +25,7 @@ public sealed class Entrypoint : IHostedService, IDisposable
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly HashSet<Guid> _seasonsToAnalyze = [];
|
||||
private readonly Timer _queueTimer;
|
||||
private readonly PluginConfiguration _config;
|
||||
private static readonly ManualResetEventSlim _autoTaskCompletEvent = new(false);
|
||||
private bool _analyzeAgain;
|
||||
private static CancellationTokenSource? _cancellationTokenSource;
|
||||
@ -46,6 +48,7 @@ public sealed class Entrypoint : IHostedService, IDisposable
|
||||
_logger = logger;
|
||||
_loggerFactory = loggerFactory;
|
||||
|
||||
_config = Plugin.Instance?.Configuration ?? new PluginConfiguration();
|
||||
_queueTimer = new Timer(
|
||||
OnTimerCallback,
|
||||
null,
|
||||
@ -119,7 +122,7 @@ public sealed class Entrypoint : IHostedService, IDisposable
|
||||
private void OnItemAdded(object? sender, ItemChangeEventArgs itemChangeEventArgs)
|
||||
{
|
||||
// Don't do anything if auto detection is disabled
|
||||
if (!Plugin.Instance!.Configuration.AutoDetectIntros && !Plugin.Instance.Configuration.AutoDetectCredits)
|
||||
if (!_config.AutoDetectIntros && !_config.AutoDetectCredits)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -148,7 +151,7 @@ public sealed class Entrypoint : IHostedService, IDisposable
|
||||
private void OnItemModified(object? sender, ItemChangeEventArgs itemChangeEventArgs)
|
||||
{
|
||||
// Don't do anything if auto detection is disabled
|
||||
if (!Plugin.Instance!.Configuration.AutoDetectIntros && !Plugin.Instance.Configuration.AutoDetectCredits)
|
||||
if (!_config.AutoDetectIntros && !_config.AutoDetectCredits)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -177,7 +180,7 @@ public sealed class Entrypoint : IHostedService, IDisposable
|
||||
private void OnLibraryRefresh(object? sender, TaskCompletionEventArgs eventArgs)
|
||||
{
|
||||
// Don't do anything if auto detection is disabled
|
||||
if (!Plugin.Instance!.Configuration.AutoDetectIntros && !Plugin.Instance.Configuration.AutoDetectCredits)
|
||||
if (!_config.AutoDetectIntros && !_config.AutoDetectCredits)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -257,21 +260,18 @@ public sealed class Entrypoint : IHostedService, IDisposable
|
||||
var modes = new List<AnalysisMode>();
|
||||
var tasklogger = _loggerFactory.CreateLogger("DefaultLogger");
|
||||
|
||||
if (Plugin.Instance!.Configuration.AutoDetectIntros && Plugin.Instance.Configuration.AutoDetectCredits)
|
||||
{
|
||||
modes.Add(AnalysisMode.Introduction);
|
||||
modes.Add(AnalysisMode.Credits);
|
||||
tasklogger = _loggerFactory.CreateLogger<DetectIntrosCreditsTask>();
|
||||
}
|
||||
else if (Plugin.Instance.Configuration.AutoDetectIntros)
|
||||
if (_config.AutoDetectIntros)
|
||||
{
|
||||
modes.Add(AnalysisMode.Introduction);
|
||||
tasklogger = _loggerFactory.CreateLogger<DetectIntrosTask>();
|
||||
}
|
||||
else if (Plugin.Instance.Configuration.AutoDetectCredits)
|
||||
|
||||
if (_config.AutoDetectCredits)
|
||||
{
|
||||
modes.Add(AnalysisMode.Credits);
|
||||
tasklogger = _loggerFactory.CreateLogger<DetectCreditsTask>();
|
||||
tasklogger = modes.Count == 2
|
||||
? _loggerFactory.CreateLogger<DetectIntrosCreditsTask>()
|
||||
: _loggerFactory.CreateLogger<DetectCreditsTask>();
|
||||
}
|
||||
|
||||
var baseCreditAnalyzer = new BaseItemAnalyzerTask(
|
||||
|
Loading…
x
Reference in New Issue
Block a user