Files
blackBarRemover/JellyfinPlugin/Tasks/LibraryRetroactiveScanTask.cs
T

104 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
namespace JellyfinPlugin.Tasks
{
public class LibraryRetroactiveScanTask : IScheduledTask
{
private readonly ILogger<LibraryRetroactiveScanTask> _logger;
private readonly ILibraryManager _libraryManager;
public LibraryRetroactiveScanTask(ILogger<LibraryRetroactiveScanTask> logger, ILibraryManager libraryManager)
{
_logger = logger;
_libraryManager = libraryManager;
}
public string Name => "Scan Missing Black Bars (Black Bar Remover)";
public string Key => "BlackBarRetroactiveScanTask";
public string Description => "Scans the existing library, skipping already analyzed files. Run this after installing the plugin.";
public string Category => "Library";
public async Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
var config = Plugin.Instance!.Configuration;
if (!config.IsEnabled)
{
_logger.LogInformation("Plugin is disabled. Skipping.");
return;
}
var items = _libraryManager.RootFolder.GetRecursiveChildren()
.Where(x => x is Movie || x is Episode)
.ToList();
int total = items.Count;
if (total == 0) return;
int processed = 0;
int maxParallel = Math.Clamp(config.MaxParallelScans, 1, 16);
var parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = maxParallel,
CancellationToken = cancellationToken
};
_logger.LogInformation("Starting Retroactive Scan of {Total} items with {MaxParallel} parallel workers.", total, maxParallel);
await Parallel.ForEachAsync(items, parallelOptions, async (item, ct) =>
{
if (item.ProviderIds != null &&
item.ProviderIds.TryGetValue("BlackBarCrop", out string? existingCrop) &&
!string.IsNullOrEmpty(existingCrop))
{
int currentSkipped = Interlocked.Increment(ref processed);
progress.Report((currentSkipped / (double)total) * 100);
return;
}
var path = item.Path;
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
try
{
string cropData = await CropHelper.DetectCropAsync(path, config.CropDetectLimit);
if (!string.IsNullOrEmpty(cropData))
{
if (item.ProviderIds == null)
{
item.ProviderIds = new Dictionary<string, string>();
}
item.ProviderIds["BlackBarCrop"] = cropData;
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, ct);
_logger.LogInformation("Found black bars {Crop} in {Path}", cropData, path);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error scanning file {Path}", path);
}
}
int currentDone = Interlocked.Increment(ref processed);
progress.Report((currentDone / (double)total) * 100);
});
}
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return Array.Empty<TaskTriggerInfo>();
}
}
}