Skip to main content

CLI-Tool zur Konvertierung von DTS/DTS-HD Audiospuren in MKV-Dateien zu E-AC3 (Dolby Digital Plus)

Project description

kinofilm-manager

Python-CLI-Tool zur Konvertierung von DTS/DTS-HD Audiospuren in MKV-Dateien zu E-AC3 (Dolby Digital Plus). Das Ergebnis ist eine neue MKV-Datei, die direkt in Subler importiert und zu M4V/MP4 für Apple TV und Infuse weiterverarbeitet werden kann.

Für Artwork und Fanart wird die TMDB-API (The Movie Database) verwendet.


Hintergrund und Motivation

Das Container-Problem

Der MP4/M4V-Container – der native Container für Apple TV, iTunes und Infuse – unterstützt DTS und DTS-HD nicht. Dies ist eine Einschränkung des Container-Standards: DTS ist im MP4-Standard nicht als zulässiger Audio-Codec spezifiziert.

Wer eine Archivierungs-Pipeline aufbaut, die auf folgenden Komponenten basiert:

MKV (Quellformat) → Subler (Muxing/Metadaten) → M4V (Apple TV / Infuse)

steht vor dem Problem, dass Subler DTS-Spuren aus einem MKV nicht direkt in einen M4V-Container übernehmen kann. Der Workaround wäre ein manuelles Transcodieren in Subler – was aber keine Batch-Fähigkeit bietet und keinen kontrollierten Workflow erlaubt.

Die Lösung: Zweistufiger Workflow

Der Workflow wird sauber in zwei unabhängige Schritte getrennt:

Schritt 1: kinofilm-manager convert
MKV (mit DTS) → MKV (mit E-AC3)

Schritt 2: Subler (manuell oder via SublerCLI)
MKV (mit E-AC3) → M4V (für Apple TV / Infuse)

Dadurch bleibt Subler ein reines Muxing- und Metadaten-Tool und kinofilm-manager übernimmt die Audiokonvertierung deterministisch und reproduzierbar.


Unterstützte Audio-Codecs im M4V-Container

Zur Übersicht welche Audioformate im MP4/M4V-Container zulässig sind:

Codec M4V-kompatibel Bemerkung
AAC Nativ
AC3 (Dolby Digital) Von Apple für M4V zugelassen
E-AC3 (Dolby Digital Plus) Inkl. Atmos-Metadata
DTS Nicht im MP4-Standard
DTS-HD HRA / MA Nicht im MP4-Standard
TrueHD Nicht im MP4-Standard

Voraussetzungen

  • Python 3.11 oder neuer
  • ffmpeg und ffprobe im PATH

Installation ffmpeg auf macOS:

brew install ffmpeg

Hinweis: HandBrake nicht via Homebrew installieren – es überschreibt shared Libraries (z.B. libvpx) und kann zu dyld: Library not loaded-Fehlern bei ffmpeg führen. HandBrake stattdessen als .app via DMG installieren.


Installation

# Via pip
pip install kurmann-kinofilm-manager

# Via uv
uv pip install kurmann-kinofilm-manager

# Für Entwicklung (lokal)
git clone https://github.com/kurmann/kinofilm-manager.git
cd kinofilm-manager
pip install -e ".[dev]"

Verwendung

kinofilm-manager convert <input.mkv> [Optionen]
kinofilm-manager artwork fetch <video-file> [Optionen]
kinofilm-manager movie identify <video-file> [Optionen]

Parameter

Argument Kurz Standard Beschreibung
INPUT_FILE Pfad zur Eingabe-MKV (Pflichtfeld)
--output -o <input>_eac3.mkv Pfad zur Ausgabe-MKV
--bitrate -b automatisch oder config-Wert E-AC3-Bitrate für alle konvertierten Spuren
--dry-run / --no-dry-run false oder config-Wert Zeigt Analyse und FFmpeg-Befehl, erstellt keine Datei
--verbose / --no-verbose -v false oder config-Wert Zusätzliche Diagnoseinformationen auf stderr

Beispiele

# Einfachster Aufruf – Ausgabe landet neben der Quelldatei
kinofilm-manager convert "Film (2024).mkv"

# Ausgabepfad selbst bestimmen
kinofilm-manager convert "Film (2024).mkv" -o "Film (2024)_subler.mkv"

# Erst prüfen was passieren würde (empfohlen beim ersten Test)
kinofilm-manager convert "Film (2024).mkv" --dry-run

# Eigene Bitrate (kleinere Datei, geringfügig weniger Qualität)
kinofilm-manager convert "Film (2024).mkv" --bitrate 448k

