diff --git a/README.md b/README.md index 9396b64..c4195a3 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ - **Automatische Farbraum-Konvertierung** (Rec.601 PAL/NTSC ↔ Rec.709) inkl. `colorspace`-Filter - **Forced Subtitles** werden automatisch eingebrannt (wenn `_forced.srt` vorhanden) - **Informative Tkinter-UI** mit Analyse, Audio-Uebersicht und Encoding-Log +- **Windows-Fallback ohne Tkinter** mit nativen Dateidialogen und Konsolen-Log - **Amazon PVD optimierte Parameter** (Bitrate, Level, GOP, x264-Settings) - **Saubere Metadaten** + `faststart` für beste Streaming-Performance - Funktioniert mit Drag & Drop (`.bat` oder direkt auf Script ziehen) @@ -49,6 +50,8 @@ ``` 5. In der UI Quelle auswaehlen, analysieren und Encoding starten. +Wenn die installierte Python-Version kein Tkinter mitbringt, oeffnet das Tool automatisch Windows-Dateidialoge fuer Quelle und Ausgabeordner und zeigt die Analyse sowie das Encoding-Log in der Konsole. + Fuer automatisierte CLI-Laeufe kann das Encoding direkt gestartet werden: ```powershell diff --git a/pvd_mezzanine.py b/pvd_mezzanine.py index 0787d73..b5141a9 100644 --- a/pvd_mezzanine.py +++ b/pvd_mezzanine.py @@ -712,8 +712,7 @@ class MezzanineApp: def run_ui() -> int: if tk is None: - print("Tkinter ist nicht verfuegbar. Bitte Datei per CLI uebergeben.") - return 1 + return run_no_tk_fallback() root = tk.Tk() app = MezzanineApp(root) if len(sys.argv) > 1 and os.path.isfile(sys.argv[1]): @@ -722,6 +721,48 @@ def run_ui() -> int: return 0 +def run_no_tk_fallback() -> int: + if len(sys.argv) > 1 and os.path.isfile(sys.argv[1]): + print("Tkinter ist nicht verfuegbar. Starte Drag-and-Drop-Datei direkt im CLI-Modus.") + return run_cli(sys.argv[1], OUTPUT_BASE_DIR) + + print("Tkinter ist nicht verfuegbar. Oeffne Windows-Dateidialoge als Fallback.") + selected = choose_paths_with_powershell() + if selected is None: + print("Keine Quelle ausgewaehlt.") + return 1 + input_file, output_dir = selected + return run_cli(input_file, output_dir) + + +def choose_paths_with_powershell() -> tuple[str, str] | None: + script = r""" +Add-Type -AssemblyName System.Windows.Forms +$open = New-Object System.Windows.Forms.OpenFileDialog +$open.Title = 'Basis-Video auswaehlen' +$open.Filter = 'Video-Dateien (*.mov;*.mxf;*.mp4;*.mkv;*.ts;*.m2ts;*.vob)|*.mov;*.mxf;*.mp4;*.mkv;*.ts;*.m2ts;*.vob|Alle Dateien (*.*)|*.*' +if ($open.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { exit 2 } +$folder = New-Object System.Windows.Forms.FolderBrowserDialog +$folder.Description = 'Ausgabeordner auswaehlen' +$folder.SelectedPath = 'H:\VOD' +if ($folder.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { exit 2 } +Write-Output $open.FileName +Write-Output $folder.SelectedPath +""" + result = subprocess.run( + ["powershell", "-NoProfile", "-STA", "-Command", script], + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0: + return None + lines = [line.strip() for line in result.stdout.splitlines() if line.strip()] + if len(lines) < 2: + return None + return lines[0], lines[1] + + def main() -> int: if len(sys.argv) > 2 and sys.argv[1] == "--cli": return run_cli(sys.argv[2], OUTPUT_BASE_DIR)