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]

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)>.m4v, .mkv oder .mp4
  • Alternativ: --title und --year, falls der Dateiname nicht parsebar ist

Optionen

Option Standard Beschreibung
--title TEXT aus Dateiname Alternativer Filmtitel
--year INTEGER aus Dateiname Erscheinungsjahr; nur zusammen mit --title
--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"

# 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

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.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.1.0.tar.gz (30.0 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.1.0-py3-none-any.whl (25.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kurmann_kinofilm_manager-2.1.0.tar.gz
  • Upload date:
  • Size: 30.0 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.1.0.tar.gz
Algorithm Hash digest
SHA256 122050a292f17de77e9345a34b4df5b49ffe4090d0505f0a4c73c26d31c93be1
MD5 82b3e2504b962b6149f48d18b2fda472
BLAKE2b-256 3b3b060e6569ca2e38b43532401bf31e14421b92e62a9832fd475ad194633965

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for kurmann_kinofilm_manager-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 81449cb4abcc7c62682e0b1379bda93d96f952ba11696c6eb8e0836b94280fbc
MD5 a80da0bbe2acd56c2485fd914b930f90
BLAKE2b-256 5931e9c9fcfc17fc789178e4ed2b228c43887b0016523300e794eae45eb90dca

See more details on using hashes here.

Provenance

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