jukebox-vibe/README.md
2026-03-05 11:13:03 +01:00

7 KiB
Raw Permalink Blame History

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)
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:

  1. Startup: Hintergrund-Sync normalisiert alle uncached Sounds
  2. Cache Hit: Gecachte PCM-Datei wird direkt gestreamt (kein ffmpeg, instant)
  3. Cache Miss: ffmpeg streamt live zum Player UND schreibt gleichzeitig in Cache
  4. Upload: Neue Dateien werden sofort im Hintergrund normalisiert

Voice Connection

3-stufiges Recovery bei Verbindungsproblemen:

  1. Wait for Ready (15s Timeout)
  2. Rejoin im selben Channel (15s Timeout)
  3. 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