# Persistente Defaults für künftige Aufrufe setzen
kinofilm-manager config set bitrate 448k
kinofilm-manager config set verbose true

# Pipeline: Ergebnis-Pfad auf stdout, Diagnose auf stderr
output=$(kinofilm-manager convert "Film (2024).mkv")
echo "Konvertierte Datei: $output"

Artwork / Fanart für Infuse

Für Infuse-kompatibles Fanart kann pro Videodatei ein Backdrop im Format <Titel (Jahr)-fanart.jpg> geladen werden. Die Datei wird immer im gleichen Verzeichnis wie die Videodatei gespeichert.

kinofilm-manager artwork fetch <video-file> [Optionen]

Unterstützte Eingaben

  • Primär: Dateiname im Schema <Titel (Jahr)>[ - Zusatz].m4v, .mkv oder .mp4; Zusätze nach - werden ignoriert
  • Alternativ: --title und --year, falls der Dateiname nicht parsebar ist
  • Direkter Lookup: --tmdb-id, falls ein Film über Titel und Jahr nicht zuverlässig gefunden werden kann

Optionen

Option Standard Beschreibung
--title TEXT aus Dateiname Alternativer Filmtitel
--year INTEGER aus Dateiname Erscheinungsjahr; nur zusammen mit --title
--tmdb-id INTEGER Direkter TMDB-ID-Lookup; umgeht die Titelsuche. Kann nicht zusammen mit --title/--year verwendet werden
--dry-run / --no-dry-run false oder config-Wert Prüft den Workflow ohne Dateiablage
--language TEXT Suchsprache für TMDB, z.B. de-DE oder en-US
--provider TEXT tmdb oder config-Wert Artwork-Provider; aktuell wird nur tmdb unterstützt
--tmdb-api-key TEXT config-Wert TMDB API Key
--interactive / --no-interactive false Erlaubt eine manuelle Auswahl bei mehrdeutigen Treffern

Beispiele

# Fanart direkt neben der Videodatei speichern
kinofilm-manager artwork fetch "Frozen (2013).m4v" --tmdb-api-key "$TMDB_API_KEY"

# Parsebaren Dateinamen überschreiben
kinofilm-manager artwork fetch "film-final.mp4" --title "Frozen" --year 2013 --tmdb-api-key "$TMDB_API_KEY"

# Direkter TMDB-ID-Lookup für hartnäckige Suchfälle
kinofilm-manager artwork fetch "Neues von uns Kindern aus Bullerbü (1987).m4v" --tmdb-id 26111 --tmdb-api-key "$TMDB_API_KEY"

# Mehrdeutige Treffer bewusst interaktiv auswählen
kinofilm-manager artwork fetch "Frozen (2013).m4v" --interactive --tmdb-api-key "$TMDB_API_KEY"

# Workflow testen ohne Dateiablage
kinofilm-manager artwork fetch "Frozen (2013).m4v" --dry-run --tmdb-api-key "$TMDB_API_KEY"

Ausgabe-Konvention für artwork fetch

  • stdout: Zielpfad der Fanart-Datei
  • stderr: Parsing-/Such-Events, Auswahlhinweise, Fehlerdiagnosen
  • Ohne --interactive wird bei mehrdeutigen Treffern mit Exit-Code 1 abgebrochen
  • Mit --dry-run wird der Zielpfad ausgegeben, aber keine Datei geschrieben

Verwendete Dienste

Dienst Verwendung Nutzungsform
TMDB Filmsuche und Backdrop-Download Kostenlos, API-Key erforderlich

Film-Identifikation: movie identify

Mit movie identify wird eine Videodatei so umbenannt, dass die TMDB-ID direkt im Dateinamen eingebettet ist. Das Format [tmdb-<id>] wird von Infuse direkt gelesen und ermöglicht eine zuverlässige Metadaten- und Artwork-Erkennung, ohne dass eine manuelle Zuordnung in Infuse erforderlich ist.

kinofilm-manager movie identify <video-file> [Optionen]

Filmidentifikation via Videometadaten

Vorhandene Metadaten im Videocontainer werden standardmässig bevorzugt für die TMDB-Suche verwendet. Sind in der Datei ein Filmtitel oder ein Erscheinungsjahr hinterlegt (z. B. durch Subler oder andere Werkzeuge), werden diese Informationen gegenüber dem Dateinamen priorisiert. Liefert die Metadaten-basierte Suche keinen Treffer, wird automatisch auf den Dateinamen zurückgefallen.

