Skip to main content

CLI-Tool zur Konvertierung von DTS/DTS-HD Audiospuren in MKV-Dateien zu AC3

Project description

kinofilm-manager

Python-CLI-Tool zur Konvertierung von DTS/DTS-HD Audiospuren in MKV-Dateien zu Dolby Digital AC3. 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 AC3)

Schritt 2: Subler (manuell oder via SublerCLI)
MKV (mit 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>_ac3.mkv Pfad zur Ausgabe-MKV
--bitrate -b automatisch oder config-Wert 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]

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"

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
--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="448k",
)
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}")

Laufzeitoptionen und Konfiguration

ConvertRequest beschreibt nur den fachlichen Auftrag (input_path, optional output_path). Technische Laufzeitoptionen wie Bitrate oder Dry-Run 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.


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 AC3 mit gleicher Kanalanzahl vorhanden

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

Eine vorhandene AC3 Stereo (2.0) Spur ist kein Ersatz für eine DTS 5.1 Spur – der Mehrkanal-Surround-Ton würde verloren gehen.

3. Kanalanzahl und Bitrate

AC3 (Dolby Digital) unterstützt maximal 5.1 (6 Kanäle). Die Bitrate wird automatisch je nach Kanalanzahl gewählt:

Kanäle Automatische Bitrate
Mono / Stereo 192k
5.1 640k
7.1 (vor Downmix) 640k

4. 7.1 → 5.1 Downmix via pan-Filter

DTS-HD 7.1 wird via FFmpeg pan-Filter auf 5.1 downgemischt. Seitenkanäle (SL/SR) werden auf die Rear-Kanäle (BL/BR) überlagert mit Faktor 0.7 zur Clipping-Vermeidung. Frontkanäle bleiben unverändert.

5. 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.

6. Stream-Metadaten

Alle Stream-Metadaten (Sprache, Titel) werden explizit pro Stream übertragen. Für konvertierte DTS-Spuren wird der Titel automatisch neu generiert.

7. 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.
  • AC3-Maximum ist 5.1 – 7.1-Material wird immer auf 5.1 downgemischt.
  • Qualitätsverlust – DTS→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.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.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

[2.0.0] – 2026-03-12

  • ⚠️ Breaking Change: Neuer CLI-Aufruf kinofilm-manager convert statt python3 mkv_dts_to_ac3.py
  • Restrukturierung als PyPI-Paket kurmann-kinofilm-manager
  • CLI mit typer und rich, Ergebnisse auf stdout, Diagnose auf stderr
  • Request/Result-API für programmatische Nutzung

[1.0.0] – 2026-03-12

  • Erstveröffentlichung als einzelnes Script

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.2.0.tar.gz (39.5 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.2.0-py3-none-any.whl (30.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kurmann_kinofilm_manager-2.2.0.tar.gz
  • Upload date:
  • Size: 39.5 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.2.0.tar.gz
Algorithm Hash digest
SHA256 8cb2edf0eba9966ff2aae5d84c5b7e5ab0045a05e78477fc1fe51049515e5cac
MD5 c707bd5c4e6d394d282caeb30c3ae62e
BLAKE2b-256 7c3a232203836062c5c665871a901ce08b3d647fdc5057a48ad1264a96d972a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_kinofilm_manager-2.2.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.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for kurmann_kinofilm_manager-2.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31f1de39b8285e52586f197e54314ac007801fb933a0d1a1c6622ac8c376e919
MD5 05d88416534c2e4252401d9e1b636903
BLAKE2b-256 224c7ab780567f781f80ac8f0323d23a27b004eaf68ea2e14985acdb7c0b5397

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_kinofilm_manager-2.2.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