Projekt: Meine Musiksammlung in neuem Glanz

Projekt: Meine Musiksammlung in neuem Glanz

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.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

iPhone 16 als perfekte Point‑and‑Shoot‑Kamera – Warum Kompaktkameras ausgedient haben Previous post Die perfekte Point‑and‑Shoot‑Kamera
Next post Kaffee & Kuchentour