# Audiofy – Musikwünsche für Partys Gäste scannen einen QR-Code und wünschen sich Songs. Ein **Player** spielt über Spotify zufällige Titel aus einer Grund-Playlist – jeder N-te Titel ist ein Wunsch. Gibt es keine Wünsche, läuft einfach die Playlist weiter. Der Gastgeber steuert alles über einen Admin-Bereich, auch vom Handy. - **Gäste:** Spotify-Suche, Wünschen (optional mit Namen), „Läuft gerade“, Warteschlange – ohne Spotify-Konto - **Schutz:** Zugang nur per Einladungslink/QR-Code, Limit pro Gast, keine Duplikate, Sperrzeit für Wiederholungen, Sperrliste, optional Moderation und Cloudflare Turnstile - **Admin:** Play/Pause/Weiter/Lautstärke, „Als Nächstes spielen“, Not-Aus, Wünsche freigeben/umsortieren/löschen, Gäste sperren, Playlist wechseln, Bluetooth-Lautsprecher suchen und wechseln, Verlauf - **Abwechslung:** Ein Playlist-Titel kommt erst wieder, wenn seit seinem letzten Einsatz mindestens X % der Playlist gelaufen sind (einstellbar, auch über Neustarts); Wünsche haben eine eigene Sperrzeit in Minuten - **Robust:** Ohne Server spielt der Player die Playlist weiter; Bedienung über die normale Spotify-App bleibt möglich; Pause des Gastgebers wird auch über Neustarts respektiert ## Aufbau ``` Gast-Handy ──HTTPS──▶ Server: Caddy → audiofy-web (FastAPI + SQLite) ▲ Player-API (Bearer-Token) │ nur ausgehend vom Player Player: raspotify (Spotify Connect) + audiofy-controller └─▶ Bluetooth-Lautsprecher (BlueALSA) oder Kabel/HDMI/USB (ALSA) ``` | Rolle | Läuft auf | Braucht | |---|---|---| | **Server** | VPS, Heimserver, VM … | Debian 12+, öffentliche (Sub-)Domain, Ports 80/443 | | **Player** | Raspberry Pi, Mini-PC, VM mit Audio … | Debian 12+ (arm64/armhf/amd64), Lautsprecher, Internet | Beide Rollen können auch auf demselben Gerät laufen. Der Player braucht **keine** Portfreigabe am Router. ## Voraussetzungen 1. **Spotify Premium** für das Konto, das abspielt. 2. **Spotify-App** auf : - App anlegen (Web API), Redirect-URI **`http://127.0.0.1:8888/callback`** eintragen - unter „User Management“ das eigene Spotify-Konto eintragen - Client ID und Client Secret bereithalten 3. Eine **eigene Playlist** als Grund-Playlist (im Development Mode lassen sich nur eigene Playlists lesen). 4. Für den Server eine **Domain**, deren A/AAAA-Record auf den Server zeigt. ## Installation **Per Einzeiler** – als Benutzer mit sudo-Rechten (oder als root) in einem Terminal: ``` curl -fsSL https://git.wind8000.de/0/audiofy/raw/branch/main/install/get.sh | bash -s -- server curl -fsSL https://git.wind8000.de/0/audiofy/raw/branch/main/install/get.sh | bash -s -- player ``` Das Startskript installiert bei Bedarf `git`, holt Audiofy nach `/usr/local/src/audiofy` und startet das passende Install-Skript. Später aktualisieren: denselben Befehl mit `--update` am Ende (`… | bash -s -- server --update`). Vorsichtiger – erst ansehen, dann ausführen: ``` curl -fsSLO https://git.wind8000.de/0/audiofy/raw/branch/main/install/get.sh less get.sh bash get.sh server # bzw. player ``` **Oder von Hand:** Repository klonen (`git clone https://git.wind8000.de/0/audiofy.git`) und die Install-Skripte direkt starten: **1. Server** ``` install/install-server.sh ``` Fragt Domain, E-Mail für Let's Encrypt, Spotify-Zugang und Playlist ab, richtet Dienst-Benutzer, Python-Umgebung, systemd-Dienst und Caddy (HTTPS) ein und optional Firewall (ufw), fail2ban und automatische Sicherheitsupdates. Danach folgen der Spotify-Login (nur für die Suche) und das Admin-Passwort. Am Ende zeigt das Skript, wie du den **`PLAYER_API_TOKEN`** für den Player abrufst. **2. Player** ``` install/install-player.sh ``` Fragt Gerätename, Audio-Ausgabe (Bluetooth oder ALSA), Server-Adresse, `PLAYER_API_TOKEN`, Spotify-Zugang und Playlist ab, installiert raspotify, koppelt auf Wunsch gleich den Bluetooth-Lautsprecher und richtet den Controller als Dienst ein. Danach folgt der Spotify-Login für die Wiedergabe-Steuerung. **3. Einmalig in der Spotify-App** das neue Gerät (Standard: „Audiofy“) auswählen – im selben Netz wie der Player. Damit speichert raspotify seine Anmeldung und ist nach jedem Neustart von selbst wieder da. **4. Admin-Bereich** unter `https:///admin` öffnen, unter **Gäste** den Gastzugang einschalten und den QR-Code zeigen oder ausdrucken. ## Betrieb | Aufgabe | Befehl | |---|---| | Status | `systemctl status audiofy-web` (Server) · `systemctl status audiofy-controller raspotify` (Player) | | Logs live | `journalctl -u audiofy-web -f` · `journalctl -u audiofy-controller -f` | | Neustart | `sudo systemctl restart audiofy-web` bzw. `audiofy-controller` | | Update | Einzeiler mit `--update` – oder im Repository `git pull && install/install-server.sh --update` bzw. `install/install-player.sh --update` | `--update` ersetzt nur Code, Python-Umgebung und Dienstdatei; Konfiguration, Datenbank, Caddy, Firewall und raspotify bleiben unverändert. **Dateien** | Pfad | Inhalt | |---|---| | `/opt/audiofy/app` | Code (gehört root, der Dienst darf nur lesen) | | `/opt/audiofy/.env` (Server) | Geheimnisse: Spotify, Admin-Passwort-Hash, Turnstile, `PLAYER_API_TOKEN` | | `/opt/audiofy/data/audiofy.db` (Server) | Wünsche, Verlauf, Einstellungen | | `/opt/audiofy/config/.env` (Player) | Geheimnisse: Spotify, `SERVER_URL`, `PLAYER_API_TOKEN`, Lautsprecher | Die `.env`-Dateien gehören dem Dienst-Benutzer `audiofy` (Rechte 600). **Sichere sie an einem sicheren Ort** (z. B. Passwort-Manager) – sie stehen bewusst nicht im Repository. **Verwaltung** (interaktiv, im eigenen Terminal): ``` # Server: Admin-Passwort bzw. Turnstile-Schlüssel ändern sudo -u audiofy /opt/audiofy/.venv/bin/python /opt/audiofy/app/verwaltung.py passwort --env /opt/audiofy/.env sudo -u audiofy /opt/audiofy/.venv/bin/python /opt/audiofy/app/verwaltung.py turnstile --env /opt/audiofy/.env # Spotify-Login erneuern – Server bzw. Player sudo -u audiofy /opt/audiofy/.venv/bin/python /opt/audiofy/app/auth.py --profil server --env /opt/audiofy/.env sudo -u audiofy /opt/audiofy/.venv/bin/python /opt/audiofy/app/auth.py --profil player --env /opt/audiofy/config/.env ``` Danach den jeweiligen Dienst neu starten. **Datenbank sichern** (Server): ``` sudo -u audiofy sqlite3 /opt/audiofy/data/audiofy.db ".backup /opt/audiofy/data/sicherung.db" ``` ## Server härten (empfohlen, von Hand) Das Install-Skript ändert die SSH-Konfiguration bewusst **nicht** – damit sperrt man sich leicht aus. Vorlage: `install/vorlagen/sshd-10-audiofy.conf` (anderer Port, nur Schlüssel, kein root, nur ein Admin-Benutzer). Vorgehen: 1. Eigenen Admin-Benutzer mit sudo anlegen, SSH-Schlüssel hinterlegen, Login testen. 2. Neuen Port in ufw **und** einer eventuellen Cloud-Firewall öffnen. 3. Vorlage ausgefüllt nach `/etc/ssh/sshd_config.d/10-audiofy.conf` legen, `sudo sshd -t`, `sudo systemctl restart ssh`. 4. **In einer zweiten Sitzung** testen – die alte bleibt offen, bis es klappt. 5. Erst dann den alten Port in ufw/Cloud-Firewall schließen und fail2ban auf den neuen Port umstellen. ## Fehlerbehebung | Problem | Ursache / Lösung | |---|---| | Keine Musik, Log: „Lautsprecher nicht verbunden“ | Lautsprecher einschalten – der Player verbindet ihn neu und startet die Musik von selbst. | | Lautsprecher verbindet sich nicht mehr („Permission denied“) | Kopplung verloren. Im Admin unter Einstellungen → Lautsprecher neu suchen und verbinden (Lautsprecher im Kopplungsmodus). | | „Gerät nicht gefunden“ | `systemctl status raspotify`. Nach einer Neuinstallation einmal in der Spotify-App das Gerät auswählen. | | Admin: „Player offline“ | `systemctl status audiofy-controller`, Internet des Players prüfen. Die Musik läuft trotzdem mit der Playlist weiter. | | Admin: „Grund-Playlist nicht lesbar“ | Nur eigene Playlists funktionieren (Spotify Development Mode). | | Befehle „No active device“ | Spotify hatte kein aktives Gerät; „Play“ startet dann die Playlist auf dem Player. | | Nach Neustart bleibt es still | Gewollt, wenn vorher pausiert oder Not-Aus aktiv war – im Admin „Play“ bzw. „Freigeben“. | | Musik stockt während der Lautsprecher-Suche | Normal: WLAN und Bluetooth teilen sich oft einen Funkchip. | | Gäste: „Kein Zugang“ | Gastzugang im Admin eingeschaltet? Nach „Neuen Link erzeugen“ gilt nur der neue QR-Code. | | Zu viele Admin-Login-Versuche | 15 Minuten warten (max. 5 Versuche pro IP). | ## Spotify-Hinweise Audiofy nutzt die Spotify Web API im **Development Mode** (nicht kommerziell). Dort gilt: Premium für den App-Besitzer, Nutzer-Allowlist, höchstens 10 Suchtreffer, nur eigene Playlists lesbar. Gäste melden sich nie bei Spotify an; Server und Player nutzen je einen eigenen Refresh-Token desselben Kontos. ## Entwicklung ``` cd server && python3 -m venv .venv && .venv/bin/pip install -r requirements.txt pytest .venv/bin/python -m pytest -q # Server cd ../player && python3 -m venv .venv && .venv/bin/pip install -r requirements.txt pytest .venv/bin/python -m pytest -q tests # Player (Wiederholungsregel) ``` ## Lizenz Noch nicht festgelegt.