# Jellyfin Trickplay Generator (Legacy Layout) Dieses Script erzeugt **Jellyfin-kompatible Trickplay-Tiles** im **Legacy-Layout** – also genauso, wie du es in deinem Medienordner beobachtet hast: ``` .trickplay/ 640 - 10x10/ 0.jpg 1.jpg ... ``` ✅ **Keine JSON-Datei** im Trickplay-Ordner (Legacy). ✅ **Parallelisierbar** (mehrere Medien gleichzeitig) – anders als Jellyfin intern. ✅ **Optional Hardware-Decode** via ffmpeg (`vaapi`, `qsv`, `cuda`, `d3d11va`, `amf`). ✅ **Resume/Incremental**: Generiert nur fehlende Auflösungen bzw. nur wenn Settings geändert wurden (per-Width Fingerprint). ✅ **Schöne Konsole** mit Fortschritt (optional via `rich`). --- ## Voraussetzungen ### Python - Windows: `py --version` - Linux: `python3 --version` ### ffmpeg + ffprobe Beide müssen verfügbar sein: ```bash ffmpeg -version ffprobe -version ``` Wenn nicht im PATH, kannst du die Pfade in `settings.ini` setzen. ### Python-Pakete Pflicht: ```bash pip install pillow ``` Optional (für hübsche Fortschrittsbalken): ```bash pip install rich ``` --- ## Installation (Windows Beispiel) ```powershell cd "C:\Users\Thorsten\Documents\Scripte" py -m pip install pillow rich py .\py_jellyfin_trickplay_generator.py ``` --- ## Installation (Linux Beispiel) ```bash cd /pfad/zum/script python3 -m pip install --user pillow rich python3 ./py_jellyfin_trickplay_generator.py ``` --- ## Konfiguration: `settings.ini` Beim ersten Start wird automatisch eine `settings.ini` im gleichen Ordner erstellt. Beispiel: ```ini [input] paths = L:\TV Serien\FSK 0 L:\Filme recursive = true [general] output = alongside out_dir = workers = 6 replace = false keep_temp = false loglevel = error jpeg_quality = 90 [trickplay] interval_ms = 10000 widths = 320,640 tile_cols = 10 tile_rows = 10 [ffmpeg] ffmpeg = ffprobe = hw = none hw_device = ``` ### Erklärung wichtiger Optionen #### `[input]` - `paths`: Eine oder mehrere Wurzeln. Multi-line empfohlen. - `recursive`: `true` findet Medien rekursiv in Unterordnern. #### `[general]` - `workers`: Anzahl paralleler Prozesse (Medien parallel). - `replace`: - `false`: Incremental/Resume (nur fehlende Widths / nur wenn Fingerprint nicht passt) - `true`: Alles neu (löscht vorhandene Trickplay-Daten für die Datei) - `output`: - `alongside` (Standard): direkt neben der Videodatei als `*.trickplay` - `dir`: in einem zentralen `out_dir` (selten sinnvoll für Jellyfin Legacy) - `loglevel`: ffmpeg Log-Level (`error`, `warning`, `info`, ...) #### `[trickplay]` - `interval_ms`: Abstand zwischen Thumbnails (10000ms = alle 10 Sekunden) - `widths`: Zielbreiten, z.B. `640` oder `320,640,720` - `tile_cols`, `tile_rows`: Grid der Tile-Spritesheets (z.B. `10x10`) #### `[ffmpeg]` - `hw` (Hardware-Decode): - `none` (Standard) - `vaapi` (Linux Intel/AMD iGPU, /dev/dri/…) - `qsv` (Intel QuickSync) - `cuda` (NVIDIA) - `d3d11va` (Windows: Intel/AMD/NVIDIA – Decode über D3D11) - `amf` (AMD – intern ebenfalls d3d11va für Decode genutzt) - `hw_device`: z.B. `/dev/dri/renderD128` bei VAAPI --- ## CLI Nutzung (Overrides) CLI-Argumente überschreiben Werte aus der INI: ```bash python3 py_jellyfin_trickplay_generator.py --workers 8 --widths 640 --interval-ms 10000 /pfad/zu/Medien ``` Rekursiv: ```bash python3 py_jellyfin_trickplay_generator.py --recursive /pfad/zu/Serien ``` --- ## Fortschritt / Konsole Wenn `rich` installiert ist, zeigt das Script: - **Overall** (Gesamtfortschritt Dateien) - **Worker** pro Prozess (Stage: probe / extract / tile / skip) Wenn `rich` fehlt, gibt es einfache Textausgaben pro Datei. --- ## Resume / Incremental Build (Marker-Dateien) Damit man erkennt, ob ein Durchlauf sauber fertig wurde und um nur fehlende Dinge zu generieren, werden Marker-Dateien genutzt. ### Root (pro Video) Im `*.trickplay` Root: - `.inprogress` → Job lief / wurde evtl. unterbrochen - `.complete` → Job komplett (für genau diese Job-Settings) - `.trickplay.job.json` → Job-Settings + Job-Fingerprint ### Pro Width In jedem Width-Ordner (z.B. `640 - 10x10/`): - `.inprogress` → diese Width wurde gerade gebaut - `.complete` → diese Width ist vollständig - `.meta.json` → Width-Settings + Width-Fingerprint **Wichtig:** Der Skip passiert nur, wenn - Tiles existieren (`0.jpg` vorhanden), - `.complete` existiert, - und `.meta.json`-Fingerprint zu den aktuellen Settings passt. So kannst du z.B. später `widths = 320,640,720` einstellen und es wird nur 720 nachgezogen. --- ## Typische Probleme ### `ffmpeg not found in PATH` - Windows: PowerShell neu öffnen nachdem ffmpeg installiert wurde - oder Pfade in `settings.ini` setzen: ```ini [ffmpeg] ffmpeg = C:\Tools\ffmpeg\bin\ffmpeg.exe ffprobe = C:\Tools\ffmpeg\bin\ffprobe.exe ``` ### `ModuleNotFoundError: No module named 'PIL'` ```bash pip install pillow ``` ### Windows: `python3` öffnet Microsoft Store Nutze: ```powershell py script.py ``` --- ## Notes - Das Script implementiert das beobachtete Jellyfin **Legacy** Trickplay-Layout. - Wenn Jellyfin in deiner Installation irgendwann auf ein anderes Layout umstellt (mit JSON/Manifest), müsste das Script entsprechend erweitert werden. ---