- Python 100%
- jellyfin_playlist_generator_v9.py: kompletter Rewrite mit Bugfixes (FILENAME_PATTERNS-Reihenfolge, IndexError bei leeren Artists, Backup-Namenskollision, Symlink-Schleife), neuem --root-playlist-Feature, maybe_tqdm-Helper und verbesserter Fehlerbehandlung - test_suite_v9.py: 27 Tests (Unit + Integration) für v9 - README.md: vollständige Dokumentation aller Optionen und Features Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .gitignore | ||
| jellyfin_playlist_generator_v9.py | ||
| README.md | ||
| test_suite_v9.py | ||
Jellyfin Playlist Generator v9
Rekursiver .m3u-Playlist-Generator für Jellyfin-Musikbibliotheken.
Prinzip: Du gibst ein Root-Verzeichnis an. Jeder direkte Unterordner gilt als Album und bekommt genau eine Playlist. Tracks werden rekursiv aus allen Unterordnern des Albums gesammelt, nach Unterordner und Dateiname natural-sortiert.
Voraussetzungen
Python 3.10+
pip install mutagen tqdm tenacity # alle optional, aber empfohlen
| Paket | Funktion |
|---|---|
mutagen |
Tags lesen und schreiben |
tqdm |
Fortschrittsbalken |
tenacity |
Robusteres Retry bei I/O-Fehlern |
Ohne mutagen werden nur Playlists erzeugt; Tags werden weder gelesen noch geschrieben.
Aufruf
jellyfin_playlist_generator_v9.py [Optionen] PFAD [PFAD ...]
Minimaler Aufruf
python3 jellyfin_playlist_generator_v9.py /pfad/zur/Musik
Alle Optionen
| Option | Beschreibung |
|---|---|
--dry-run |
Simulationsmodus: nichts schreiben, nichts löschen |
--relative-to PFAD |
Playlist-Einträge relativ zu diesem Basispfad |
--root-playlist |
Zusätzlich pro Root-Verzeichnis eine Sammel-Playlist erzeugen |
--write-tags |
Harmonisierte Tags zurück in die Audiodateien schreiben (erfordert mutagen) |
--backup PFAD |
Vor dem Tag-Schreiben Originale in dieses Verzeichnis sichern |
--report PFAD |
CSV-Report aller Tracks speichern |
--no-tqdm |
Fortschrittsanzeige deaktivieren |
Beispiele
Dry-Run — was würde passieren?
python3 jellyfin_playlist_generator_v9.py --dry-run /mnt/Musik
Playlists mit relativen Pfaden (für portierbare Jellyfin-Bibliothek)
python3 jellyfin_playlist_generator_v9.py --relative-to /mnt/Musik /mnt/Musik
Zusätzliche Sammel-Playlist pro Root
python3 jellyfin_playlist_generator_v9.py --root-playlist /mnt/Musik
Erzeugt neben den Album-Playlists auch /mnt/Musik/Musik.m3u mit allen Tracks.
Tags harmonisieren mit Backup
python3 jellyfin_playlist_generator_v9.py --write-tags --backup /mnt/Backup /mnt/Musik
CSV-Report für Qualitätskontrolle
python3 jellyfin_playlist_generator_v9.py --report /tmp/report.csv /mnt/Musik
Verzeichnisstruktur
Musik/ ← Root (wird übergeben)
├── Pink Floyd/ ← Album-Ordner
│ ├── CD1/
│ │ ├── 01 - Shine On.mp3
│ │ └── 02 - Have a Cigar.mp3
│ ├── CD2/
│ │ └── 10 - Comfortably Numb.mp3
│ └── Pink Floyd.m3u ← erzeugte Playlist (alle Tracks aus CD1+CD2)
├── Dave Brubeck Quartet/
│ ├── 01 - Blue Rondo.flac
│ └── Dave Brubeck Quartet.m3u
└── Musik.m3u ← nur mit --root-playlist
- Versteckte Ordner (
.oder_als Präfix) werden übersprungen. - Bestehende
.m3u/.m3u8-Dateien werden vor dem Schreiben gelöscht. - Ordner ohne Mediendateien werden still übersprungen.
Metadaten-Verarbeitung
Das Skript versucht für jeden Track sinnvolle Werte für title, artist, album, albumartist, tracknumber, discnumber und date zu ermitteln.
Quellen (Priorität: Tag > Dateiname > Ordnername):
-
ID3/FLAC/MP4-Tags via Mutagen
-
Dateiname-Parsing nach diesen Mustern (spezifischste zuerst):
Muster Beispiel Ergebnis D-TT - Titel2-07 - Finale.mp3disc=2, track=7, title=Finale TT - Artist - Titel07 - Pink Floyd - Shine.mp3track=7, artist=Pink Floyd, title=Shine TT - Titel07 - Shine.mp3track=7, title=Shine Artist - TitelPink Floyd - Shine.mp3artist=Pink Floyd, title=Shine -
Disc-Nummer aus Unterordnernamen wie
CD1,Disc 2,Disk_3 -
Album-Name aus dem Ordnernamen
albumartist-Harmonisierung:
- ≥ 3 verschiedene Artists →
Various Artists - 1–2 Artists → Mehrheits-Artist
- Tracks mit bereits gesetztem
albumartist-Tag werden nicht überschrieben.
Konflikte (z. B. Title im Tag weicht vom Dateinamen ab) werden im CSV-Report markiert.
CSV-Report
Felder: status, path, title, artist, album, albumartist, duration, conflicts, notes
status ist ok, changed oder conflict.
python3 jellyfin_playlist_generator_v9.py --report report.csv /mnt/Musik
Unterstützte Formate
Audio: .mp3 .flac .m4a .aac .ogg .opus .wav .wma .aiff .ape
Video: .mp4 .mkv .avi .mov .wmv .flv .webm .m4v .mpeg .mpg .3gp
Tests
python3 test_suite_v9.py
27 Tests: Unit-Tests für Parsing/Enrichment und Integrationstests für alle CLI-Optionen.
Zusammenfassung-Output
Am Ende jedes Laufs:
========================================
✅ Zusammenfassung:
🗑️ Playlists gelöscht: 209
📁 Root-Verzeichnisse verarbeitet: 1
💿 Album-Verzeichnisse verarbeitet: 209
🎵 Tracks analysiert: 6745
📝 Album-Playlists erstellt: 209
⚠️ Konflikte gefunden: 3476
🔄 Tags geschrieben: 0
❌ Fehler: 0
========================================