Skip to main content

CLI-Tool zur Erstellung von Mediensets (statisches HTML mit OG-Tags, Vorschaubildern und ZIP-Download) aus Videodateien.

Project description

mediaset-creator

CLI-Tool und Python-Bibliothek zur Erstellung von Mediensets aus Videodateien. Ein Medienset repräsentiert genau ein Video und kann als Infuse-Medienset (Original-Video + Artworks + Metadaten) und/oder Web-Medienset (HTML-Seite + komprimiertes Video + ZIP) in separate Verzeichnisse ausgegeben werden.


Voraussetzungen


Installation

uv pip install kurmann-mediaset-creator

Im Entwicklungsmodus (editierbar):

uv sync

Konzept: Profile

Ein Medienset kann in zwei Profilen ausgegeben werden:

Profil Zweck Inhalt
Infuse Medienserver (Infuse/Firecore) Original-Video, Landscape (-fanart), Portrait (-poster), NFO
Web Streaming via Hidden Link HTML-Seite, komprimiertes Video, Landscape, optional ZIP

Jedes Profil schreibt in ein eigenes Verzeichnis. Beide Profile sind unabhängig aktivierbar – mindestens eines muss angegeben werden.

Ausgabestruktur

infuse_dir/                              web_dir/{ULID}/
├── Leah Treppen-Surfen.m4v              ├── index.html
├── Leah Treppen-Surfen-fanart.jpg       ├── leah-treppen-surfen.jpg
├── Leah Treppen-Surfen-poster.jpg       ├── leah-treppen-surfen.mp4  (komprimiert)
└── Leah Treppen-Surfen.nfo              └── leah-treppen-surfen.zip  (optional)
  • Infuse: Dateien mit Original-Dateinamen (inkl. Umlaute, Leerzeichen)
  • Web: Dateien mit sanitisierten ASCII-Dateinamen, ULID-Unterverzeichnis für Hidden Links

Verwendung (CLI)

# Einfachster Aufruf – Web-Medienset im Quellverzeichnis
mediaset-creator create /pfad/zu/video.m4v \
  --title "Leah Treppen-Surfen" \
  --date "2024-07-01"

# Mit expliziten Profilen
mediaset-creator create /pfad/zu/video.m4v \
  --title "Leah Treppen-Surfen" \
  --category "Familie Kurmann-Glück" \
  --date "2024-07-01" \
  --quality "Dolby Vision" \
  --infuse-dir /nas/infuse/familienfilme \
  --web-dir /nas/shares

Ohne --infuse-dir oder --web-dir wird automatisch ein Web-Medienset im Verzeichnis der Quelldatei erstellt (ULID-Unterordner).

Optionen

Option Profil Beschreibung
VIDEO (Argument) Pflicht Pfad zur Videodatei
--title TEXT Gemeinsam Titel des Videos (auch H1-Überschrift). Fallback: Dateiname.
--mediaset-title TEXT Gemeinsam Optionaler H1-Titel, falls abweichend vom Video-Titel
--description TEXT Gemeinsam Beschreibung des Videos
--category TEXT Gemeinsam Kategorie (z.B. «Familie Kurmann-Glück»)
--date TEXT Gemeinsam Aufnahmedatum im ISO-Format (YYYY-MM-DD)
--quality TEXT Gemeinsam Qualitätsangabe (z.B. «Dolby Vision», «4K HDR»)
--poster-frame N Gemeinsam Video-Framenummer für Vorschaubild
--poster-at SEKUNDEN Gemeinsam Zeitpunkt in Sekunden für Vorschaubild-Frame
--poster-crop POS Gemeinsam Bildausschnitt für Poster (left/center/right/...)
--work-dir PATH Gemeinsam Arbeitsverzeichnis für temporäre Dateien. Default: Quellverzeichnis
--force Gemeinsam Erzwingt Neuerstellung aller Dateien
--verbose, -v Gemeinsam Zusätzliche Ablaufinformationen auf stderr
--infuse-dir PATH Infuse Aktiviert Infuse-Profil, Zielverzeichnis
--web-dir PATH Web Web-Profil Basisverzeichnis (+ ULID). Default: Quellverzeichnis
--ulid TEXT Web ULID übersteuern (für bestehende Mediensets)
--no-zip Web Kein ZIP im Web-Profil
--no-og-tags Web OpenGraph-Tags deaktivieren

Ausgabe (stdout)

  • Nur Infuse: Pfad zum Infuse-Verzeichnis
  • Nur Web (oder Default): Pfad zum ULID-Verzeichnis
  • Beide: JSON {"infuse": "/pfad/...", "web": "/pfad/.../ULID"}

Konfiguration

Einstellungen werden in ~/.config/mediaset-creator/config.toml gespeichert.

Befehle

# Wert speichern
mediaset-creator config set <schlüssel> "<wert>"

# Einzelnen Wert lesen
mediaset-creator config get <schlüssel>

