A turnkey, lightweight, and secure Dockerized soundboard solution that connects to a Mumble server. It features a nostalgic late-90s web interface to trigger local sound files and stream YouTube audio directly into your voice channel via a privacy-respecting Invidious proxy.
- Retro 90s Design: Web-safe colors, sticky control decks, marquees, and "Under Construction" GIFs.
- High-Quality Audio: Streams at 96kbps (Music Quality) to Mumble, using a jitter-free threading engine.
- Universal Playback:
- Local Files: Plays
.mp3,.wav,.ogg,.m4a,.flacfrom a mounted folder. - YouTube Proxying: The system is designed to never contact YouTube directly. It utilizes an Invidious instance (e.g.,
tube.wxbu.de) to resolve streams via API, ensuring your server IP remains hidden from Google and bypassing "Sign in to confirm you're not a bot" blocks.
- Local Files: Plays
- Real-time Controls:
- Volume Slider.
- Global Stop Button (Kill switch).
- "ON AIR" visual indicator.
- Search-as-you-type: Instantly filter the soundboard grid by typing.
- Statistics: Tracks play counts for both local files and YouTube links in a persistent SQLite database.
- Security Hardened: Runs as a non-root user (UID 1000) inside the container with read-only root filesystem access.
This entire solution—from the Python audio mixing engine and threading logic to the retro HTML/CSS design and Docker security hardening—was architected and generated by Google Gemini. It serves as a demonstration of using AI as a master architect for full-stack application development.
- A running Mumble Server (Murmur).
- Docker installed on the host machine.
- (Optional) An Invidious instance for YouTube proxying.
Create a folder for the project and two subfolders for persistence:
mkdir -p retro-soundboard/sounds
mkdir -p retro-soundboard/dataPlace your audio files inside the sounds/ folder.
Run the container using the following command (replace environment variables with your actual server details):
docker run -d \
--name retro-soundboard \
--restart always \
--user 1000:1000 \
-p 5000:5000 \
-v $(pwd)/sounds:/app/sounds \
-v $(pwd)/data:/app/data \
-e MUMBLE_HOST="your.mumble-server.com" \
-e MUMBLE_PORT=64738 \
-e MUMBLE_USER="DJ_Retro" \
-e MUMBLE_PASSWORD="yourpassword" \
-e MUMBLE_CHANNEL="Music Room" \
-e INVIDIOUS_HOST="[https://tube.wxbu.de](https://tube.wxbu.de)" \
-e INVIDIOUS_USER="optional_user" \
-e INVIDIOUS_PASS="optional_pass" \
-e ALLOWED_EXTENSIONS="mp3,wav,m4a,ogg" \
ghcr.io/YOUR_USERNAME/YOUR_REPO:latestNote: Ensure the host folders sounds and data are owned by UID 1000 (chown -R 1000:1000 ./sounds ./data).
Open your browser and navigate to: http://your-server-ip:5000
| Variable | Default | Description |
|---|---|---|
| MUMBLE_HOST | localhost | Address of the Mumble Server. |
| MUMBLE_PORT | 64738 | Port of the Mumble Server. |
| MUMBLE_USER | SoundBot | Username the bot will use. |
| MUMBLE_PASSWORD | None | Password (if server requires it). |
| MUMBLE_CHANNEL | None | Channel to join automatically (Case Sensitive). |
| INVIDIOUS_HOST | None | Base URL of Invidious instance (e.g. https://tube.wxbu.de). |
| INVIDIOUS_USER | None | Basic Auth Username for Invidious (if protected). |
| INVIDIOUS_PASS | None | Basic Auth Password for Invidious. |
This application implements a strict proxying policy. If INVIDIOUS_HOST is configured, the system will resolve video streams via the Invidious API using ?local=true. This forces the Invidious server to proxy the traffic, meaning your server never establishes a direct connection to Google/YouTube servers, protecting your IP address and preventing 403/Bot bans.
Backend: Python 3.11, Flask.
Audio Engine: ffmpeg (streaming/mixing) + pymumble (transmission).
Downloader: yt-dlp (configured for API-based stream resolution).
Database: SQLite3.
Frontend: HTML5/CSS3`(Retro Table Layout).
Enjoy the noise! 📢