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.


API-Keys (KI-Funktionen)

Der Mediaset-Creator selbst spricht nicht mit Claude. Wenn ein PosterSpec ohne frame_number/timestamp_seconds (oder ganz None) übergeben wird, ruft er den vorschaubild-manager auf, der die Frame-Auswahl und/oder den Crop-Vorschlag via Claude erledigt.

Empfohlenes Setup: ANTHROPIC_API_KEY als Umgebungsvariable

# In ~/.zshenv eintragen (gilt für interaktive UND non-interaktive Shells,
# also auch für launchd / cron / Tool-Subprozesse via uv tool):
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.zshenv

# Für laufende launchd-Jobs zusätzlich (einmalig, persistiert über Reboots):
launchctl setenv ANTHROPIC_API_KEY "sk-ant-..."

ANTHROPIC_API_KEY ist der offizielle Variablenname des Anthropic-SDK und wird vom Vorschaubild-Manager bevorzugt gelesen. Der historische Name CLAUDE_API_KEY bleibt als Fallback unterstützt.

Wer liest den Key wann?

Tool Liest Key? Wann
Mediaset-Creator (dieses Tool) ❌ nein Pass-Through, KI greift implizit auf das Prozess-ENV zu
Vorschaubild-Manager ✅ ja beim Mosaic-Auto-Frame und beim Crop-Auto-Wahl

Alternative: lokale Config-Datei

vorschaubild-manager config set claude.api_key "sk-ant-..."
# → schreibt nach ~/.config/vorschaubild-manager/config.toml

Ohne API-Key

Wenn weder ENV noch Config gesetzt sind und kein expliziter PosterSpec.frame_number/timestamp_seconds übergeben wurde, schlägt die Mediaset-Erstellung mit einer Fehlermeldung aus dem Vorschaubild-Manager fehl.


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.1.0.tar.gz (31.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_mediaset_creator-3.1.0-py3-none-any.whl (36.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kurmann_mediaset_creator-3.1.0.tar.gz
  • Upload date:
  • Size: 31.0 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.1.0.tar.gz
Algorithm Hash digest
SHA256 3bb332c759ceedca2d337d1e3fd1e080cb0e70cabe4538a71e23290ebf5c5d86
MD5 270426cd901fb1fd34783c6a4904c47d
BLAKE2b-256 5567ec81dc1f55b70c2fdd3e056a7a78a36b91fe66627543525ef94ad4a0b625

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for kurmann_mediaset_creator-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a4beeee5ffb527692b5e9d6899e59bd39cad5cff46510037404b5e3c658d5236
MD5 244e097763b0aceda1695f449dabb23f
BLAKE2b-256 74439c35391e96eaac7c707b579ef4c934f652f62e0b1e4b3698e04701fcf1be

See more details on using hashes here.

Provenance

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