···11+# Mumble server address (host:port).
22+MUMBLE_SERVER=mumble-server:64738
33+44+# Bot display name in mumble.
55+MUMBLE_USERNAME=MusicBot
66+77+# Server password (leave empty if none).
88+MUMBLE_PASSWORD=
99+1010+# Channel to auto-join (slash-separated path, e.g. "Music Room").
1111+# Leave empty to stay in root.
1212+MUMBLE_CHANNEL=
1313+1414+# Accept self-signed TLS certificates (true/false).
1515+MUMBLE_INSECURE=true
···11+# Mumble Music Bot
22+33+A Mumble bot written in Go that streams YouTube audio into a voice channel. Users paste YouTube URLs in chat and the bot plays them using `yt-dlp` + `ffmpeg`.
44+55+## Features
66+77+- Paste a YouTube URL in chat to play audio
88+- Song queue with auto-advance
99+- Chat commands: `!skip`, `!stop`, `!queue`, `!np`, `!vol <0-100>`, `!help`
1010+- Fetches and displays video titles
1111+- Configurable via environment variables
1212+1313+## Building
1414+1515+The bot is packaged as a Docker image. Build it from this directory:
1616+1717+```bash
1818+# Linux / macOS
1919+./build.sh
2020+2121+# Windows (PowerShell)
2222+.\build.ps1
2323+```
2424+2525+This produces an image tagged `mumble-music-bot:latest`.
2626+2727+## Deployment
2828+2929+The image is self-contained — it includes `ffmpeg`, `yt-dlp`, and the compiled bot binary. No files from this repository are needed at the deployment location, only the image and your configuration.
3030+3131+### Adding to an existing Docker Compose stack
3232+3333+In your compose file (wherever your Mumble server is defined), add the bot as a service referencing the built image:
3434+3535+```yaml
3636+services:
3737+ mumble-server:
3838+ # ... your existing mumble server config ...
3939+4040+ mumble-bot:
4141+ image: mumble-music-bot
4242+ restart: unless-stopped
4343+ environment:
4444+ MUMBLE_SERVER: mumble-server:64738
4545+ MUMBLE_USERNAME: MusicBot
4646+ MUMBLE_PASSWORD: your-server-password
4747+ MUMBLE_INSECURE: "true"
4848+ depends_on:
4949+ - mumble-server
5050+```
5151+5252+Alternatively, use an env file:
5353+5454+```yaml
5555+ mumble-bot:
5656+ image: mumble-music-bot
5757+ restart: unless-stopped
5858+ env_file: ./mumble-bot.env
5959+ depends_on:
6060+ - mumble-server
6161+```
6262+6363+## Configuration
6464+6565+All configuration is done through environment variables:
6666+6767+| Variable | Default | Description |
6868+|---|---|---|
6969+| `MUMBLE_SERVER` | `localhost:64738` | Mumble server address (`host:port`) |
7070+| `MUMBLE_USERNAME` | `MusicBot` | Bot display name |
7171+| `MUMBLE_PASSWORD` | *(empty)* | Server password (leave empty if none) |
7272+| `MUMBLE_CHANNEL` | *(empty)* | Channel to auto-join (e.g. `Music Room`). Empty = stay in root |
7373+| `MUMBLE_INSECURE` | `false` | Accept self-signed TLS certificates |
7474+7575+See [.env.example](.env.example) for a template.
7676+7777+## Chat Commands
7878+7979+| Command | Description |
8080+|---|---|
8181+| *(YouTube URL)* | Queue and play a YouTube video |
8282+| `!skip` | Skip the current track |
8383+| `!stop` | Stop playback and clear the queue |
8484+| `!queue` / `!q` | Show the current queue |
8585+| `!np` / `!nowplaying` | Show what's currently playing |
8686+| `!vol <0-100>` | Set playback volume |
8787+| `!help` | Show available commands |
8888+8989+## Project Structure
9090+9191+```
9292+├── cmd/bot/main.go # Entrypoint
9393+├── internal/
9494+│ ├── bot/
9595+│ │ ├── bot.go # Mumble connection and lifecycle
9696+│ │ └── handler.go # Chat command handling and URL parsing
9797+│ └── player/
9898+│ ├── player.go # Audio streaming (yt-dlp → ffmpeg → Mumble)
9999+│ └── queue.go # Thread-safe song queue
100100+├── Dockerfile # Multi-stage build (Go builder + Alpine runtime)
101101+├── build.sh / build.ps1 # Image build scripts
102102+├── .env.example # Configuration template
103103+└── README.md
104104+```