Generischer Medien-Metadaten-Leser: exiftool-Wrapper + Best-Guess-Aufnahmedatum mit Provenance. Vereinheitlicht Metadaten aus Blackmagic Camera, iPhone Camera, Final Cut Camera und weiteren Quellen.
Project description
🎬 medien-leser
Generischer Medien-Metadaten-Leser. Wrappt exiftool und liefert ein einheitliches Schema mit Provenance — speziell für das Best-Guess-Aufnahmedatum (recorded_at + recorded_at_source), das über verschiedene Aufnahme-Quellen hinweg konsistent funktioniert.
Status: 0.1.0 (Alpha) — API kann sich in 0.x-Versionen noch ändern. Konsumenten (
kamera-einleser,schnittprojekt-leser) pinnen aktuell auf eine konkrete Version. Ab 1.0.0 ist die API stabil nach SemVer.
✨ Was es kann
- Einheitliche Schemas für Video-/Foto-Metadaten aus verschiedenen Quellen:
MediaFileMetadata— Top-Level mitdates,video,audio,camera,gps,production,source_app- Sub-Schemas:
DateSources,VideoInfo,AudioInfo,CameraInfo,GpsInfo,ProductionInfo
- Best-Guess-Aufnahmedatum mit dokumentierter Vertrauens-Hierarchie und Provenance-Label:
Keys:CreationDate→QuickTime:CreationDate→Blackmagic-design:CameraDateRecorded→DateTimeOriginal→CreateDate→file_birthtime→file_mtime- Zeitzonen-Inferenz für Apps wie Final Cut Camera, die
CreateDatein UTC ohne TZ-Marker schreiben - Format-Normalisierung von
2026:04:20 12:52:15+02:00→2026-04-20T12:52:15+02:00(ISO-8601 mit Doppelpunkt im TZ-Offset)
- Source-App-Detection: Heuristik erkennt Blackmagic Camera, iPhone Camera, Final Cut Camera anhand
AppleProappsAppBundleID, BMD-design-Tags, Apple-Make/Model - Batch-Modus (
extract_metadata_for_files): N Dateien in einem einzigenexiftool-Aufruf → 5-50× schneller als N Einzelaufrufe
📋 Voraussetzungen
- Python 3.10 oder höher
- exiftool (
brew install exiftoolauf macOS)
🚀 Installation
uv add kurmann-medien-leser
# oder
pipx install kurmann-medien-leser
# oder
pip install kurmann-medien-leser
🎯 Quick Start
from pathlib import Path
from kurmann_medien_leser import read_metadata, pick_recorded_at
# Eine Datei einlesen
metadata = read_metadata(Path("IMG_0001.mov"))
print(metadata.recorded_at) # "2026-05-03T07:38:55+02:00"
print(metadata.recorded_at_source) # "exif:CreateDate+tz_from_mtime"
print(metadata.source_app) # "Final Cut Camera"
print(metadata.camera.model) # "iPhone 15 Pro Max"
print(metadata.gps.lat, metadata.gps.lon) # 47.07054, 7.58165
print(metadata.video.codec, metadata.video.resolution) # "HEVC", "3840x2160"
# Manuelle Best-Guess-Logik aus eigenen DateSources
from kurmann_medien_leser import DateSources
dates = DateSources(
exif_create_date="2026-05-03T05:38:55",
file_mtime="2026-05-03T07:39:00+02:00",
)
iso, source = pick_recorded_at(dates)
# → ("2026-05-03T07:38:55+02:00", "exif:CreateDate+tz_from_mtime")
📚 Public API
| Symbol | Beschreibung |
|---|---|
read_metadata(path) → MediaFileMetadata |
Eine Datei einlesen, alle Tags + Best-Guess in einem Aufruf |
extract_metadata_for_files(paths) → dict[Path, dict] |
Batch-Modus für viele Dateien (Performance) |
pick_recorded_at(dates) → (iso_string, source_label) |
Best-Guess mit Provenance, anwendbar auf eigene DateSources |
detect_source_app(raw_metadata) → str | None |
Heuristik für Aufnahme-App-Erkennung |
normalize_iso_date(raw) → str | None |
Format-Normalisierung exiftool → ISO-8601 |
MediaFileMetadata, DateSources, VideoInfo, AudioInfo, CameraInfo, GpsInfo, ProductionInfo |
Dataclasses (Type-Hints) |
🎥 Unterstützte Aufnahme-Quellen
Genau wie im Original-Manifest-System aus kamera-einleser:
| App | Aufnahmedatum-Quelle | Eigenheiten |
|---|---|---|
| Blackmagic Camera | Keys:CreationDate mit TZ |
viele proprietäre Blackmagic-design:*-Felder; Apple ProApps Production (Reel/Scene/Shot/Project/Director); Kamera-Settings (ISO, Shutter, WB, Aperture) |
| iPhone Camera | Keys:CreationDate mit TZ |
Standard Apple QuickTime; Lens-Modell in VideoKeys:LensModel; GPS mit Höhe |
| Final Cut Camera | nur CreateDate (UTC ohne TZ) ⚠️ |
identifizierbar via Keys:AppleProappsAppBundleID = com.apple.FinalCutApp.companion; TZ wird aus file_mtime abgeleitet |
Andere Quellen funktionieren oft auch (Fallback auf klassisches EXIF), kriegen aber source_app=None.
🛣️ Roadmap
- 0.x: API-Stabilisierung gemeinsam mit den ersten beiden Konsumenten (
kamera-einleser,schnittprojekt-leser) - 1.0.0: stabile API nach SemVer
- Später: Audio-/PDF-Metadaten als zusätzliche Schemas (gleicher Stil wie
MediaFileMetadata)
📝 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_medien_leser-0.1.0.tar.gz.
File metadata
- Download URL: kurmann_medien_leser-0.1.0.tar.gz
- Upload date:
- Size: 39.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb6c08abe8bd05056f38de0108b82e5efdd75f8103ad930e7b7ef03e389cec24
|
|
| MD5 |
eae95afffc94ffce69eb480374ae673e
|
|
| BLAKE2b-256 |
cc381ae726be83eebcc6e9bb4b412b852f1b24b207f008b291c8beab0397c446
|
Provenance
The following attestation bundles were made for kurmann_medien_leser-0.1.0.tar.gz:
Publisher:
publish.yml on kurmann/medien-leser
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_medien_leser-0.1.0.tar.gz -
Subject digest:
fb6c08abe8bd05056f38de0108b82e5efdd75f8103ad930e7b7ef03e389cec24 - Sigstore transparency entry: 1519919174
- Sigstore integration time:
-
Permalink:
kurmann/medien-leser@cebb45a224c83b2ffccee44cc4446de4f15035b4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cebb45a224c83b2ffccee44cc4446de4f15035b4 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file kurmann_medien_leser-0.1.0-py3-none-any.whl.
File metadata
- Download URL: kurmann_medien_leser-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.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 |
8053562d45b7a1a9637462f35281a1bc09897cc261773c7b53bb34b343527307
|
|
| MD5 |
1a155c4dc968cb8ea423681989a1acfc
|
|
| BLAKE2b-256 |
e4360a8462beb0e98da153f2af74029f4e4b9832592350c5de5eeeb5c4a7ec80
|
Provenance
The following attestation bundles were made for kurmann_medien_leser-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on kurmann/medien-leser
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kurmann_medien_leser-0.1.0-py3-none-any.whl -
Subject digest:
8053562d45b7a1a9637462f35281a1bc09897cc261773c7b53bb34b343527307 - Sigstore transparency entry: 1519919186
- Sigstore integration time:
-
Permalink:
kurmann/medien-leser@cebb45a224c83b2ffccee44cc4446de4f15035b4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kurmann
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cebb45a224c83b2ffccee44cc4446de4f15035b4 -
Trigger Event:
workflow_dispatch
-
Statement type: