Files
2026-02-12 09:34:07 +01:00

341 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:
```
<VideoDatei>.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.
---
---
## ffmpeg Hardware-Decode (hw) Details (Windows vs Linux)
Wichtig: Das Script nutzt Hardware **nur fürs Decode** (Einlesen/Decodieren des Videos).
Die Ausgabe ist weiterhin **MJPEG** (CPU), was für Trickplay/Thumbs völlig ok ist.
### Überblick: Welche `hw`-Option wo sinnvoll ist
- **Windows**
- `d3d11va` ✅ (empfohlen; Intel/AMD/NVIDIA Decode über Direct3D 11)
- `cuda` ✅ (NVIDIA Decode; meist stabil, braucht NVIDIA-Treiber + ffmpeg mit CUDA-Support)
- `qsv` ✅ (Intel Quick Sync; benötigt Intel iGPU + Treiber; ffmpeg Build muss QSV unterstützen)
- `amf` ⚠️ (AMD AMF ist in ffmpeg primär Windows-Stack; im Script wird fürs Decode intern ebenfalls `d3d11va` genutzt)
- `vaapi` ❌ (VAAPI ist Linux/Unix-Stack)
- **Linux**
- `vaapi` ✅ (empfohlen für Intel iGPU & AMD GPUs über Mesa VAAPI)
- `qsv` ✅ (Intel Quick Sync; je nach Distribution/ffmpeg Build)
- `cuda` ✅ (NVIDIA; benötigt Treiber + ffmpeg mit CUDA/NVDEC)
- `d3d11va` ❌ (Windows-only)
- `amf` ❌/⚠️ (AMD AMF ist i.d.R. nicht der Linux-Standardpfad; auf Linux nimmst du für AMD fast immer `vaapi`)
### `hw_device` wann braucht man das?
Im Script wird `hw_device` derzeit **nur für `vaapi`** genutzt.
#### VAAPI (Linux): Device angeben
- Typisch: `hw = vaapi`
- Device: **Render-Node** unter `/dev/dri/`
Meist ist das:
- `/dev/dri/renderD128` (sehr häufig)
- oder `/dev/dri/renderD129` (wenn mehrere GPUs vorhanden)
**So findest du die Render Nodes:**
```bash
ls -l /dev/dri/
```
Beispiel output:
- `card0`, `card1` (Display devices)
- `renderD128`, `renderD129` (Render nodes, die wir wollen)
**Empfehlung:** immer den `renderD*` Node verwenden, nicht `card*`.
In `settings.ini`:
```ini
[ffmpeg]
hw = vaapi
hw_device = /dev/dri/renderD128
```
#### QSV (Intel Quick Sync): Device meist leer lassen
Im Script wird QSV aktuell so genutzt:
- `-hwaccel qsv`
In den meisten Fällen brauchst du **kein** `hw_device`.
Wenn du später tiefer optimieren willst (z.B. spezielles QSV device), müsste man das Script erweitern.
In `settings.ini`:
```ini
[ffmpeg]
hw = qsv
hw_device =
```
#### CUDA (NVIDIA): Device leer lassen
CUDA/NVDEC benötigt typischerweise kein Device-Argument (Treiber entscheidet).
```ini
[ffmpeg]
hw = cuda
hw_device =
```
#### D3D11VA (Windows): Device leer lassen
Direct3D 11 VA ist ein Windows-API; Device-Auswahl erfolgt automatisch.
```ini
[ffmpeg]
hw = d3d11va
hw_device =
```
---
## Troubleshooting Hardware-Decode
### 1) Erst testen, ob ffmpeg den hwaccel kennt
```bash
ffmpeg -hide_banner -hwaccels
```
Da sollte z.B. `vaapi`, `qsv`, `cuda`, `d3d11va` auftauchen.
### 2) Linux VAAPI: Treiber/Stack
- Intel: `intel-media-driver` (neuere Gen) oder `i965-va-driver` (älter)
- AMD: Mesa VAAPI (`mesa-va-drivers`)
Test:
```bash
vainfo
```
Wenn `vainfo` schon Fehler wirft, wird ffmpeg mit `vaapi` auch zicken.
### 3) NVIDIA CUDA/NVDEC
Wenn `ffmpeg -hwaccels` kein `cuda` zeigt, ist dein ffmpeg-Build evtl. ohne CUDA.
### 4) Wenns instabil ist
Setze erst mal:
```ini
[ffmpeg]
hw = none
```
und prüfe, ob alles stabil durchläuft. Danach wieder mit `hw` testen.
### 5) Mehrere GPUs
- Linux: VAAPI über `renderD128`/`renderD129` zielst du die GPU indirekt an.
- Windows: D3D11VA/CUDA/QSV nutzen i.d.R. automatisch die passende Hardware; explizite Auswahl wäre möglich, ist aber derzeit im Script nicht vorgesehen.