Add Force Rescan All Black Bars scheduled task
Build and Release Plugin / release (push) Failing after 17s

This commit is contained in:
2026-09-17 15:45:57 +02:00
parent a048a91f23
commit 9159d8f8d7
2 changed files with 91 additions and 0 deletions
@@ -15,6 +15,7 @@ namespace JellyfinPlugin
// W Jellyfin 10.9+ zadania harmonogramu czasami trzeba jawnie rejestrować jeśli refleksja ich nie wychwyci
serviceCollection.AddScoped<MediaBrowser.Model.Tasks.IScheduledTask, LibraryRetroactiveScanTask>();
serviceCollection.AddScoped<MediaBrowser.Model.Tasks.IScheduledTask, LibraryForceRescanTask>();
}
}
}
@@ -0,0 +1,90 @@
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 LibraryForceRescanTask : IScheduledTask
{
private readonly ILogger<LibraryForceRescanTask> _logger;
private readonly ILibraryManager _libraryManager;
public LibraryForceRescanTask(ILogger<LibraryForceRescanTask> logger, ILibraryManager libraryManager)
{
_logger = logger;
_libraryManager = libraryManager;
}
public string Name => "Force Rescan All Black Bars (Black Bar Remover)";
public string Key => "BlackBarForceRescanTask";
public string Description => "Forces a rescan of all files, overwriting any previously saved crop data. Use this if you changed the detection limit.";
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;
int processed = 0;
foreach (var item in items)
{
cancellationToken.ThrowIfCancellationRequested();
// Wymuszamy skanowanie, więc nie sprawdzamy czy ma już BlackBarCrop
var path = item.Path;
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
try
{
string cropData = await CropHelper.DetectCropAsync(path, config.CropDetectLimit);
if (item.ProviderIds == null)
{
item.ProviderIds = new Dictionary<string, string>();
}
// Zawsze dodajemy flagę, nawet jak puste, żeby nie skanować drugi raz tego samego pliku
// (puste oznacza że nie ma czarnych pasów do ucięcia)
item.ProviderIds["BlackBarCrop"] = cropData ?? string.Empty;
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, cancellationToken);
if (!string.IsNullOrEmpty(cropData))
_logger.LogInformation("Found black bars {Crop} in {Path}", cropData, path);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error scanning file {Path}", path);
}
}
processed++;
progress.Report((processed / (double)total) * 100);
}
}
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
{
return Array.Empty<TaskTriggerInfo>();
}
}
}