Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| efd0f14278 |
@@ -12,5 +12,8 @@ namespace JellyfinPlugin.Configuration
|
||||
|
||||
// Tryb odtwarzania: "Server" (FFmpeg wrapper), "Client" (CSS injection w Web UI), "Auto" (Automatyczny: CSS dla Web, FFmpeg dla aplikacji natywnych)
|
||||
public string PlaybackMode { get; set; } = "Auto";
|
||||
|
||||
// Maksymalna liczba równoległych wątków skanowania czarnych pasów (1 - 16, domyślnie 4)
|
||||
public int MaxParallelScans { get; set; } = 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
<div class="fieldDescription">Choose how the plugin should remove black bars. Auto mode uses lightweight CSS clipping for Web browser DirectPlay, and falls back to FFmpeg transcoding for native apps or unsupported video formats.</div>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="txtMaxParallelScans">Max Parallel Scans (1 - 16):</label>
|
||||
<input type="number" step="1" min="1" max="16" id="txtMaxParallelScans" is="emby-input" required />
|
||||
<div class="fieldDescription">Number of files to analyze concurrently during library scheduled tasks. Default is 4. Higher values speed up library scans on multi-core CPUs.</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block emby-button">
|
||||
<span>Save</span>
|
||||
@@ -56,6 +62,7 @@
|
||||
var mode = config.PlaybackMode || "Auto";
|
||||
if (mode === "Both") mode = "Auto";
|
||||
$('#selectPlaybackMode', page).val(mode);
|
||||
$('#txtMaxParallelScans', page).val(config.MaxParallelScans || 4);
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
});
|
||||
@@ -69,6 +76,7 @@
|
||||
config.IsEnabled = $('#chkEnablePlugin', form).prop('checked');
|
||||
config.CropDetectLimit = parseFloat($('#txtCropLimit', form).val());
|
||||
config.PlaybackMode = $('#selectPlaybackMode', form).val();
|
||||
config.MaxParallelScans = parseInt($('#txtMaxParallelScans', form).val(), 10) || 4;
|
||||
|
||||
ApiClient.updatePluginConfiguration(BlackBarRemoverConfig.pluginUniqueId, config).then(function (result) {
|
||||
Dashboard.processPluginConfigurationUpdateResult(result);
|
||||
|
||||
@@ -42,15 +42,21 @@ namespace JellyfinPlugin.Tasks
|
||||
.ToList();
|
||||
|
||||
int total = items.Count;
|
||||
if (total == 0) return;
|
||||
|
||||
int processed = 0;
|
||||
int maxParallel = Math.Clamp(config.MaxParallelScans, 1, 16);
|
||||
|
||||
foreach (var item in items)
|
||||
var parallelOptions = new ParallelOptions
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Wymuszamy skanowanie, więc nie sprawdzamy czy ma już BlackBarCrop
|
||||
MaxDegreeOfParallelism = maxParallel,
|
||||
CancellationToken = cancellationToken
|
||||
};
|
||||
|
||||
_logger.LogInformation("Starting Force Rescan of {Total} items with {MaxParallel} parallel workers.", total, maxParallel);
|
||||
|
||||
await Parallel.ForEachAsync(items, parallelOptions, async (item, ct) =>
|
||||
{
|
||||
var path = item.Path;
|
||||
if (!string.IsNullOrEmpty(path) && File.Exists(path))
|
||||
{
|
||||
@@ -65,7 +71,7 @@ namespace JellyfinPlugin.Tasks
|
||||
item.ProviderIds = new Dictionary<string, string>();
|
||||
}
|
||||
item.ProviderIds["BlackBarCrop"] = cropData;
|
||||
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, cancellationToken);
|
||||
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, ct);
|
||||
_logger.LogInformation("Found black bars {Crop} in {Path}", cropData, path);
|
||||
}
|
||||
}
|
||||
@@ -75,9 +81,9 @@ namespace JellyfinPlugin.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
processed++;
|
||||
progress.Report((processed / (double)total) * 100);
|
||||
}
|
||||
int current = Interlocked.Increment(ref processed);
|
||||
progress.Report((current / (double)total) * 100);
|
||||
});
|
||||
}
|
||||
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
|
||||
@@ -42,19 +42,28 @@ namespace JellyfinPlugin.Tasks
|
||||
.ToList();
|
||||
|
||||
int total = items.Count;
|
||||
if (total == 0) return;
|
||||
|
||||
int processed = 0;
|
||||
int maxParallel = Math.Clamp(config.MaxParallelScans, 1, 16);
|
||||
|
||||
foreach (var item in items)
|
||||
var parallelOptions = new ParallelOptions
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
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))
|
||||
{
|
||||
processed++;
|
||||
progress.Report((processed / (double)total) * 100);
|
||||
continue;
|
||||
int currentSkipped = Interlocked.Increment(ref processed);
|
||||
progress.Report((currentSkipped / (double)total) * 100);
|
||||
return;
|
||||
}
|
||||
|
||||
var path = item.Path;
|
||||
@@ -71,7 +80,7 @@ namespace JellyfinPlugin.Tasks
|
||||
item.ProviderIds = new Dictionary<string, string>();
|
||||
}
|
||||
item.ProviderIds["BlackBarCrop"] = cropData;
|
||||
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, cancellationToken);
|
||||
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, ct);
|
||||
_logger.LogInformation("Found black bars {Crop} in {Path}", cropData, path);
|
||||
}
|
||||
}
|
||||
@@ -81,9 +90,9 @@ namespace JellyfinPlugin.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
processed++;
|
||||
progress.Report((processed / (double)total) * 100);
|
||||
}
|
||||
int currentDone = Interlocked.Increment(ref processed);
|
||||
progress.Report((currentDone / (double)total) * 100);
|
||||
});
|
||||
}
|
||||
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
|
||||
@@ -63,11 +63,12 @@ This plugin has been verified and tested on:
|
||||
|
||||
1. Go to **Dashboard** -> **Plugins** -> **Black Bar Remover**.
|
||||
2. Set your **Crop Detect Limit** (Default is `0.094`). If your web-dl rips have noisy black bars that are not being cropped, increase this value to `0.15` or `0.20`.
|
||||
3. Select your preferred **Playback Mode**:
|
||||
3. Set **Max Parallel Scans** (Default is `4`, Range `1 - 16`). Controls how many video files are scanned concurrently during library tasks to maximize multi-core CPU utilization.
|
||||
4. Select your preferred **Playback Mode**:
|
||||
- `Auto`: Lightweight CSS clipping for Web browser DirectPlay; FFmpeg transcoding for native apps.
|
||||
- `Client`: Uses CSS injection in the web player.
|
||||
- `Server`: Requires setting up the FFmpeg wrapper.
|
||||
- `Both`: Attempts both methods depending on the client.
|
||||
4. **Important for existing libraries**: The plugin automatically scans *new* files when they are added to Jellyfin. For your existing library, go to **Dashboard -> Scheduled Tasks** and run the **"Scan Missing Black Bars (Black Bar Remover)"** task manually. It will scan all existing movies and episodes in the background.
|
||||
5. **Important for existing libraries**: The plugin automatically scans *new* files when they are added to Jellyfin. For your existing library, go to **Dashboard -> Scheduled Tasks** and run the **"Scan Missing Black Bars (Black Bar Remover)"** task manually. It will scan all existing movies and episodes in the background.
|
||||
|
||||
### Activating the Server-Side Wrapper (Automatic)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user