Das Verhalten lässt sich mit --lookup-source steuern:

  • auto (Standard): Metadaten bevorzugt, Fallback auf Dateiname
  • metadata: nur Metadaten, kein Dateiname-Fallback
  • filename: nur Dateiname (bisheriges Verhalten)

Beispiele

# Datei automatisch identifizieren und TMDB-ID anhängen
kinofilm-manager movie identify 'Wir Kinder aus Bullerbü (1986).m4v' --tmdb-api-key "$TMDB_API_KEY"
# → Wir Kinder aus Bullerbü (1986) [tmdb-21394].m4v

# Direkter Lookup per TMDB-ID (umgeht die Titelsuche)
kinofilm-manager movie identify 'Film (1987).m4v' --tmdb-id 26111 --tmdb-api-key "$TMDB_API_KEY"

# Mehrdeutige Treffer interaktiv auswählen
kinofilm-manager movie identify 'Pippi Langstrumpf (1969).m4v' --interactive --tmdb-api-key "$TMDB_API_KEY"

# Nur Zielpfad anzeigen, nicht umbenennen
kinofilm-manager movie identify 'Film (2000).m4v' --dry-run --tmdb-api-key "$TMDB_API_KEY"

# Nur Dateinamen für die Suche verwenden (Metadaten ignorieren)
kinofilm-manager movie identify 'Film (2000).m4v' --lookup-source filename --tmdb-api-key "$TMDB_API_KEY"

Wenn bereits ein [tmdb-xxxx]-Suffix im Dateinamen vorhanden ist, wird er ersetzt, nicht doppelt angehängt.

Optionen

Option Standard Beschreibung
--title TEXT aus Dateiname Alternativer Filmtitel
--year INTEGER aus Dateiname Erscheinungsjahr; nur zusammen mit --title
--tmdb-id INTEGER Direkter TMDB-ID-Lookup; umgeht die Titelsuche. Kann nicht zusammen mit --title/--year verwendet werden
--lookup-source TEXT auto Quelle für die Filmidentifikation: auto (Metadaten bevorzugt, dann Dateiname), metadata (nur Metadaten) oder filename (nur Dateiname)
--dry-run / --no-dry-run false oder config-Wert Zeigt Zielpfad, benennt aber nicht um
--language TEXT Suchsprache für TMDB, z.B. de-DE oder en-US
--provider TEXT tmdb oder config-Wert Provider; aktuell wird nur tmdb unterstützt
--tmdb-api-key TEXT config-Wert TMDB API Key
--interactive / --no-interactive false Erlaubt eine manuelle Auswahl bei mehrdeutigen Treffern

Ausgabe-Konvention für movie identify

  • stdout: Neuer Dateipfad nach der Umbenennung
  • stderr: Such-Events, Auswahlhinweise, Fehlerdiagnosen
  • Ohne --interactive wird bei mehrdeutigen Treffern mit Exit-Code 1 abgebrochen
  • Mit --dry-run wird der Zielpfad ausgegeben, aber die Datei nicht umbenannt

Persistente Konfiguration

Persistente CLI-Defaults werden XDG-konform in ~/.config/kinofilm-manager/config.toml gespeichert. Falls XDG_CONFIG_HOME gesetzt ist, wird stattdessen $XDG_CONFIG_HOME/kinofilm-manager/config.toml verwendet.

Unterstützte Konfigurationsschlüssel

Schlüssel Typ Beschreibung
bitrate String Default für --bitrate, z.B. 448k oder 640k
dry_run Boolean Default für --dry-run / --no-dry-run
verbose Boolean Default für --verbose / --no-verbose
artwork_provider String Default für artwork fetch --provider (tmdb)
tmdb_api_key String Default für artwork fetch --tmdb-api-key

CLI-Befehle

# Alle unterstützten Schlüssel und aktuelle Werte anzeigen
kinofilm-manager config list

# Einzelnen Wert setzen
kinofilm-manager config set bitrate 448k
kinofilm-manager config set dry_run false
kinofilm-manager config set artwork_provider tmdb
kinofilm-manager config set tmdb_api_key "<API_KEY>"

# Einzelnen Wert lesen
kinofilm-manager config get bitrate

Beispiel-Konfiguration

bitrate = "448k"
dry_run = false
verbose = true
artwork_provider = "tmdb"
tmdb_api_key = "your-key"

CLI-Optionen überschreiben persistierte Defaults immer explizit pro Aufruf. Die Bibliotheks-API liest keine globale Konfiguration; technische Laufzeitoptionen werden explizit als RuntimeOptions übergeben.

Ausgabekonvention

