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
- Python 3.11+
- ffmpeg und
ffprobeim$PATH - kurmann-vorschaubild-manager (wird als Dependency installiert)
- Ein Anthropic API Key für die automatische Vorschaubildauswahl
(konfigurierbar via
vorschaubild-manager config set claude.api_key <key>)
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») |
--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 (+ 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.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_hdrvia 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
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-jsonentfernt - Neuer API-Contract:
MediaItementfernt, Video-Felder direkt aufCreateMediasetRequest.MediasetResultprofil-basiert mitInfuseResult/WebResult. Poster-Parameter inPosterSpecgruppiert - Vereinfachte CLI-Optionen:
--titlestatt--video-title,--categorystatt--video-category, etc. - Milestone-Events mit Pfaden:
INFUSE_READYundWEB_READYenthaltenpaths-Dict - Site-Name konfigurierbar: HTML-Header nutzt
og.site_nameaus Config statt Hardcoding - Breaking: Alle
stage_id-Werte von Deutsch auf Englisch
Vollständige Historie: CHANGELOG.md
Lizenz
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kurmann_mediaset_creator-2.1.0.tar.gz.
File metadata
- Download URL: kurmann_mediaset_creator-2.1.0.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cae70b2b9f61ae9161bed2218eaab88cac0c047f131b8affccbc3666c1b890b7
|
|
| MD5 |
d3fd205f658b12c7fd7d95b2e152286a
|
|
| BLAKE2b-256 |
22bbd89eba4cb0be414b3d383dac88f8a892629ef4b71adc5d017965e1f1e15b
|
Provenance
The following attestation bundles were made for kurmann_mediaset_creator-2.1.0.tar.gz:
Publisher:
publish.yml on kurmann/mediaset-creator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_mediaset_creator-2.1.0.tar.gz -
Subject digest:
cae70b2b9f61ae9161bed2218eaab88cac0c047f131b8affccbc3666c1b890b7 - Sigstore transparency entry: 1320366496
- Sigstore integration time:
-
Permalink:
kurmann/mediaset-creator@e5cfc2787ab1b1d3029bf8b34da2d71d6632c73e -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e5cfc2787ab1b1d3029bf8b34da2d71d6632c73e -
Trigger Event:
release
-
Statement type:
File details
Details for the file kurmann_mediaset_creator-2.1.0-py3-none-any.whl.
File metadata
- Download URL: kurmann_mediaset_creator-2.1.0-py3-none-any.whl
- Upload date:
- Size: 30.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
858fcc50f9e3f976b1bd92c5021764cce6a70141fdf4c3f2e9ecf5c71a2537f8
|
|
| MD5 |
6644213614a62fd93f01f9b6856bddff
|
|
| BLAKE2b-256 |
e005a419557ee258ccf86cc1e996096594201ffefde42c202eccc1dfb24da290
|
Provenance
The following attestation bundles were made for kurmann_mediaset_creator-2.1.0-py3-none-any.whl:
Publisher:
publish.yml on kurmann/mediaset-creator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_mediaset_creator-2.1.0-py3-none-any.whl -
Subject digest:
858fcc50f9e3f976b1bd92c5021764cce6a70141fdf4c3f2e9ecf5c71a2537f8 - Sigstore transparency entry: 1320366603
- Sigstore integration time:
-
Permalink:
kurmann/mediaset-creator@e5cfc2787ab1b1d3029bf8b34da2d71d6632c73e -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e5cfc2787ab1b1d3029bf8b34da2d71d6632c73e -
Trigger Event:
release
-
Statement type: