docs: update Mumble docs for pymumble transport

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-21 23:16:56 +01:00
parent d884d2bb55
commit eae36aa1f9
3 changed files with 26 additions and 34 deletions

View File

@@ -4,10 +4,10 @@
| Pri | Status | Task | | Pri | Status | Task |
|-----|--------|------| |-----|--------|------|
| P0 | [x] | `src/derp/opus.py` -- ctypes libopus encoder (zero Python deps) | | P0 | [x] | `src/derp/mumble.py` -- rewrite to pymumble transport (voice + text) |
| P0 | [x] | `src/derp/mumble.py` -- voice varint, voice packet, PCM scaling, stream_audio |
| P0 | [x] | `plugins/music.py` -- play/stop/skip/queue/np/volume commands | | P0 | [x] | `plugins/music.py` -- play/stop/skip/queue/np/volume commands |
| P1 | [x] | Tests: `test_opus.py`, `test_mumble.py` voice additions, `test_music.py` | | P0 | [x] | Container patches for pymumble ssl + opuslib musl |
| P1 | [x] | Tests: `test_mumble.py` (62 cases), `test_music.py` (28 cases) |
| P2 | [x] | Documentation update (USAGE.md, CHEATSHEET.md) | | P2 | [x] | Documentation update (USAGE.md, CHEATSHEET.md) |
## Previous Sprint -- v2.2.0 Configurable Proxy (2026-02-21) ## Previous Sprint -- v2.2.0 Configurable Proxy (2026-02-21)

View File

@@ -529,20 +529,19 @@ split at 4096 chars. IRC-only commands are no-ops. ~90% of plugins work.
# config/derp.toml # config/derp.toml
[mumble] [mumble]
enabled = true enabled = true
proxy = true # SOCKS5 proxy for TCP proxy = false # pymumble connects directly
host = "mumble.example.com" host = "mumble.example.com"
port = 64738 port = 64738
username = "derp" username = "derp"
password = "" password = ""
tls_verify = false # self-signed certs common
admins = ["admin_user"] # Mumble usernames admins = ["admin_user"] # Mumble usernames
operators = [] operators = []
trusted = [] trusted = []
``` ```
TCP/TLS via SOCKS5 proxy by default (`proxy = true`). Minimal protobuf Uses pymumble for protocol handling (connection, voice, Opus encoding).
codec (no external dep). HTML stripped on receive, escaped on send. HTML stripped on receive, escaped on send. IRC-only commands are no-ops.
IRC-only commands are no-ops. ~90% of plugins work. ~90% of plugins work.
## Music (Mumble only) ## Music (Mumble only)

View File

@@ -1480,30 +1480,30 @@ proxy at `127.0.0.1:1080` via `derp.http.urlopen` when `proxy = true`
## Mumble Integration ## Mumble Integration
Connect derp to a Mumble server via TCP/TLS protobuf control channel. Connect derp to a Mumble server with text chat and voice playback.
Text chat only (no voice). TCP is routed through the SOCKS5 proxy when Uses [pymumble](https://github.com/azlux/pymumble) for the Mumble
`proxy = true` (default). No protobuf library dependency -- uses a protocol (connection, SSL, voice encoding). Text commands are bridged
minimal built-in varint/field encoder/decoder for the ~7 message types from pymumble's thread callbacks to asyncio for plugin dispatch.
needed.
### How It Works ### How It Works
The bot connects to the Mumble server over TLS, sends pymumble handles the Mumble protocol: TLS connection, ping keepalives,
Version and Authenticate messages, then enters a read loop. It tracks channel/user tracking, and Opus voice encoding. The bot registers
channels (ChannelState), users (UserState), and dispatches commands callbacks for text messages and connection events, then bridges them
from TextMessage messages through the shared plugin registry. to asyncio via `run_coroutine_threadsafe()`. Voice playback feeds raw
PCM to `sound_output.add_sound()` -- pymumble handles Opus encoding,
packetization, and timing.
### Configuration ### Configuration
```toml ```toml
[mumble] [mumble]
enabled = true enabled = true
proxy = true # Route TCP through SOCKS5 proxy = false # SOCKS5 proxy (pymumble connects directly)
host = "mumble.example.com" # Mumble server hostname host = "mumble.example.com" # Mumble server hostname
port = 64738 # Default Mumble port port = 64738 # Default Mumble port
username = "derp" # Bot username username = "derp" # Bot username
password = "" # Server password (optional) password = "" # Server password (optional)
tls_verify = false # Mumble commonly uses self-signed certs
admins = ["admin_user"] # Mumble usernames admins = ["admin_user"] # Mumble usernames
operators = [] # Mumble usernames operators = [] # Mumble usernames
trusted = [] # Mumble usernames trusted = [] # Mumble usernames
@@ -1511,8 +1511,7 @@ trusted = [] # Mumble usernames
### Mumble Setup ### Mumble Setup
1. **Ensure a Mumble server** (Murmur/Mumble-server) is running and 1. **Ensure a Mumble server** (Murmur/Mumble-server) is running
accessible through the SOCKS5 proxy
2. **Configure the bot** with the server hostname, port, and credentials 2. **Configure the bot** with the server hostname, port, and credentials
@@ -1556,13 +1555,14 @@ unescapes entities. On send, text is HTML-escaped. Action messages use
### Music Playback ### Music Playback
Stream audio from YouTube, SoundCloud, and other yt-dlp-supported sites Stream audio from YouTube, SoundCloud, and other yt-dlp-supported sites
into the Mumble voice channel. Audio is decoded to PCM, encoded to Opus into the Mumble voice channel. Audio is decoded to PCM via a
via system libopus, and transmitted as voice packets over the TCP tunnel. `yt-dlp | ffmpeg` subprocess pipeline; pymumble handles Opus encoding
and voice transmission.
**System dependencies** (must be installed on the host): **System dependencies** (container image includes these):
- `yt-dlp` -- audio stream extraction - `yt-dlp` -- audio stream extraction
- `ffmpeg` -- decode to 48kHz mono s16le PCM - `ffmpeg` -- decode to 48kHz mono s16le PCM
- `libopus.so.0` -- Opus codec (ctypes, no Python binding) - `libopus` -- Opus codec (used by pymumble/opuslib)
``` ```
!play <url> Play audio or add to queue !play <url> Play audio or add to queue
@@ -1572,21 +1572,14 @@ via system libopus, and transmitted as voice packets over the TCP tunnel.
!queue <url> Add to queue (alias for !play) !queue <url> Add to queue (alias for !play)
!np Now playing !np Now playing
!volume [0-100] Get/set volume !volume [0-100] Get/set volume
!testtone Play 3-second 440Hz test tone
``` ```
- Queue holds up to 50 tracks - Queue holds up to 50 tracks
- Volume applies from the next track (default: 50%) - Volume applies from the next track (default: 50%)
- Title resolved via `yt-dlp --get-title` before playback - Title resolved via `yt-dlp --get-title` before playback
- Audio pipeline: `yt-dlp | ffmpeg` subprocess, 20ms Opus frames - Audio pipeline: `yt-dlp | ffmpeg` subprocess, PCM fed to pymumble
- Commands are Mumble-only; `!play` on other adapters replies with an error, - Commands are Mumble-only; `!play` on other adapters replies with an error,
other music commands silently no-op other music commands silently no-op
- Playback runs as an asyncio background task; the bot remains responsive - Playback runs as an asyncio background task; the bot remains responsive
to text commands during streaming to text commands during streaming
### Transport
TCP connections route through the SOCKS5 proxy at `127.0.0.1:1080`
via `derp.http.create_connection` when `proxy = true` (default). Set
`proxy = false` to connect directly. TLS is applied on top of the
socket. Mumble commonly uses self-signed certificates, so `tls_verify`
defaults to `false`.