using System; using System.IO; using System.Threading.Tasks; using MediaBrowser.Controller.Plugins; using Microsoft.Extensions.Logging; using MediaBrowser.Common.Configuration; using Microsoft.Extensions.Hosting; namespace JellyfinPlugin { public class WrapperGenerator : IHostedService { private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; public WrapperGenerator(ILogger logger, IApplicationPaths appPaths) { _logger = logger; _appPaths = appPaths; } public Task StartAsync(CancellationToken cancellationToken) { GenerateWrapper(); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } private void GenerateWrapper() { try { string wrapperDir = Path.Combine(_appPaths.PluginsPath, "BlackBarRemover"); Directory.CreateDirectory(wrapperDir); string wrapperPath = Path.Combine(wrapperDir, "ffmpeg-wrapper.sh"); string script = @"#!/bin/bash # Zmienna przechowująca ścieżkę do prawdziwego FFmpeg Jellyfina (zmień jeśli trzeba) REAL_FFMPEG=""/usr/lib/jellyfin-ffmpeg/ffmpeg"" # Znajdujemy ścieżkę pliku wejściowego (argument po -i) INPUT_FILE="""" for i in ""${!@}""; do if [[ ""${@:$i:1}"" == ""-i"" ]]; then INPUT_FILE=""${@:$i+1:1}"" break fi done # Pobieramy crop z API naszej wtyczki if [ -n ""$INPUT_FILE"" ]; then # Jellyfin lokalnie słucha na 8096, odpytujemy API o crop CROP_DATA=$(curl -s --max-time 1 -G --data-urlencode ""Path=$INPUT_FILE"" http://127.0.0.1:8096/BlackBarRemover/CropByPath) if [ -n ""$CROP_DATA"" ] && [ ""$CROP_DATA"" != """" ]; then # Znaleziono crop! Wstrzykujemy filtr crop=W:H:X:Y do argumentów # Dodajemy -vf crop przed argumentami wyjścia NEW_ARGS=() for arg in ""$@""; do # Prosta iniekcja, w realnym środowisku szukamy gdzie wkleić -vf, zazwyczaj przed plikiem wyjściowym. # Jellyfin sprzętowy tworzy filtry z -filter_complex, w softwareowym z -vf. NEW_ARGS+=(""$arg"") done # Uruchamiamy ffmpeg z crop # UWAGA: to jest uproszczenie. Prawdziwy wrapper IntroSkipper musi łączyć filtry. # W tym MVP dodajemy prosty filter: exec ""$REAL_FFMPEG"" ""$@"" -vf ""crop=$CROP_DATA"" exit 0 fi fi # Zwykłe uruchomienie bez crop exec ""$REAL_FFMPEG"" ""$@"" "; File.WriteAllText(wrapperPath, script); // Nadajemy uprawnienia do wykonywania w systemach Linux (używając shella) if (Environment.OSVersion.Platform == PlatformID.Unix) { System.Diagnostics.Process.Start("chmod", $"+x \"{wrapperPath}\""); } _logger.LogInformation("Wygenerowano skrypt FFmpeg Wrapper w lokalizacji: {Path}", wrapperPath); } catch (Exception ex) { _logger.LogError(ex, "Błąd podczas generowania skryptu FFmpeg wrapper."); } } public void Dispose() { } } }