Gemäss den Architekturprinzipien gilt:

  • stdout: Ergebnis-Pfad der konvertierten Datei (pipeline-freundlich)
  • stderr: Stream-Analyse, Fortschritt, Warnungen (Rich-formatiert)
  • --verbose: Zusätzliche Diagnoseinformationen (FFmpeg-Befehl) auf stderr

API-Nutzung

kinofilm-manager kann auch als Python-Bibliothek verwendet werden:

from pathlib import Path
from kinofilm_manager.api import ConvertRequest, RuntimeOptions, convert

request = ConvertRequest(
    input_path=Path("Film.mkv"),
)
runtime_options = RuntimeOptions(
    dry_run=True,
    bitrate="640k",
)
result = convert(request, runtime_options=runtime_options)

if result.success:
    print(f"Konvertiert: {result.converted_count} Spuren")
    for stream in result.streams:
        print(f"  #{stream.index}: {stream.codec_name}{stream.action}")

Event-Callbacks

Für lang laufende Konvertierungen können strukturierte Fortschrittsereignisse und FFmpeg-Textausgabe abonniert werden:

from kinofilm_manager.api import ConvertEvent, ConvertRequest, RuntimeOptions, convert

def on_event(event: ConvertEvent) -> None:
    print(f"[{event.stage_id}] {event.message}")

def on_output(line: str) -> None:
    print(f"  ffmpeg: {line}")

result = convert(
    ConvertRequest(input_path=Path("Film.mkv")),
    on_event=on_event,
    on_output=on_output,
)

Stabile stage_id-Werte: analyse_start, analyse_done, konvertierung_start, konvertierung_done.

Laufzeitoptionen und Konfiguration

ConvertRequest beschreibt nur den fachlichen Auftrag (input_path, optional output_path). Technische Laufzeitoptionen wie Bitrate, Dry-Run oder Pfade zu externen Werkzeugen werden getrennt über RuntimeOptions übergeben. Die CLI liest dafür auf Wunsch persistente Defaults aus der XDG-Konfiguration und reicht sie explizit an die API weiter.

runtime_options = RuntimeOptions(
    bitrate="1536k",
    dry_run=False,
    ffmpeg_path="/opt/homebrew/bin/ffmpeg",   # Standard: Auflösung via PATH
    ffprobe_path="/opt/homebrew/bin/ffprobe",
)

Fachlogik

1. DTS-Erkennung

DTS-Spuren werden über codec_name und profile aus den ffprobe-Metadaten erkannt:

  • dts (DTS Core)
  • dts-hd / dtshd
  • Profile wie DTS-HD HRA, DTS-HD MA

2. Duplikat-Erkennung: DTS überspringen wenn E-AC3/AC3 mit gleicher Kanalanzahl vorhanden

Viele MKV-Dateien enthalten bereits mehrere Audiospuren pro Sprache. Eine DTS-Spur wird nur dann übersprungen, wenn bereits eine E-AC3- oder AC3-Spur gleicher Sprache und mindestens gleicher Kanalanzahl vorhanden ist.

Eine vorhandene E-AC3 Stereo (2.0) Spur ist kein Ersatz für eine DTS 5.1 Spur – der Mehrkanal-Surround-Ton würde verloren gehen. Ebenso ist eine E-AC3 5.1-Spur kein Ersatz für eine DTS 7.1-Spur – da E-AC3 nativ 7.1 unterstützt, wird DTS 7.1 erst übersprungen, wenn bereits E-AC3 7.1 gleicher Sprache vorhanden ist.

3. Zielformat: E-AC3 (Dolby Digital Plus)

E-AC3 (Dolby Digital Plus) unterstützt nativ bis zu 7.1 (8 Kanäle) – ein 7.1→5.1 Downmix ist nicht mehr nötig. Die Kanalanzahl der Quelle wird direkt übernommen:

Quell-Kanalanzahl Zielformat Automatische Bitrate
Mono (1ch) E-AC3 Mono 192k
Stereo (2ch) E-AC3 Stereo 192k
5.1 (6ch) E-AC3 5.1 640k
7.1 (8ch) E-AC3 7.1 1536k

Für andere Kanalanzahlen wird die Default-Bitrate von 640k verwendet.

4. Tonversatz (Audio Delay)

MKV-Dateien können pro Spur einen start_time-Wert enthalten. FFmpeg erhält -avoid_negative_ts make_zero für korrekte Übertragung.

5. Stream-Metadaten

Alle Stream-Metadaten (Sprache, Titel) werden explizit pro Stream übertragen. Für konvertierte DTS-Spuren wird der Titel automatisch neu generiert (z.B. E-AC3 7.1 (von DTS-HD MA 7.1)).

6. Untertitel-Kompatibilität

Inkompatible Untertitel-Streams (z.B. dvd_subtitle) werden erkannt und weggelassen. MKV-kompatible Formate (SRT, ASS, PGS, etc.) werden unverändert kopiert.

PGS-Untertitel und OCR: Blu-ray PGS-Untertitel werden als Bitmap ins MKV kopiert. Eine integrierte OCR-Lösung wurde evaluiert, wird aber bewusst nicht umgesetzt. Das Tool bleibt im Scope der Audio-Konvertierung. Subler übernimmt im nachgelagerten Schritt die OCR-Konvertierung der PGS-Untertitel beim Muxing zu M4V – mit guter Qualität.


Bekannte Einschränkungen

  • DVD-Untertitel werden weggelassen. Workaround: In Subler als Bitmap importieren.
  • Qualitätsverlust – DTS→E-AC3 ist verlustbehaftet. Für audiophile Ansprüche bleibt MKV mit DTS-HD das bessere Archivformat.

Weiterführender Workflow

Nach der Konvertierung empfiehlt sich folgender Workflow in Subler:

  1. Konvertierte MKV in Subler öffnen
  2. Gewünschte Spuren auswählen (typisch: eine Audiospur pro Sprache)
  3. PGS-Untertitel via Sublers integrierte OCR zu Text konvertieren (falls vorhanden)
  4. Metadaten ergänzen (Titel, Jahr, Beschreibung, Artwork)
  5. Als M4V exportieren

Änderungsverlauf

[2.3.0] – 2026-03-19

  • Ziel-Audiocodec: DTS/DTS-HD → E-AC3 (Dolby Digital Plus) statt AC3
  • DTS 7.1 → E-AC3 7.1 direkt (kein Downmix mehr); DTS 5.1 → E-AC3 5.1
  • Neue Bitrate für 7.1: 1536k; Duplikat-Erkennung für 7.1 angepasst
  • Event-Callbacks (on_event, on_output) in convert()
  • ffmpeg_path/ffprobe_path in RuntimeOptions für explizite Tool-Pfade
  • Standardmässiger Ausgabedateiname: <input>_eac3.mkv

[2.2.0] – 2026-03-19

  • Neuer Befehl movie identify: identifiziert einen Film via TMDB und ergänzt [tmdb-<id>] im Dateinamen
  • Neues Modul movie_search mit wiederverwendbarer Film-Such- und Auswahllogik
  • artwork fetch --tmdb-id: direkter TMDB-ID-Lookup ohne Titelsuche

[2.1.1] – 2026-03-18

  • Fallback-Suche ohne Jahr, wenn Suche mit Jahr keinen Treffer liefert
  • Fallback-Suche ohne Untertitel bei fehlendem Treffer
  • Ausgabedateiname basiert auf originalem Input-Stem

[2.1.0] – 2026-03-18

  • Neues Subcommand kinofilm-manager config mit set, get und list
  • Persistente XDG-Konfiguration unter ~/.config/kinofilm-manager/config.toml
  • RuntimeOptions trennt CLI-Laufzeitoptionen von ConvertRequest

Vollständiger Änderungsverlauf: CHANGELOG.md


Lizenz

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kurmann_kinofilm_manager-2.3.0.tar.gz (46.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kurmann_kinofilm_manager-2.3.0-py3-none-any.whl (34.2 kB view details)

Uploaded Python 3

File details

Details for the file kurmann_kinofilm_manager-2.3.0.tar.gz.

File metadata

  • Download URL: kurmann_kinofilm_manager-2.3.0.tar.gz
  • Upload date:
  • Size: 46.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for kurmann_kinofilm_manager-2.3.0.tar.gz
Algorithm Hash digest
SHA256 a6389dc5bb3e90f4520307222233163e17ab1b26d69a187f1bc54a2d698c096c
MD5 06c12bdde0591eb1427778e73be7e5e0
BLAKE2b-256 2e871a1d64b6a01b676291ce2303eff3483a074611c3a696df242de90b67316d

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_kinofilm_manager-2.3.0.tar.gz:

Publisher: publish.yml on kurmann/kinofilm-manager

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kurmann_kinofilm_manager-2.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for kurmann_kinofilm_manager-2.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9a9f28075e0a15f53db65df3a1ab440d13e77f7e12ff1ba29d5d438e0effd246
MD5 c234876598ac86e6d0d15d753d9e3c1c
BLAKE2b-256 04e51251341e682df4d0833e92f4b0f947eba1016fe4fe66bf836e7b994bb78a

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_kinofilm_manager-2.3.0-py3-none-any.whl:

Publisher: publish.yml on kurmann/kinofilm-manager

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page