:64738

Mumble Bridge

Audio bidireccional → <audio> en browser

Pipeline Completo

 MIC (ALSA)                                         BROWSER (sin JS)
     │                                                    ▲
     ▼                                                    │
 ┌──────────┐    Opus     ┌────────────┐   OGG/HTTP  ┌───┴──────┐
 │ murmurd  │◀═══════════▷│ gumble bot │────────────▷│ <audio>  │
 │ :64738   │  (Mumble    │  ↓ PCM     │  chunked    │ autoplay │
 │          │   protocol) │  ffmpeg    │  transfer   │          │
 └──────────┘             └────────────┘             └──────────┘
                                │
                          Oasis :3000
                          GET /audio

Key Concept: Por Qué Mumble y No Otro

Mumble ya está instalado y corriendo en el SNH (Solar Net Hub). Añadir otro servidor de audio sería desperdiciar RAM en un device de 1 GB. Reutilizar murmurd = +0 MB de RAM nueva para audio.
AlternativaRAM extraBidireccionalTorYa instalado
Mumble (actual)+0 MB✔ nativo✔ TCP tunnel
go2rtc (audio ALSA)~20 MB✘ solo send⚠️
ffmpeg ALSA → OGG directo~15 MB✘ solo send
PulseAudio + HTTP~30 MBComplejo

3 Estrategias para Bridge Mumble → Browser

El browser SIN JS no puede hablar protocolo Mumble. Necesitamos un bridge que: (1) conecta como cliente Mumble, (2) recibe audio Opus, (3) re-empaqueta en OGG y (4) lo sirve como HTTP chunked para <audio src="/audio">.
3A: Bridge HTTP ★3B: mumble-web3C: Cliente nativo
JS en browser✘ No✔ Sí (viola restricción)✘ No
Apps necesariasSolo navegadorSolo navegadorNavegador + Mumble app
Código nuevo~100 lín bridgeInstalar mumble-web + proxy~10 lín (URL mumble://)
Latencia audio~200 ms~50 ms (WebRTC)~20 ms (UDP nativo)
Bidireccional⚠️ Complejo✔ Nativo✔ Nativo
Tor⚠️ (WebRTC→TURN)✔ (TCP tunnel)
Elegida: 3A (bridge HTTP) para la UI unificada del SNH + 3C (cliente nativo) como experiencia premium para el peer remoto.

Implementación del Bridge (Estrategia 3A)

Recomendada: gumble (Go) → ffmpeg pipe
# Bot gumble captura audio del canal → stdout PCM 16-bit 48kHz mono # ffmpeg re-codifica a OGG/Opus para streaming HTTP mumble-audio-bridge --server localhost:64738 --channel "WebRTC" \ | ffmpeg -f s16le -ar 48000 -ac 1 -i pipe:0 \ -c:a libopus -application voip -b:a 32k \ -f ogg pipe:1 \ | serve-as-http --port 3001 --content-type "audio/ogg"
gumble (Go, github.com/layeh/gumble) se compila como binario estático ARM64 (~5 MB). Conecta a murmurd, captura el audio mezclado del canal, y lo escribe a stdout como PCM raw.
Oasis route (/audio)
// Endpoint HTTP mínimo (~30 líneas en Node.js/Koa) app.get('/audio', (req, res) => { res.writeHead(200, { 'Content-Type': 'audio/ogg', 'Transfer-Encoding': 'chunked', 'Cache-Control': 'no-cache' }); bridge.stdout.pipe(res); req.on('close', () => bridge.stdout.unpipe(res)); });
Alternativa legacy: Node.js mumble-client
// node-mumble — ⚠️ no mantenido desde 2019 // bindings nativos rompen con Node.js recientes // Solo referencia; preferir gumble (Go) const mumble = require('mumble'); mumble.connect('mumble://127.0.0.1:64738', (err, conn) => { conn.authenticate('oasis-bridge'); conn.on('voice', (pcmBuffer) => { /* ... */ }); });
⚠️ ffmpeg NO tiene handler nativo mumble:// — el comando ffmpeg -i mumble://... NO funciona sin compilación custom. El pipeline correcto es: bot gumble → stdout PCM → pipe a ffmpeg.

Legitimidad: ¿Es Válido Usar murmurd con un Bot?

Sí. murmurd como bus de audio con un bot bridge es un patrón establecido, no un hack. El protocolo Mumble no distingue entre un cliente humano y un bot — esto es by design.
PrecedenteDescripción
MumbleDJBot Go que inyecta audio (música) en canales Mumble
piepanFramework Lua para scripting de bots Mumble
barnardCliente Mumble CLI en Go (usa gumble)
murmurd ofrece mezclador, Opus, jitter buffer, AGC, cifrado — reimplementar esto sería absurdo cuando ya corre y consume +0 MB extra.

Audio Bidireccional — Opciones

DirecciónMecanismoLatenciaRequiere JS
SNH → Browser (downstream)murmurd → bridge → <audio>~200 ms✘ No
Browser → SNH (upstream via Mumble native)Cliente Mumble nativo en otro device~20 ms✘ No (app nativa)
Browser → SNH (upstream via WebRTC)getUserMedia → node-datachannel → murmurd~100 ms✔ Sí
Para audio upstream SIN JS: el peer usa un cliente Mumble nativo (Plumble en Android, Mumble desktop en PC). Esto bypasa el browser completamente.
Audio upstream VÍA browser requiere getUserMedia (JS). No hay forma de capturar micrófono en HTML puro sin JS. Esto es una limitación del estándar web, no de la arquitectura.

Budget de Latencia — Audio Path

EtapaLatencia
ALSA capture → murmurd~10-20 ms
murmurd Opus encode~5-10 ms
Bridge decode + OGG re-encode~20-40 ms
HTTP chunked transfer (LAN)~5-10 ms
<audio> browser buffering~100-150 ms
TOTAL (downstream)~150-250 ms
Cliente nativo Mumble~20-30 ms
Si la latencia de ~200 ms del bridge HTTP es inaceptable, el peer puede simplemente usar un cliente Mumble nativo con RTT ~20 ms — sin pasar por el browser.

murmurd Config — Ajustes Relevantes

# /etc/mumble-server.ini (fragmento relevante) # Escuchar solo localhost si el bridge es local host=127.0.0.1 port=64738 # Opus siempre (no permitir otros codecs) opusthreshold=0 # Bandwidth: 64kbps basta para voz en LAN bandwidth=64000 # Máx. usuarios (el SNH + bridge + 2-3 peers) users=5 # Deshabilitar text-to-speech, logs pesados, etc. textmessagelength=0 logdays=-1
Si murmurd escucha en 127.0.0.1, los clientes externos entran vía Tor TCP tunnel o SSH port forward. No exponer en 0.0.0.0 sin razón.

Keywords

Opus Vorbis OGG gumble ALSA chunked transfer bidireccional murmurd ffmpeg :64738 PCM bridge