CLI-Tool und Python-Bibliothek zur Veröffentlichung von Familienfilmen: Medienset-Erstellung, Infuse-Deployment, Webserver-Deployment und Archivierung.
Project description
familienfilm-manager
CLI-Tool und Python-Bibliothek zur Veröffentlichung von selbst geschnittenen Familienfilmen.
Orchestriert den gesamten Workflow: Metadaten extrahieren, Medienset erstellen (via mediaset-creator),
Infuse-/Webserver-Deployment und Archivierung.
Voraussetzungen
- Python 3.11+
- ffmpeg und
ffprobeim$PATH - rclone im
$PATH(für Deployments und Archivierung) - hdiutil (macOS, für ISO-Erstellung)
- kurmann-mediaset-creator (wird als Dependency installiert)
Installation
uv pip install kurmann-familienfilm-manager
Im Entwicklungsmodus:
uv sync
Verwendung (CLI)
Gesamtworkflow
familienfilm-manager publish /pfad/zu/video.m4v \
--title "Wanderung auf den Napf" \
--category "Familie Kurmann-Glück" \
--date "2025-03-24" \
-v
Das Tool:
- Extrahiert Metadaten (QuickTime-Tags oder Dateiname)
- Erstellt ein Medienset via
mediaset-creatormit separaten Profilen (Infuse/Web) - Deployt zu Infuse sofort bei Fertigstellung (direkt via rclone, kein ZIP-Entpacken)
- Deployt zum Webserver nach Fertigstellung der Web-Komprimierung (rclone)
- Archiviert Original + Sidecars als TAR (Python tarfile → rclone move)
Einzeloperationen
# Nur Infuse-Deployment eines Verzeichnisses mit Infuse-Dateien
familienfilm-manager deploy-infuse /pfad/zum/infuse-verzeichnis/
# Nur Web-Deployment eines Web-ID-Verzeichnisses
familienfilm-manager deploy-web /pfad/zum/01JNXYZ.../
# Nur Archivierung
familienfilm-manager archive /pfad/zu/video.m4v --date 2025-03-24
Optionen (publish)
| Option | Beschreibung |
|---|---|
--title TEXT |
Video-Titel (überschreibt extrahierte Metadaten) |
--description TEXT |
Beschreibung des Videos |
--category TEXT |
Kategorie (z.B. «Familie Kurmann-Glück») |
--date TEXT |
Aufnahmedatum im ISO-Format (YYYY-MM-DD) |
--output-dir PATH |
Basisverzeichnis für die Web-Medienset-Ausgabe |
--poster-frame INT |
Frame-Nummer für Vorschaubild (überspringt KI-Auswahl) |
--poster-at FLOAT |
Zeitpunkt in Sekunden für Vorschaubild (z.B. 90 oder 1.5) |
--poster-crop TEXT |
Bildausschnitt (left/center-left/center/center-right/right) |
--web-id TEXT |
Web-ID für Web-Medienset (12 Zeichen, a-z 0-9; überschreibt Sidecar-Wert) |
--max-luminance INT |
Peak-Leuchtdichte in nits für HDR-Metadaten (Default: 1000) |
--no-sidecar |
Sidecar-Datei nicht lesen/schreiben |
--no-infuse |
Infuse-Deployment überspringen |
--no-web |
Web-Deployment überspringen |
--no-archive |
Archivierung überspringen |
--force |
Neuerstellung erzwingen |
--verbose, -v |
Zusätzliche Ablaufinformationen auf stderr |
Ausgabe
stdout enthält den Pfad zum erstellten Verzeichnis (Web-ID-Verzeichnis oder Infuse-Verzeichnis):
/pfad/zum/output/01JNXYZ.../
Verzeichnis-Publikation (Batch)
Mit publish-dir werden alle qualifizierten Videos in einem Verzeichnis sequenziell publiziert
(älteste zuerst). Ideal für Watch-Folder-Workflows.
# Trockenlauf: zeige welche Videos publiziert würden
familienfilm-manager publish-dir /Movies/LumaFusion-Export/ --dry-run
# Alle qualifizierten Videos publizieren
familienfilm-manager publish-dir /Movies/LumaFusion-Export/
# Auch bereits publizierte Videos neu publizieren
familienfilm-manager publish-dir /Movies/LumaFusion-Export/ --force
Filter-Kriterien
Nur Dateien werden publiziert, die alle Bedingungen erfüllen:
- Bekannte Video-Endung:
.mov,.mp4,.m4v,.mkv - Dateiname matcht das Muster
<YYYY-MM-DD> <titel>.<ext>(mindestens Datum-Präfix) - Kein Hidden-File (kein
.am Anfang) - Keine Verzeichnisse
Alles andere wird stillschweigend ignoriert.
Idempotenz
Nach erfolgreicher Publikation wird der Zeitpunkt als published_at ins Sidecar
(<video>.settings.toml) geschrieben. Beim nächsten publish-dir-Lauf werden Videos
übersprungen, sofern:
- Sidecar mit
published_atexistiert, und - Quellvideo seit
published_atnicht geändert wurde, und - Sidecar selbst seit
published_atnicht geändert wurde
Eine manuelle Sidecar-Anpassung (z.B. neuer poster-at-Wert) triggert also automatisch
einen Republish. Mit --force werden alle Videos unabhängig vom Status neu publiziert.
Hinweis: Beim Einzeldatei-publish greift der Skip-Check nicht — der explizite
Aufruf publiziert immer.
Optionen (publish-dir)
| Option | Beschreibung |
|---|---|
--no-infuse |
Infuse-Deployment für alle Videos überspringen |
--no-web |
Web-Deployment für alle Videos überspringen |
--no-archive |
Archivierung für alle Videos überspringen |
--force |
Auch bereits publizierte Videos neu publizieren |
--dry-run |
Nur anzeigen welche Videos publiziert würden, ohne zu publizieren |
--work-dir PATH |
Arbeitsverzeichnis für temporäre Dateien (überschreibt paths.work_dir Config) |
--verbose, -v |
Zusätzliche Ablaufinformationen pro Video auf stderr |
Verhalten bei Fehlern
Ein Fehler bei einem Video stoppt den Batch-Lauf nicht — die Verarbeitung läuft mit
dem nächsten Video weiter. Am Schluss wird eine Zusammenfassung mit Erfolgen,
übersprungenen und fehlgeschlagenen Videos ausgegeben. Exit-Code 1 wenn mindestens
ein Video fehlschlug.
Metadaten-Extraktion
Metadaten werden in folgender Priorität ermittelt:
Aufnahmedatum
- CLI-Parameter (
--date) – überschreibt alles - QuickTime-Tag (
com.apple.quicktime.creationdate) – bewusst in Final Cut Pro gesetztes Datum - Dateiname – ISO-Datum am Anfang des Dateinamens (z.B.
2019-12-22 Twannbachschlucht.mov) - Generische Tags (
creation_time,date) – oft das Datei-Änderungsdatum, nicht das Aufnahmedatum
Der Dateiname hat bewusst höhere Priorität als generische Tags (creation_time), weil der Videoschnitt selten am gleichen Tag wie die Aufnahme stattfindet. So kann das korrekte Aufnahmedatum über den Dateinamen bestimmt werden.
Titel
- CLI-Parameter (
--title) – überschreibt alles - QuickTime-Tags (via ffprobe) – aus Final Cut Pro exportierte Metadaten
- Dateiname – Titel nach dem Datumspräfix:
2025-03-24 Wanderung auf den Napf.m4v→ «Wanderung auf den Napf»2025-03-24 - Wanderung auf den Napf.m4v→ «Wanderung auf den Napf»
Poster-Zeitpunkt aus dem Dateinamen
Der Zeitpunkt für das Vorschaubild kann direkt im Dateinamen mitgegeben werden – ideal für Videoschnitt-Programme wie LumaFusion, die keine Sidecar-Dateien beim Export erstellen.
Format: poster-<zeit> am Ende des Dateinamens (Leerzeichen davor).
Minuten-Marker: min (vollständig) oder m (Kurzform, ffmpeg-Stil).
| Suffix | Bedeutung |
|---|---|
poster-2min / poster-2m |
2 Minuten = 120 Sek. |
poster-3min12 / poster-3m12 |
3 Min 12 Sek = 192 Sek. |
poster-1min30s500 / poster-1m30s500 |
1 Min 30.5 Sek (Sub-Sekunden) |
poster-30s |
30 Sek. |
poster-30s500 |
30.5 Sek. |
Beispiel:
2026-04-16 HDR-Test poster-1min30.mov
→ Datum: 2026-04-16, Titel: «HDR-Test», Poster-Zeitpunkt: 90 Sek.
Der Suffix wird beim Parsen vom Titel entfernt (landet nicht im Output-Dateinamen) und
automatisch in die Sidecar-Datei (.settings.toml) geschrieben. Bei einem späteren
publish ohne Suffix im Dateinamen wird der Wert aus der Sidecar-Datei gelesen.
Priorität: CLI (--poster-at) > Filename-Suffix > Sidecar.
Wichtig: Ein Aufnahmedatum ist zwingend erforderlich. Ohne Datum wird die Verarbeitung abgebrochen.
Settings-Sidecar-Datei
Wenn Poster-Einstellungen via CLI angegeben werden (--poster-frame, --poster-at, --poster-crop), speichert der Familienfilm Manager diese automatisch in einer .settings.toml-Datei neben dem Video:
2025-03-24 Wanderung auf den Napf.m4v
2025-03-24 Wanderung auf den Napf.settings.toml ← automatisch erstellt
Inhalt:
[poster]
timestamp_seconds = 42.5
crop_position = "center-right"
[web]
web_id = "a3xk9mn2pqrw"
Bei einem erneuten publish werden die Werte automatisch aus der Sidecar-Datei gelesen – CLI-Parameter überschreiben gespeicherte Werte. Die Web-ID wird nach erfolgreicher Erstellung automatisch gespeichert, damit bei erneutem Publish die gleiche ID wiederverwendet wird (gleiche URL bleibt stabil).
Die Sidecar-Datei wird bei der Archivierung automatisch mit ins ISO aufgenommen.
Deaktivieren: --no-sidecar (pro Aufruf) oder familienfilm-manager config set sidecar.enabled false (global).
Konfiguration
Einstellungen werden in ~/.config/familienfilm-manager/config.toml gespeichert.
Befehle
# Wert speichern
familienfilm-manager config set <schlüssel> "<wert>"
# Einzelnen Wert lesen
familienfilm-manager config get <schlüssel>
# Alle gespeicherten Werte anzeigen
familienfilm-manager config list
Erlaubte Schlüssel
| Schlüssel | Beschreibung | Standard |
|---|---|---|
targets.infuse |
rclone-Ziel für Infuse (z.B. nas:/media/videos/) |
(leer) |
targets.web |
rclone-Ziel für Webserver (z.B. azure:container/shares/) |
(leer) |
targets.archive |
rclone-Ziel für Archiv (z.B. nas:/archive/familienfilme/) |
(leer) |
infuse.group_by |
Gruppierung: year oder month |
year |
defaults.category |
Standard-Kategorie für Videos | (leer) |
sidecar.enabled |
Sidecar-Dateien automatisch lesen/schreiben | true |
cleanup.web_workdir |
Temporäres Web-Arbeitsverzeichnis nach erfolgreichem Deployment löschen | true |
paths.work_dir |
Standard-Arbeitsverzeichnis für temporäre Dateien (lokaler SSD bei SMB-Quellen empfohlen) | (leer) |
mediaset.branding_base_url |
Stamm-URL für Web-Mediasets und OG-Tags | (leer) |
mediaset.branding_site_name |
Site-Name (sichtbar im Header + OG-Meta) | (leer) |
tools.ffmpeg |
Pfad zur ffmpeg-Binärdatei | ffmpeg |
tools.ffprobe |
Pfad zur ffprobe-Binärdatei | ffprobe |
tools.rclone |
Pfad zur rclone-Binärdatei | rclone |
Beispiel
familienfilm-manager config set targets.infuse "nas:/media/familienfilme/"
familienfilm-manager config set targets.web "azure:kurmann-glueck/shares/"
familienfilm-manager config set targets.archive "nas:/archive/familienfilme/"
familienfilm-manager config set defaults.category "Familie Kurmann-Glück"
familienfilm-manager config set mediaset.branding_base_url "https://kurmannmedia.blob.core.windows.net/kurmann-glueck/"
Arbeitsverzeichnis bei SMB-Quellen
Wenn die Quellvideos auf einem SMB-/NAS-Laufwerk liegen, sollte ein lokales Arbeitsverzeichnis konfiguriert werden, damit Komprimierung und temporäre Dateien nicht über das Netzwerk laufen:
familienfilm-manager config set paths.work_dir "~/Movies/.familienfilm-tmp"
Dann werden bei jeder Publikation:
- Quellvideo gelesen vom SMB
- Sidecar
.settings.tomlgeschrieben auf SMB (klein) - Komprimierung, Thumbnails, Web-Output: lokal im Work-Dir
- Web-Deployment: rclone push vom lokalen Work-Dir zum Webserver
Resolution: CLI --work-dir > Config paths.work_dir > Quellverzeichnis.
Verwendung (Python API)
from pathlib import Path
from familienfilm_manager.api import (
PublishRequest,
RuntimeOptions,
publish,
)
request = PublishRequest(
source_path=Path("/pfad/zu/video.m4v"),
title="Wanderung auf den Napf",
category="Familie Kurmann-Glück",
recording_date="2025-03-24",
)
runtime = RuntimeOptions(
infuse_target="nas:/media/familienfilme/",
web_target="azure:kurmann-glueck/shares/",
archive_target="nas:/archive/familienfilme/",
branding_base_url="https://example.com/shares/",
)
result = publish(request, runtime)
if result.success:
print(f"Infuse: {result.infuse_dir} (deployed: {result.infuse_deployed})")
print(f"Web: {result.web_dir} (deployed: {result.web_deployed})")
print(f"Archiv: {result.archived}")
else:
print(f"Fehler: {result.error_message}")
Öffentliche API-Exporte
from familienfilm_manager.api import (
publish, # Gesamtworkflow
deploy_infuse, # Nur Infuse-Deployment
deploy_web, # Nur Web-Deployment
archive, # Nur Archivierung
PublishRequest, # Fachlicher Request
PublishResult, # Ergebnis
DeployRequest, # Deploy-Request
DeployResult, # Deploy-Ergebnis
ArchiveRequest, # Archiv-Request
ArchiveResult, # Archiv-Ergebnis
RuntimeOptions, # Technische Optionen
FamilienfilmEvent, # Fortschritts-Event
FamilienfilmStage, # Stage-IDs
)
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_familienfilm_manager-0.5.0.tar.gz.
File metadata
- Download URL: kurmann_familienfilm_manager-0.5.0.tar.gz
- Upload date:
- Size: 37.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cfa18c2832f87f1bb639c3c83b50f8ccd6ce6740fe4c2106fea154932e97bf8d
|
|
| MD5 |
95a109db4ea851203cc2a56ae9098526
|
|
| BLAKE2b-256 |
b26491f691161346f85799cf2f0bd3c2ae1f7d803d36d41bba5d30d288780d49
|
Provenance
The following attestation bundles were made for kurmann_familienfilm_manager-0.5.0.tar.gz:
Publisher:
publish.yml on kurmann/familienfilm-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_familienfilm_manager-0.5.0.tar.gz -
Subject digest:
cfa18c2832f87f1bb639c3c83b50f8ccd6ce6740fe4c2106fea154932e97bf8d - Sigstore transparency entry: 1328399181
- Sigstore integration time:
-
Permalink:
kurmann/familienfilm-manager@339815bcbe51c01789f5a9f7145d8d1ae7ac5066 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@339815bcbe51c01789f5a9f7145d8d1ae7ac5066 -
Trigger Event:
release
-
Statement type:
File details
Details for the file kurmann_familienfilm_manager-0.5.0-py3-none-any.whl.
File metadata
- Download URL: kurmann_familienfilm_manager-0.5.0-py3-none-any.whl
- Upload date:
- Size: 36.3 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 |
3dfa8ffbd803494d6ccf7fb2a9e163b9483c961e015a96cfc068df89baf55b2c
|
|
| MD5 |
5c64a73e55b67c9207ab4c838527d611
|
|
| BLAKE2b-256 |
496633bab2f713c321e121659b4dab20c06539f50f25cfda5509c72e7e9fd4de
|
Provenance
The following attestation bundles were made for kurmann_familienfilm_manager-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on kurmann/familienfilm-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_familienfilm_manager-0.5.0-py3-none-any.whl -
Subject digest:
3dfa8ffbd803494d6ccf7fb2a9e163b9483c961e015a96cfc068df89baf55b2c - Sigstore transparency entry: 1328399190
- Sigstore integration time:
-
Permalink:
kurmann/familienfilm-manager@339815bcbe51c01789f5a9f7145d8d1ae7ac5066 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@339815bcbe51c01789f5a9f7145d8d1ae7ac5066 -
Trigger Event:
release
-
Statement type: