7 KiB
7 KiB
Jukebox Vibe – Discord Soundboard
Self-hosted Discord Soundboard mit Web-UI. Spielt Sounds in Discord Voice Channels, verwaltet per Browser. Dockerized, ein Container, fertig.
Tech Stack
| Komponente | Technologie |
|---|---|
| Backend | Node.js 20, Express, TypeScript, discord.js 14 |
| Voice | @discordjs/voice 0.19, @discordjs/opus, DAVE E2EE (@snazzah/davey) |
| Frontend | React 18, Vite, TypeScript, Custom CSS |
| Audio | ffmpeg (EBU R128 Loudnorm), yt-dlp |
| Deployment | Multi-Stage Dockerfile, GitLab CI/CD (Kaniko) |
Features
Soundboard
- MP3/WAV Playback in Discord Voice Channels
- Loudness Normalization (EBU R128) mit PCM-Cache fuer Instant-Playback
- Per-Guild Volume (0-100%), live adjustable, persistiert
- Party Mode – zufaellige Sounds alle 30-90 Sekunden
- Stop/Panic – sofortiger Playback-Stop fuer alle
Discord Bot
- Entrance Sounds – persoenlicher Sound beim Channel-Join
- Exit Sounds – Sound beim Disconnect (nicht bei Channel-Wechsel)
- DM Upload – Sounds per Direktnachricht an den Bot hochladen
- Voice Resilience – 3-Tier Reconnect mit Exponential Backoff
Web-UI
- Sound Grid mit klickbaren Cards
- Suche mit optionalem Fuzzy-Matching
- Ordner-Filter mit farbigen Chips
- Favoriten (Cookie-basiert)
- Kategorien und Badges (Admin-verwaltet)
- Channel-Selector gruppiert nach Guild
- Now Playing Anzeige mit Wellenform-Animation
- 5 Themes – Discord, Midnight, Forest, Sunset, Ocean
- Card-Size Slider (80-160px)
- Drag & Drop Upload (Admin)
- MP3-URL Import – direkter Download und Playback
- Real-Time Sync via Server-Sent Events (SSE)
Admin
- Login mit HMAC-SHA256 Token (HttpOnly Cookie, 7 Tage)
- Bulk Delete / Rename von Sounds
- Upload bis zu 20 Dateien (je max. 50MB)
- Kategorien erstellen, bearbeiten, loeschen, zuweisen
- Custom Badges zuweisen/entfernen
Quickstart
Voraussetzungen
- Docker
- Discord Bot Token mit Intents:
Guilds,GuildVoiceStates,GuildMembers,DirectMessages,MessageContent
Setup
git clone https://git.daddelolymp.de/root/jukebox-vibe.git
cd jukebox-vibe
cp .env.example .env
# .env anpassen (DISCORD_TOKEN, ADMIN_PWD)
docker compose up -d
Docker Run (ohne Compose)
docker run -d \
--name jukebox \
-p 8199:8080 \
-e DISCORD_TOKEN=dein_token \
-e ADMIN_PWD=dein_passwort \
-v $(pwd)/sounds:/data/sounds \
--restart unless-stopped \
git.daddelolymp.de/root/jukebox-vibe:latest
Konfiguration
| Variable | Default | Beschreibung |
|---|---|---|
DISCORD_TOKEN |
erforderlich | Discord Bot Token |
ADMIN_PWD |
'' |
Admin-Passwort fuer Web-UI |
PORT |
8080 |
Server Port |
SOUNDS_DIR |
/data/sounds |
Sound-Verzeichnis (Docker Volume) |
ALLOWED_GUILD_IDS |
'' |
Komma-getrennte Guild-IDs (leer = alle) |
NORMALIZE_ENABLE |
true |
Loudness Normalization an/aus |
NORMALIZE_I |
-16 |
Ziel-Lautstaerke in LUFS |
NORMALIZE_LRA |
11 |
Loudness Range |
NORMALIZE_TP |
-1.5 |
True Peak in dBTP |
NORM_CONCURRENCY |
2 |
Parallele ffmpeg-Prozesse |
Bot Commands
Alle Commands per DM an den Bot oder im Server-Chat:
| Command | Beschreibung |
|---|---|
?help |
Hilfe anzeigen |
?list |
Alle Sounds auflisten |
?entrance <datei> |
Entrance-Sound setzen |
?entrance remove |
Entrance-Sound entfernen |
?exit <datei> |
Exit-Sound setzen |
?exit remove |
Exit-Sound entfernen |
Upload via DM: MP3/WAV als Anhang an den Bot senden – wird automatisch gespeichert und normalisiert.
API
Public
GET /api/health Healthcheck + Stats
GET /api/sounds Sound-Liste (query: q, folder, categoryId, fuzzy)
GET /api/analytics Top 10 Most Played, Gesamt-Plays
GET /api/channels Verfuegbare Voice Channels
GET /api/selected-channels Gespeicherte Channel-Auswahl
POST /api/selected-channel Channel-Auswahl setzen
POST /api/play Sound abspielen (body: soundName, guildId, channelId)
POST /api/play-url MP3-URL downloaden und abspielen
POST /api/stop Playback stoppen
GET /api/volume Volume abfragen
POST /api/volume Volume setzen (0-1)
POST /api/party/start Party Mode starten
POST /api/party/stop Party Mode stoppen
GET /api/events SSE Stream (Real-Time Updates)
Admin (Cookie-Auth)
POST /api/admin/login Login (body: password)
POST /api/admin/logout Logout
GET /api/admin/status Auth-Status pruefen
POST /api/upload Dateien hochladen (multipart, max 20x50MB)
POST /api/admin/sounds/delete Sounds loeschen (body: paths[])
POST /api/admin/sounds/rename Sound umbenennen
GET /api/categories Kategorien auflisten
POST /api/categories Kategorie erstellen
PATCH /api/categories/:id Kategorie bearbeiten
DELETE /api/categories/:id Kategorie loeschen
POST /api/categories/assign Kategorien zuweisen
POST /api/badges/assign Badges zuweisen
POST /api/badges/clear Badges entfernen
Sound-Dateien
/data/sounds/
state.json # Persistierter State (Volumes, Plays, Kategorien, etc.)
.norm-cache/ # Normalisierte PCM-Caches
airhorn.mp3 # Sounds im Root
memes/ # Ordner-Struktur (1 Ebene)
bruh.mp3
oof.wav
- Formate:
.mp3,.wav - Ordner werden als Filter-Chips im Frontend angezeigt
.norm-cache/wird automatisch verwaltet (Cache-Invalidierung bei Datei-Aenderung)
Loudness Normalization
Alle Sounds werden per ffmpeg loudnorm (EBU R128) normalisiert:
- Startup: Hintergrund-Sync normalisiert alle uncached Sounds
- Cache Hit: Gecachte PCM-Datei wird direkt gestreamt (kein ffmpeg, instant)
- Cache Miss: ffmpeg streamt live zum Player UND schreibt gleichzeitig in Cache
- Upload: Neue Dateien werden sofort im Hintergrund normalisiert
Voice Connection
3-stufiges Recovery bei Verbindungsproblemen:
- Wait for Ready (15s Timeout)
- Rejoin im selben Channel (15s Timeout)
- Destroy + Fresh Join (15s Timeout)
Lifecycle-Handler mit:
- Max 3 Reconnect-Versuche mit Exponential Backoff
- Anti-Reentrancy Guard gegen Endlosschleifen
- Automatisches State-Cleanup bei totalem Verbindungsverlust
Projektstruktur
jukebox-vibe/
server/
src/index.ts # Server + Discord Bot (Hauptdatei)
package.json
tsconfig.json
web/
src/
App.tsx # React SPA
styles.css # Themes + Layout
types.ts # TypeScript Types
package.json
vite.config.ts
Dockerfile # Multi-Stage Build (web + server + runtime)
docker-compose.yml
.gitlab-ci.yml # CI/CD Pipeline (Kaniko)
.env.example
CI/CD
GitLab CI baut automatisch bei jedem Push:
| Branch | Image Tag |
|---|---|
main |
:main, :latest, :sha |
nightly |
:nightly, :sha |
| andere | :<branch-name>, :sha |
Registry: git.daddelolymp.de/root/jukebox-vibe
Lizenz
MIT