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" \
  --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 (Web-ID-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)
--max-luminance N Gemeinsam Peak-Leuchtdichte in nits für HDR-Metadaten (Default: 1000)
--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 (+ Web-ID). Default: Quellverzeichnis
--web-id TEXT Web Web-ID übersteuern (12 Zeichen, a-z 0-9). Default: auto-generiert
--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
branding.base_url Stamm-URL für Web-Mediasets und OG-Tags (z.B. https://mediathek.example.com/) (leer)
branding.enabled OpenGraph-Meta-Tags rendern (true/false) true
branding.site_name Site-Name (sichtbar im Header + OG-Meta) (leer)
branding.locale OG locale Metadatum (z.B. de_CH) 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",
    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://mediathek.example.com/",
)

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} (Web-ID: {result.web.web_id})")
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               # Web-ID-Verzeichnis
    web_id: str                    # 12 Zeichen, a-z 0-9 (Lowercase Base36)
    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.

3.0.0 – 2026-04-17

  • Web-ID statt ULID: Web-Mediasets bekommen 12-stellige Lowercase-IDs (a-z, 0-9) statt 26-stellige ULIDs. Kürzere URLs (/a3xk9mn2pqrw/ statt /01KPCZDEZVQ0PDNAJKB6V5RTXV/)
  • Dolby Vision-Erkennung: Wird automatisch erkannt und im color_space_label ausgegeben (Vorrang vor "BT.2020 PQ")
  • HTML-Title mit Kategorie: <title>Familie Kurmann-Glück – Heubürzel Ann-Sophie</title>
  • Technische Specs im HTML: Stream + Original/ZIP mit Farbraum, Auflösung, fps, Bitrate
  • VideoInfo.frame_rate + bit_depth + color_space_label + is_dolby_vision: Neue Properties
  • VideoSpecs Dataclass: Neue View-Modell-Klasse mit format_compact()
  • OgConfigBrandingConfig: Klarerer Name, gleiche Felder (+ web_id statt ulid)
  • Config-Keys: og.Xbranding.X
  • quality_label entfernt: Durch Tech-Specs überflüssig (Dolby Vision wird automatisch erkannt)
  • Breaking: HTML-Generierung läuft jetzt nach der Komprimierung. HTML_GENERATED Event kommt nach VIDEO_COMPRESSED. WEB_READY bleibt unverändert als zentraler Milestone.
  • Dependency: python-ulid entfernt

2.1.0 – 2026-04-16

  • HDR-Metadaten-Einbettung: MaxCLL, MaxFALL und Mastering Display Metadaten werden automatisch in HDR-Videos eingebettet, damit Geräte die Peak-Leuchtdichte korrekt interpretieren
  • --max-luminance: Peak-Leuchtdichte in nits übersteuern (Default: 1000)
  • HDR-Erkennung: VideoInfo.is_hdr via ffprobe (PQ/HLG/BT.2020)
  • AudioToolbox-Encoder: aac_at (macOS) für bessere Audioqualität

2.0.1 – 2026-04-09

  • HTML-Template als Python-String eingebettet statt aus Dateisystem laden

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-3.0.0.tar.gz (28.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_mediaset_creator-3.0.0-py3-none-any.whl (34.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kurmann_mediaset_creator-3.0.0.tar.gz
  • Upload date:
  • Size: 28.5 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-3.0.0.tar.gz
Algorithm Hash digest
SHA256 a5d402e8cdb41e768dfdff3ec4d44b01a9b37c6c516b1d208e94d0c03a872574
MD5 4e8ef924e081f4510838cfb07dd8af95
BLAKE2b-256 32c08e37f7003b859d15d6fa1234c6417d9267f002cbf51b40e19ab9c0c88098

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for kurmann_mediaset_creator-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bf6c7b087ed374cec750b35967e87d492acb1c31dd3fe3051f555dae10231b08
MD5 bc32ace2c09688cff8edd32074569e2e
BLAKE2b-256 ad2237de788dd3c8bbce036d3bf871d095dd4ddf88b3f9350a6c516a51625a9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for kurmann_mediaset_creator-3.0.0-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