Einleitung: „Ich hatte Langeweile.“
Eigentlich wollte ich nur kurz meinen Blog reparieren, der wegen eines kaputten WordPress-Themes offline war. Doch wie das so ist: Der Blog blieb erstmal liegen, und stattdessen hat es meine Synology NAS getroffen. In einer Mischung aus Langeweile, technischem Ehrgeiz und Frust über die chaotische Musikbibliothek startete ich ein neues Projekt mit Beets. Dieses Tool hatte ich zwar schon früher installiert, aber nie wirklich zum Laufen gebracht. Jetzt, mit etwas mehr Zeit und der Hilfe von KI, habe ich das Projekt „Musiksammlung neu sortieren“ endlich durchgezogen.
Vorbereitung: Was ich wollte
- Alle Musikdateien zentral in
/volume1/music
- Ein Zwischenordner
/volume1/Tausch/Import
für neue Musik - Automatisches Importieren, Taggen, Umbenennen, Verschieben
- Keine Duplikate mehr, keine kaputten Tags, keine überflüssigen Dateien
- Zugriff auf die Musik per Browser, Handy oder App
- Kein Spotify oder Apple Music mehr notwendig
Beets: Die Magie hinter dem Chaos
Beets installieren und vorbereiten
python3 -m venv ~/beets-venv
source ~/beets-venv/bin/activate
pip install beets
Konfigurationsdatei
Die config.yaml
liegt unter ~/.config/beets/config.yaml
:
directory: /volume1/music
library: /volume1/music/musiclibrary.db
import:
move: yes
write: yes
incremental: yes
incremental_skip_later: yes
timid: no
log: /volume1/music/beets-import.log
paths:
default: "$albumartist/$album%aunique{}/$track $title"
singleton: "Non-Album/$artist - $title"
comp: "Compilations/$album/$track $title"
albumtype:soundtrack: "Soundtracks/$album/$track $title"
plugins:
- fetchart
- embedart
- chroma
- web
- info
- play
fetchart:
auto: yes
minwidth: 300
maxwidth: 1000
sources: coverart itunes amazon
embedart:
auto: yes
ifempty: yes
remove_art_file: no
filename: cover
chroma:
auto: yes
api_key: MEIN_ACOUSTID_API_KEY
web:
host: 0.0.0.0
port: 8337
ui:
color: yes
terminal_width: 100
ignore:
- .DS_Store
- Thumbs.db
- @eaDir
Was macht chroma:
?
Das chroma
-Plugin in Beets macht akustisches Fingerprinting. 🎵🔍
Konkret heisst das:
-
Es analysiert die Audioinhalte deiner Musikdateien, nicht nur Dateinamen oder Metadaten.
-
Es sendet daraus generierte Fingerprints (eine Art digitaler Audio-Fingerabdruck) an den Dienst AcoustID.
-
AcoustID gleicht diese Fingerprints mit einer Online-Datenbank ab.
-
Wenn ein Match gefunden wird, liefert Beets (über MusicBrainz) die korrekten Metadaten: Artist, Album, Tracknummer, Titel, Jahr, usw.
-
Beets kann dann die Datei mit diesen Infos taggen und korrekt einsortieren.
Vorteile:
✅ Korrigiert auch falsch benannte oder ungetaggte Dateien
✅ Funktioniert bei Dateien mit kryptischen Dateinamen
✅ Erkennt sogar dieselbe Aufnahme in unterschiedlicher Bitrate
Wichtig:
-
Du brauchst dafür einen AcoustID API Key (kostenlos).
-
Die Analyse läuft bei aktiviertem Plugin automatisch beim Import, wenn
chroma: auto: yes
gesetzt ist. -
fpcalc
muss installiert sein, da es die Fingerprints lokal erzeugt.
Automatisierung mit einem Watchdog-Script
📄 /var/services/homes/oliver/beets_watchdog.sh
#!/bin/sh
export PATH="/usr/local/bin:/opt/bin:/bin:/usr/bin:$PATH"
INCOMING_DIR="/volume1/Tausch/Import"
LOGFILE="/volume1/music/beets-watchdog.log"
STATEFILE="/volume1/music/.last-import"
MUSIC_EXTENSIONS="mp3|flac|ogg|wav|aac|m4a|alac|ape|dsf"
# Aktivieren des Python-venv
. /var/services/homes/oliver/beets-venv/bin/activate
# Prüfen, ob ein Beets-Import läuft
if ps aux | grep "[b]eet import" > /dev/null; then
echo ">>> Beets-Import läuft bereits – $(date)" >> "$LOGFILE"
exit 0
fi
# Änderungszeitpunkt im Importordner
LAST_MOD=$(find "$INCOMING_DIR" -type f -printf '%T@\n' 2>/dev/null | sort -n | tail -1 | cut -d. -f1)
LAST_RUN=$(cat "$STATEFILE" 2>/dev/null || echo 0)
# Logfile kürzen (älter als 3 Tage löschen)
if [ -f "$LOGFILE" ]; then
NOW=$(date +%s)
TMPLOG=$(mktemp)
while IFS= read -r line; do
TS=$(echo "$line" | grep -oE "[A-Z][a-z]{2} [A-Z][a-z]{2} [ 0-9]{2} [0-9:]{8} [A-Z]{3} [0-9]{4}" | tail -1)
[ -n "$TS" ] && LINE_TS=$(date -d "$TS" +%s 2>/dev/null)
[ -z "$LINE_TS" ] && echo "$line" >> "$TMPLOG" && continue
AGE=$((NOW - LINE_TS))
[ "$AGE" -lt 259200 ] && echo "$line" >> "$TMPLOG"
done < "$LOGFILE" mv "$TMPLOG" "$LOGFILE" fi # Starte Import, wenn es neue Dateien gibt if [ "$LAST_MOD" -gt "$LAST_RUN" ]; then echo ">>> Neuer Inhalt erkannt – Starte Import: $(date)" >> "$LOGFILE"
beet import "$INCOMING_DIR" >> "$LOGFILE" 2>&1 && date +%s > "$STATEFILE"
# Neue Titel & Ordner zählen
NEW_COUNT=$(find "$INCOMING_DIR" -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.m4a" -o -iname "*.ogg" \) | wc -l)
NEW_DIRS=$(find "$INCOMING_DIR" -mindepth 1 -type d | wc -l)
# DSM Notification (wenn vorhanden)
if [ -x /usr/syno/bin/synodsmnotify ]; then
/usr/syno/bin/synodsmnotify SYNO.SDS.MediaServer.Application \
"Beets-Import abgeschlossen" \
"Import: $NEW_COUNT Titel in $NEW_DIRS Ordnern"
fi
# 🧹 Ordner ohne Musikdateien löschen (nur Reste wie .jpg/.nfo)
find "$INCOMING_DIR" -mindepth 1 -type d | while read -r dir; do
if ! find "$dir" -maxdepth 1 -type f | grep -Ei "\.($MUSIC_EXTENSIONS)$" >/dev/null; then
echo "🧹 Entferne leeren Musikordner (nur Reste): $dir" >> "$LOGFILE"
rm -rf "$dir"
fi
done
else
echo "Keine neuen Dateien – Stand: $(date)" >> "$LOGFILE"
fi
Gestartet mit pm2
:
pm2 start /pfad/zum/beets_watchdog.sh --name beets-watchdog --interpreter=/bin/sh --cron "*/15 * * * *"
pm2 save







Emby: Die Streaming-Schaltzentrale
- Webplayer, Apps, DLNA, Chromecast, AirPlay
- Automatische Bibliothek nach Beets-Import
- Keine Cloud – alles lokal & privat
- Perfekt integriert, keine Online-Tags nötig
Nach 3 Tagen Dauer-Import war alles erledigt:
- Getaggte, umbenannte und sortierte Musik
- Kein Chaos mehr
- Musik streambar & durchsuchbar
Vorteile
- Unabhängig von Spotify & Co.
- Volle Kontrolle
- Lokale Qualität & Performance
Ohne KI? Hätte ich’s vermutlich wieder aufgegeben.
Was mir dieses Mal wirklich geholfen hat: Künstliche Intelligenz. Der Clou: Ich konnte jede noch so kryptische Fehlermeldung einfach der KI vorsetzen – und bekam in Sekunden eine Lösung.
Ob falsch eingerückte YAML, fehlende Abhängigkeiten oder benutzerdefinierte Bash-Skripte – die KI war mein ständiger Begleiter. Ohne sie wäre ich sicher wieder irgendwo zwischen /usr/bin/env
und pip install
hängen geblieben. Auch die „schlauen“ Vorschläge fanden Anklang.