fix: resolve ffmpeg path dynamically, handle empty crop check, and strip quotes in wrapper
Build and Release Plugin / release (push) Successful in 37s

This commit is contained in:
2026-09-17 19:26:25 +02:00
parent d5e11a52ed
commit f6ed790801
5 changed files with 24 additions and 16 deletions
+1
View File
@@ -25,6 +25,7 @@ namespace JellyfinPlugin.Api
public ContentResult GetCropByPath([FromQuery] string path)
{
if (string.IsNullOrEmpty(path)) return Content(string.Empty, "text/plain");
path = path.Trim('"').Trim('\'');
var mode = Plugin.Instance!.Configuration.PlaybackMode;
if (mode == "Client") return Content(string.Empty, "text/plain");
+8 -1
View File
@@ -9,6 +9,13 @@ namespace JellyfinPlugin
{
public static class CropHelper
{
private static string GetFFmpegPath()
{
if (File.Exists("/usr/lib/jellyfin-ffmpeg/ffmpeg")) return "/usr/lib/jellyfin-ffmpeg/ffmpeg";
if (File.Exists("/usr/bin/ffmpeg")) return "/usr/bin/ffmpeg";
return "ffmpeg";
}
public static async Task<string> DetectCropAsync(string filePath, double limit)
{
// FFmpeg w nowych wersjach przyjmuje limit w formie ułamka, np. 24/255 to ok 0.094
@@ -17,7 +24,7 @@ namespace JellyfinPlugin
var startInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
FileName = GetFFmpegPath(),
// KLUCZOWE: reset=1, żeby oceniał każdą klatkę niezależnie!
Arguments = $"-skip_frame nokey -i \"{filePath}\" -vf \"cropdetect=limit={limitStr}:round=16:reset=1\" -f null -",
RedirectStandardError = true,
+3 -1
View File
@@ -57,7 +57,9 @@ namespace JellyfinPlugin
{
try
{
if (video.ProviderIds != null && video.ProviderIds.ContainsKey("BlackBarCrop"))
if (video.ProviderIds != null &&
video.ProviderIds.TryGetValue("BlackBarCrop", out string? existingCrop) &&
!string.IsNullOrEmpty(existingCrop))
{
return;
}
@@ -48,7 +48,9 @@ namespace JellyfinPlugin.Tasks
{
cancellationToken.ThrowIfCancellationRequested();
if (item.ProviderIds != null && item.ProviderIds.ContainsKey("BlackBarCrop"))
if (item.ProviderIds != null &&
item.ProviderIds.TryGetValue("BlackBarCrop", out string? existingCrop) &&
!string.IsNullOrEmpty(existingCrop))
{
processed++;
progress.Report((processed / (double)total) * 100);
@@ -62,19 +64,17 @@ namespace JellyfinPlugin.Tasks
{
string cropData = await CropHelper.DetectCropAsync(path, config.CropDetectLimit);
if (!string.IsNullOrEmpty(cropData))
{
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;
item.ProviderIds["BlackBarCrop"] = cropData;
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);
+1 -3
View File
@@ -92,9 +92,7 @@ for (( i=1; i<=$#; i++ )); do
done
if [ -n ""$INPUT_FILE"" ]; then
# Jellyfin przekazuje ścieżkę z prefiksem file: (np. file:""/home/..."").
# Shell usuwa cudzysłowy automatycznie – zostaje nam tylko file: do usunięcia.
CLEAN_PATH=""${{INPUT_FILE#file:}}""
CLEAN_PATH=$(echo ""$INPUT_FILE"" | tr -d '""' | sed 's/^file://')
CROP_DATA=$(curl -s --max-time 1 -G --data-urlencode ""Path=$CLEAN_PATH"" http://127.0.0.1:8096/BlackBarRemover/CropByPath)