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.
| Alternativa | RAM extra | Bidireccional | Tor | Ya 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 MB | Complejo | ✔ | ✘ |
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-web | 3C: Cliente nativo |
| JS en browser | ✘ No | ✔ Sí (viola restricción) | ✘ No |
| Apps necesarias | Solo navegador | Solo navegador | Navegador + Mumble app |
| Código nuevo | ~100 lín bridge | Instalar 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
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)
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
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.
| Precedente | Descripción |
| MumbleDJ | Bot Go que inyecta audio (música) en canales Mumble |
| piepan | Framework Lua para scripting de bots Mumble |
| barnard | Cliente 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ón | Mecanismo | Latencia | Requiere 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
| Etapa | Latencia |
| 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
host=127.0.0.1
port=64738
opusthreshold=0
bandwidth=64000
users=5
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