|
|
||
|---|---|---|
| android-app | ||
| docs/superpowers | ||
| tizen-app | ||
| video-konverter | ||
| .dockerignore | ||
| .gitignore | ||
| CHANGELOG.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| entrypoint.sh | ||
| README.md | ||
| requirements.txt | ||
| tools.yaml | ||
VideoKonverter
Web-basierter Video-Konverter mit GPU-Beschleunigung (Intel VAAPI), Video-Bibliotheksverwaltung und TVDB-Integration. Laeuft als Docker-Container auf Unraid oder lokal.
Features
Video-Konvertierung
- GPU-Encoding: Intel VAAPI (AV1, AV1 10-Bit, HEVC, H.264) ueber Intel A380
- CPU-Encoding: SVT-AV1, x265, x264 als Fallback
- AV1 10-Bit Standard: Bessere Qualitaet bei gleichem Speed (p010 Pixel-Format)
- Konfigurierbare Presets: 7 Presets (4x GPU + 3x CPU)
- Parallele Jobs: Mehrere Videos gleichzeitig konvertieren
- Audio-Handling: Alle Spuren behalten (DE+EN), kein Downmix, Opus-Transcoding
- Live-Fortschritt: WebSocket-basierte Echtzeit-Updates im Dashboard
- Queue-Management: Drag-and-Drop, Pause, Abbruch, Prioritaeten
Video-Player
- Browser-Streaming: Direktes Abspielen mit ffmpeg-Transcoding (EAC3/DTS/AC3 -> AAC)
- Play-Buttons: In Serien-, Film- und Ordner-Ansichten
- Delete-Buttons: Einzelne Videos loeschen (DB + Datei)
Video-Bibliothek
- Ordner-Scan: Konfigurierbare Scan-Pfade fuer Serien und Filme
- Serien-Erkennung: Automatisch via Ordnerstruktur (
S01E01,1x02,Staffel/Season XX) - Doppel-Episoden: Erkennung von Multi-Episoden-Dateien (
S01E01E02,S01E01-E02,1x01-02) - Episoden-Titel: Automatische Extraktion aus Dateinamen (ohne Qualitaets-Tags)
- Film-Erkennung: Ein Video pro Ordner = Film, Ordnername als Filmtitel
- ffprobe-Analyse: Codec, Aufloesung, Bitrate, Audio-Spuren, Untertitel, HDR/10-Bit
- TVDB-Integration: Serien + Filme, Poster, Episoden-Titel, fehlende Episoden
- TVDB Review-Modal: Vorschlaege pruefen statt blindem Auto-Match, manuelle Suche
- TVDB-Sprachkonfiguration: Metadaten in Deutsch, Englisch oder anderen Sprachen
- Schnellfilter: Vordefinierte Filter (Nicht konvertiert, Alte Formate, Fehlende Episoden)
- Filter-Presets: Eigene Filter speichern und als Standard setzen
- Fehlende Episoden: Uebersicht aller fehlenden Episoden ueber alle Serien
- Filter: Video-Codec, Aufloesung, Container, Audio-Sprache, Kanaele, 10-Bit
- Duplikat-Finder: Gleiche Episode in verschiedenen Formaten erkennen
- Import-Service: Videos einsortieren mit Serien-Erkennung und TVDB-Lookup
- Clean-Service: Nicht-Video-Dateien (NFO, JPG, SRT etc.) finden und entfernen
- Direkt-Konvertierung: Videos aus der Bibliothek direkt in die Queue senden
Administration
- Web-UI: Responsive Dashboard, Bibliothek, Einstellungen, Statistik
- Settings: Encoding-Modus, Ziel-Container, Audio-/Untertitel-Sprachen, Cleanup
- TVDB-Verwaltung: API-Key/PIN konfigurieren, Sprache waehlen, Serien + Filme zuordnen
- Scan-Pfad-Management: Pfade hinzufuegen/loeschen/scannen ueber Admin-UI
- Statistik: Konvertierungs-Historie mit Groessen-Ersparnis, Dauer, Codec-Verteilung
Architektur
┌────────────────────────────────────────────────────┐
│ Browser (Dashboard / Bibliothek / Admin / Stats) │
├──────────────┬──────────────┬──────────────────────┤
│ HTMX/JS │ WebSocket │ REST API │
├──────────────┴──────────────┴──────────────────────┤
│ aiohttp Server │
│ ┌──────────┐ ┌────────────┐ ┌──────────────────┐ │
│ │ Queue │ │ Encoder │ │ LibraryService │ │
│ │ Service │ │ Service │ │ (Scan, Filter, │ │
│ │ │ │ (ffmpeg) │ │ Serien + Filme) │ │
│ ├──────────┤ ├────────────┤ ├──────────────────┤ │
│ │ Scanner │ │ Probe │ │ TVDBService │ │
│ │ Service │ │ Service │ │ (API v4, i18n) │ │
│ ├──────────┤ │ (ffprobe) │ ├──────────────────┤ │
│ │ Importer │ └────────────┘ │ CleanerService │ │
│ │ Service │ │ (Junk-Scan) │ │
│ └──────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────┤
│ MariaDB (statistics, library_*, tvdb_episode_cache)│
└─────────────────────────────────────────────────────┘
Technologie-Stack
| Komponente | Technologie |
|---|---|
| Backend | Python 3.12, aiohttp (async) |
| Templates | Jinja2 + HTMX |
| Datenbank | MariaDB (aiomysql) |
| Video | FFmpeg + FFprobe |
| GPU | Intel VAAPI (iHD-Treiber) |
| Metadaten | TVDB API v4 (tvdb-v4-official) |
| Container | Docker (Ubuntu 24.04) |
| Echtzeit | WebSocket |
Projektstruktur
video-konverter/
├── __main__.py # Einstiegspunkt
├── Dockerfile # Ubuntu 24.04 + ffmpeg + Intel GPU
├── entrypoint.sh # Default-Configs in Volumes kopieren
├── docker-compose.yml # GPU + CPU Profile
├── requirements.txt # Python-Abhaengigkeiten
├── unraid/
│ └── my-VideoKonverter.xml # Unraid Docker-Template
├── app/
│ ├── server.py # Haupt-Server (aiohttp Application)
│ ├── config.py # Settings + Presets laden
│ ├── cfg/
│ │ ├── settings.yaml # Laufzeit-Einstellungen
│ │ └── presets.yaml # Encoding-Presets (7 Stueck)
│ ├── models/
│ │ ├── media.py # MediaFile, VideoStream, AudioStream
│ │ └── job.py # ConvertJob, JobStatus
│ ├── services/
│ │ ├── library.py # Bibliothek: Scan, Filter, Duplikate (1747 Z.)
│ │ ├── tvdb.py # TVDB: Auth, Suche, Episoden, Sprache (1005 Z.)
│ │ ├── importer.py # Import: Erkennung, TVDB-Lookup, Kopieren (734 Z.)
│ │ ├── cleaner.py # Clean: Junk-Scan, Nicht-Video-Dateien (155 Z.)
│ │ ├── queue.py # Job-Queue mit MariaDB-Persistierung (541 Z.)
│ │ ├── encoder.py # FFmpeg-Wrapper (GPU + CPU)
│ │ ├── probe.py # FFprobe-Analyse
│ │ ├── scanner.py # Dateisystem-Scanner
│ │ └── progress.py # Encoding-Fortschritt parsen
│ ├── routes/
│ │ ├── api.py # REST API (Queue, Jobs, Convert)
│ │ ├── library_api.py # REST API (Bibliothek, TVDB, Scan) (998 Z.)
│ │ ├── pages.py # HTML-Seiten (Dashboard, Admin, etc.)
│ │ └── ws.py # WebSocket-Manager
│ ├── templates/
│ │ ├── base.html # Basis-Layout mit Navigation
│ │ ├── dashboard.html # Queue + aktive Jobs
│ │ ├── library.html # Bibliothek mit Filtern
│ │ ├── admin.html # Einstellungen + TVDB + Scan-Pfade
│ │ ├── statistics.html # Konvertierungs-Statistik
│ │ └── partials/
│ │ └── stats_table.html
│ └── static/
│ ├── css/style.css # Komplettes Styling (1554 Z.)
│ └── js/
│ ├── library.js # Bibliothek-UI (1912 Z.)
│ ├── websocket.js # WebSocket-Client
│ └── filebrowser.js # Datei-Browser
├── data/ # Queue-Persistierung
├── logs/ # Server-Logs
└── testmedia/ # Test-Dateien
Installation
Voraussetzungen
- Docker + Docker Compose
- MariaDB-Server (extern, z.B. auf Unraid)
- Optional: Intel GPU fuer Hardware-Encoding (Intel A380 empfohlen)
MariaDB einrichten
CREATE DATABASE video_converter CHARACTER SET utf8mb4;
CREATE USER 'video'@'%' IDENTIFIED BY 'dein_passwort';
GRANT ALL PRIVILEGES ON video_converter.* TO 'video'@'%';
FLUSH PRIVILEGES;
Die Tabellen werden automatisch beim ersten Start erstellt.
Unraid-Installation
- Docker-Image laden (Unraid Web-Terminal):
docker load -i /mnt/user/downloads/videokonverter-cpu.tar
- XML-Template kopieren:
cp /mnt/user/downloads/my-VideoKonverter.xml /boot/config/plugins/dockerMan/templates-user/
- In der Unraid Docker-WebGUI: "Container hinzufuegen" → Template waehlen → Werte anpassen → Starten
Das Template enthält alle Variablen mit korrekten Defaults.
Konfiguration
Alle Einstellungen sind per Umgebungsvariablen (VK_*) konfigurierbar.
ENV-Variablen ueberschreiben immer die settings.yaml.
| Variable | Default | Beschreibung |
|---|---|---|
VK_DB_HOST |
192.168.155.11 |
MariaDB Host |
VK_DB_PORT |
3306 |
MariaDB Port |
VK_DB_USER |
video |
MariaDB Benutzer |
VK_DB_PASSWORD |
- | MariaDB Passwort |
VK_DB_NAME |
video_converter |
Datenbank-Name |
VK_MODE |
cpu |
Encoding-Modus: gpu, cpu, auto |
VK_GPU_DEVICE |
/dev/dri/renderD129 |
GPU Render-Device |
VK_DEFAULT_PRESET |
gpu_av1_10bit |
Standard Encoding-Preset |
VK_MAX_JOBS |
1 |
Max. parallele Jobs |
VK_TVDB_API_KEY |
- | TVDB API Key |
VK_TVDB_LANGUAGE |
deu |
TVDB Sprache |
VK_LOG_LEVEL |
INFO |
Log-Level |
Alternativ kann app/cfg/settings.yaml direkt bearbeitet werden.
Bei Erstinstallation werden Default-Konfigdateien automatisch ins cfg-Volume kopiert.
GPU-Device ermitteln
Auf dem Host pruefen welches renderD* die Intel GPU ist:
cat /sys/class/drm/renderD*/device/uevent | grep -B1 DRIVER
Beispiel: renderD128 = AMD, renderD129 = Intel → VK_GPU_DEVICE=/dev/dri/renderD129
Starten
GPU-Modus (Produktion auf Unraid):
docker compose --profile gpu up --build -d
CPU-Modus (lokal testen):
PUID=1000 PGID=1000 docker compose --profile cpu up --build -d
Web-UI: http://localhost:8080
Encoding-Presets
| Preset | Codec | Container | Qualitaet | Modus |
|---|---|---|---|---|
| GPU AV1 | av1_vaapi | WebM | QP 30 | GPU |
| GPU AV1 10-Bit | av1_vaapi | WebM | QP 30 | GPU |
| GPU HEVC | hevc_vaapi | MKV | QP 28 | GPU |
| GPU H.264 | h264_vaapi | MP4 | QP 23 | GPU |
| CPU AV1/SVT | libsvtav1 | WebM | CRF 30 | CPU |
| CPU HEVC/x265 | libx265 | MKV | CRF 28 | CPU |
| CPU H.264/x264 | libx264 | MP4 | CRF 23 | CPU |
API Referenz
Konvertierung
| Methode | Pfad | Beschreibung |
|---|---|---|
| POST | /api/convert |
Dateien/Ordner zur Queue hinzufuegen |
| GET | /api/queue |
Queue-Status abrufen |
| DELETE | /api/jobs/{id} |
Job entfernen/abbrechen |
Bibliothek
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /api/library/paths |
Scan-Pfade auflisten |
| POST | /api/library/paths |
Scan-Pfad hinzufuegen |
| DELETE | /api/library/paths/{id} |
Scan-Pfad loeschen |
| POST | /api/library/scan |
Alle Pfade scannen |
| POST | /api/library/scan/{id} |
Einzelnen Pfad scannen |
| GET | /api/library/scan-status |
Scan-Fortschritt |
| GET | /api/library/videos |
Videos filtern (siehe Filter-Params) |
| GET | /api/library/series |
Alle Serien |
| GET | /api/library/series/{id} |
Serie mit Episoden |
| GET | /api/library/series/{id}/missing |
Fehlende Episoden einer Serie |
| GET | /api/library/missing-episodes |
Alle fehlenden Episoden (paginated) |
| GET | /api/library/filter-presets |
Filter-Presets laden |
| POST | /api/library/filter-presets |
Neues Preset speichern |
| PUT | /api/library/filter-presets |
Presets aktualisieren |
| DELETE | /api/library/filter-presets/{id} |
Preset loeschen |
| PUT | /api/library/default-view |
Standard-Ansicht setzen |
| POST | /api/library/series/{id}/tvdb-match |
TVDB-ID zuordnen |
| POST | /api/library/series/{id}/convert |
Alle Episoden konvertieren |
| GET | /api/library/series/{id}/convert-status |
Codec-Status der Serie |
| POST | /api/library/series/{id}/cleanup |
Alte Dateien loeschen |
| GET | /api/library/duplicates |
Duplikate finden |
| POST | /api/library/videos/{id}/convert |
Direkt konvertieren |
| POST | /api/library/delete-folder |
Ordner komplett loeschen |
| GET | /api/library/stats |
Bibliotheks-Statistiken |
| GET | /api/library/movies |
Filme auflisten |
| POST | /api/library/movies/{id}/tvdb-match |
Film-TVDB-Zuordnung |
| POST | /api/library/tvdb-auto-match |
Review-Vorschlaege sammeln |
| POST | /api/library/tvdb-confirm |
TVDB-Match bestaetigen |
| POST | /api/library/tvdb-refresh-episodes |
Episoden-Cache aktualisieren |
| GET | /api/tvdb/search?q= |
TVDB-Suche |
| GET | /api/tvdb/language |
TVDB-Sprache lesen |
| PUT | /api/tvdb/language |
TVDB-Sprache aendern |
Streaming
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /api/library/videos/{id}/stream |
Video-Transcoding-Stream (ffmpeg pipe) |
| DELETE | /api/library/videos/{id} |
Video loeschen (DB + Datei) |
Import
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /api/library/import |
Alle Import-Jobs auflisten |
| POST | /api/library/import |
Neuen Import-Job erstellen |
| GET | /api/library/import/{id} |
Import-Job Status mit Items |
| POST | /api/library/import/{id}/analyze |
Import analysieren |
| POST | /api/library/import/{id}/execute |
Import ausfuehren |
| POST | /api/library/import/{id}/assign |
Item manuell zuordnen |
| POST | /api/library/import/{id}/skip |
Item ueberspringen |
System
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /api/logs |
Server-Logs abrufen |
| GET | /api/system |
System-Info (GPU, Jobs) |
Video-Filter (/api/library/videos)
?video_codec=hevc # h264, hevc, av1, mpeg4
&min_width=1920 # Mindest-Aufloesung
&container=mkv # mkv, mp4, avi, webm
&audio_lang=ger # Audio-Sprache
&audio_channels=6 # Kanal-Anzahl (2=Stereo, 6=5.1)
&is_10bit=1 # Nur 10-Bit
¬_converted=1 # Nicht im Zielformat (Container + Codec)
&exclude_codec=av1 # Codec ausschliessen
&exclude_container=webm # Container ausschliessen
&search=breaking # Dateiname-Suche
&sort=file_size # Sortierung
&order=desc # asc | desc
&page=1&limit=50 # Pagination
Datenbank-Schema
library_paths
Konfigurierte Scan-Pfade fuer Serien- und Film-Ordner.
library_series
Erkannte Serien mit optionaler TVDB-Verknuepfung (Poster, Beschreibung, Episoden-Zaehler).
library_movies
Erkannte Filme mit optionaler TVDB-Verknuepfung (Poster, Beschreibung, Jahr).
library_videos
Jedes Video mit vollstaendigen ffprobe-Metadaten:
- Video: Codec, Aufloesung, Framerate, Bitrate, 10-Bit, HDR
- Audio: JSON-Array mit Spuren (
[{"codec":"eac3","lang":"ger","channels":6,"bitrate":256000}]) - Untertitel: JSON-Array (
[{"codec":"subrip","lang":"ger"}]) - Serien: Staffel/Episode-Nummer, episode_end (fuer Doppel-Episoden), Episoden-Titel
tvdb_episode_cache
Zwischenspeicher fuer TVDB-Episodendaten (Serie, Staffel, Episode, Name, Ausstrahlung).
Docker Volumes
| Volume (Host) | Container-Pfad | Beschreibung |
|---|---|---|
./app/cfg (lokal) / /mnt/user/appdata/videokonverter/cfg (Unraid) |
/opt/video-konverter/app/cfg |
Konfiguration (persistent, Defaults werden automatisch kopiert) |
./data (lokal) / /mnt/user/appdata/videokonverter/data (Unraid) |
/opt/video-konverter/data |
Queue-Persistierung |
./logs (lokal) / /mnt/user/appdata/videokonverter/logs (Unraid) |
/opt/video-konverter/logs |
Server-Logs |
/mnt (lokal) / /mnt/user (Unraid) |
/mnt |
Medien-Pfade |
/dev/dri |
/dev/dri |
GPU-Devices (fuer VAAPI) |
Lizenz
Privates Projekt von Eddy (Eduard Wisch).