# Alle gespeicherten Werte anzeigen
mediaset-creator config list

Erlaubte Schlüssel

Schlüssel Beschreibung Standard
og.base_url Stamm-URL für OG-Tags (z.B. https://example.com/shares/) (leer)
og.enabled OG-Tags aktivieren (true/false) true
og.site_name OG site_name Metadatum (leer)
og.locale OG locale Metadatum de_CH
thumbnails.portrait_suffix Suffix für Hochformat-Vorschaubilder (Infuse: -poster) -poster
thumbnails.sidecar Sidecar-Bilder als Landscape-Quelle verwenden (true/false) true
title.filename_fallback Dateiname als Titel-Fallback (true/false) true
filename.date_prefix Datum (YYYY-MM-DD) als Dateiname-Prefix (true/false) true
video.auto_compress Automatische Komprimierung bei >4K oder >40 Mbit/s (true/false) true
video.crf CRF-Wert für libx265 (0–51, tiefer = bessere Qualität) 20
video.max_bitrate Maximale Bitrate in Mbit/s 40
video.preset libx265-Preset (ultrafast/fast/medium/slow/veryslow) slow
tools.ffmpeg Pfad zur ffmpeg-Binärdatei ffmpeg
tools.ffprobe Pfad zur ffprobe-Binärdatei ffprobe
tools.nice_level CPU-Priorität für ffmpeg via nice (0–19; leer = keine Drosselung) (leer)

Automatische Videokompression

Wenn video.auto_compress aktiv ist (Standard), analysiert das Tool die technischen Eigenschaften des Videos. Bei Überschreiten eines der folgenden Schwellwerte wird automatisch eine komprimierte MP4-Version für das Web-Profil erstellt:

  • Auflösung > 4K UHD (> 3840×2160)
  • Bitrate > 40 Mbit/s (konfigurierbar via video.max_bitrate)

Das Infuse-Profil erhält immer das Original-Video – Komprimierung betrifft nur das Web-Profil.

Parameter Wert Konfigurierbar
Codec HEVC (libx265), 10-Bit
Qualität CRF 20 video.crf
Preset slow video.preset
Auflösung 2560×1440 (QHD), Lanczos
Audio AAC, 192 kbit/s

Fallback: Falls libx265 nicht verfügbar, wird auf VideoToolbox (macOS) zurückgefallen.


Verwendung (Python API)

from pathlib import Path
from mediaset_creator.api import (
    CreateMediasetRequest,
    InfuseProfile,
    PosterSpec,
    WebProfile,
    RuntimeOptions,
    create_mediaset,
)

request = CreateMediasetRequest(
    source_path=Path("/pfad/zu/video.m4v"),
    title="Leah Treppen-Surfen",
    description="Beschreibung des Videos.",
    category="Familie Kurmann-Glück",
    recording_date="2024-07-01",
    quality_label="Dolby Vision",
    poster=PosterSpec(timestamp_seconds=5.0),
    mediaset_title="Familienfilme 2024",
    work_dir=Path("/tmp/mediaset-work"),  # Optional: Arbeitsverzeichnis für temporäre Dateien
    infuse=InfuseProfile(output_dir=Path("/nas/infuse/familienfilme")),
    web=WebProfile(
        output_dir=Path("/nas/shares"),
        include_zip=True,
        enable_og_tags=True,
    ),
)

runtime = RuntimeOptions(
    base_url="https://example.com/shares/",
)

result = create_mediaset(request, runtime)

if result.success:
    if result.infuse:
        print(f"Infuse: {result.infuse.output_dir}")
    if result.web:
        print(f"Web: {result.web.output_dir} (ULID: {result.web.ulid})")
else:
    print(f"Fehler: {result.error_message}")

Fortschritts-Events

Events sind strukturierte Datenstrukturen mit stabilen stage_id-Strings. Milestone-Events (INFUSE_READY, WEB_READY) enthalten ein paths-Dict mit den erzeugten Dateipfaden, sodass Host-Applikationen sofort mit dem Deployment beginnen können.

from mediaset_creator.api import MediasetCreatorEvent, MediasetCreatorStage

def on_event(event: MediasetCreatorEvent) -> None:
    print(f"  {event.message}")
    if event.stage_id == MediasetCreatorStage.INFUSE_READY:
        # Medienserver-Deployment starten
        deploy_to_infuse(event.paths)
    elif event.stage_id == MediasetCreatorStage.WEB_READY:
        # Web-Deployment starten
        deploy_to_web(event.paths)

result = create_mediaset(request, runtime, on_event=on_event)

Event-Phasen

Phase Stage-ID Beschreibung
mediaset_started Mediaset-Erstellung beginnt
1 video_analyzed Videoanalyse (Auflösung, Bitrate, Codec)
1 thumbnails_created Landscape- und Portrait-Vorschaubilder erstellt
1 nfo_created Infuse/Firecore-Metadatei erstellt
2 infuse_ready Infuse-Medienset komplett (mit paths)
3 video_copied Original kopiert (keine Komprimierung nötig)
3 video_skipped Video unverändert, übersprungen
3 zip_created ZIP-Archiv erstellt
3 html_generated HTML-Seite generiert
4 video_recompressed Nachkomprimierung läuft (Bitrate zu hoch)
4 video_compressed Komprimierung abgeschlossen
5 web_ready Web-Medienset komplett (mit paths)
5 mediaset_completed Alle Profile fertig

MediasetResult

@dataclass
class MediasetResult:
    success: bool
    infuse: InfuseResult | None    # Infuse-Profil Ergebnis
    web: WebResult | None          # Web-Profil Ergebnis
    error_message: str | None

@dataclass
class InfuseResult:
    output_dir: Path
    video_path: Path
    landscape_path: Path
    portrait_path: Path
    nfo_path: Path

@dataclass
class WebResult:
    output_dir: Path               # ULID-Verzeichnis
    ulid: str
    html_path: Path
    video_path: Path
    landscape_path: Path
    zip_path: Path | None          # None wenn include_zip=False

Öffentliche API-Exporte

from mediaset_creator.api import (
    create_mediaset,          # Hauptfunktion
    CreateMediasetRequest,    # Fachlicher Request
    InfuseProfile,            # Infuse-Profil Konfiguration
    WebProfile,               # Web-Profil Konfiguration
    PosterSpec,               # Vorschaubild-Parameter
    RuntimeOptions,           # Technische Laufzeitoptionen
    MediasetResult,           # Ergebnis (profil-basiert)
    InfuseResult,             # Infuse-Ergebnis
    WebResult,                # Web-Ergebnis
    MediasetCreatorEvent,     # Strukturiertes Fortschritts-Event
    MediasetCreatorStage,     # Stage-IDs (StrEnum)
)

Änderungsverlauf

Beinhaltet die letzten drei Versionen.

2.0.0 – 2026-04-01

  • Profil-basierte Ausgabe: Mediensets werden in separate Verzeichnisse für Infuse (--infuse-dir) und Web (--web-dir) ausgegeben
  • Ein Medienset = ein Video: Multi-Video-Logik und --from-json entfernt
  • Neuer API-Contract: MediaItem entfernt, Video-Felder direkt auf CreateMediasetRequest. MediasetResult profil-basiert mit InfuseResult/WebResult. Poster-Parameter in PosterSpec gruppiert
  • Vereinfachte CLI-Optionen: --title statt --video-title, --category statt --video-category, etc.
  • Milestone-Events mit Pfaden: INFUSE_READY und WEB_READY enthalten paths-Dict
  • Site-Name konfigurierbar: HTML-Header nutzt og.site_name aus Config statt Hardcoding
  • Breaking: Alle stage_id-Werte von Deutsch auf Englisch

1.4.0 – 2026-03-29

  • Software-Encoding: libx265 mit CRF-Modus
  • Frame-Auswahl: --poster-frame, --poster-at, --poster-crop
  • Inkrementelle Verarbeitung: --force zum Übersteuern

1.3.0 – 2026-03-28

  • Internet-freundliche Dateinamen: Umlaute transliteriert, ASCII-sicher
  • ZIP-Inhalte behalten originale Dateinamen (Infuse-freundlich)

Vollständige Historie: 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_mediaset_creator-2.0.1.tar.gz (24.4 kB view details)

Uploaded Source

Built Distribution

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

kurmann_mediaset_creator-2.0.1-py3-none-any.whl (29.5 kB view details)

Uploaded Python 3

File details

Details for the file kurmann_mediaset_creator-2.0.1.tar.gz.

File metadata

  • Download URL: kurmann_mediaset_creator-2.0.1.tar.gz
  • Upload date:
  • Size: 24.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kurmann_mediaset_creator-2.0.1.tar.gz
Algorithm Hash digest
SHA256 f7c3e4c5f151949dc5fe57b8f3abea9b8e77e82d9f99fb1a05d38c43b7bf03dc
MD5 2fe8d22e228217db86d90c8a9d98d96e
BLAKE2b-256 69a213a5c7e72c9cbc8e48c4d167961caf4e1b8ec6e427f106c5c8732528c637

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_mediaset_creator-2.0.1.tar.gz:

Publisher: publish.yml on kurmann/mediaset-creator

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_mediaset_creator-2.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for kurmann_mediaset_creator-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 712afdc3eed3a6c29c1c25a5d97c1d0da980ef4f45ef45c2a9861337b58b7cae
MD5 367ca459c1ebd5e3c57aa45f400fc52e
BLAKE2b-256 14082c1baf5635f435b9b18cef80e31b1d2d6e89689a5fb81a87ab939503db6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_mediaset_creator-2.0.1-py3-none-any.whl:

Publisher: publish.yml on kurmann/mediaset-creator

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