Audiofy – Musikwünsche für Partys
Server (Website, Admin-Bereich, Player-API) und Player (raspotify + Controller) mit Install-Skripten für Debian-Systeme. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# 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
|
||||
- **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 <https://developer.spotify.com/dashboard>:
|
||||
- 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
|
||||
|
||||
Repository auf das jeweilige Gerät holen (`git clone …`) und als Benutzer mit sudo-Rechten
|
||||
(oder als root) ausführen.
|
||||
|
||||
**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://<domain>/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 | `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
|
||||
```
|
||||
|
||||
## Lizenz
|
||||
|
||||
Noch nicht festgelegt.
|
||||
Reference in New Issue
Block a user