SOLAR NET HUB

Arq. 6

µStreamer + Mumble + node-datachannel
Software Specification — RPi 3B — Solo LAN, Cero JS
web-rtc-ext.md · EXT-10B · Camino E

☞ Deep-Dive Specs (sub-ficheros)

µStreamer — CLI flags, encoders, V4L2 M2M, troubleshooting
Mumble Bridge — audio pipeline, latencia, murmurd config
Oasis Proxy — routes, templates, security headers, CSP
node-datachannel — API, signaling SDP/ICE via SSB, file transfer
Deploy & Ops — systemd, Docker, monitoring, checklist
~10 MBRAM µStreamer
+0 MBMumble (ya corre)
22 WPanel solar
1 GBLPDDR2 total
0JS en browser

☞ Esquema de Arquitectura

 ┌──────────────────────────────────────────────────────────────────┐
 │              RASPBERRY PI 3B  ·  SOLAR NET HUB                  │
 │              BCM2837 · Cortex-A53 · VideoCore IV                │
 │                                                                  │
 │  ┌──────────┐  V4L2   ┌─────────────────────┐                  │
 │  │ 🎥 CAM   │────────▷│ µStreamer    :8080   │                  │
 │  │ CSI/USB  │         │ ┌───────────────────┐│                  │
 │  └──────────┘         │ │MJPEG (cero proxy) ││                  │
 │                       │ │GET /stream        ││                  │
 │                       │ │GET /snapshot       ││                  │
 │                       │ └───────────────────┘│                  │
 │                       └──────────┬──────────┘                   │
 │                                  │ localhost                     │
 │  ┌──────────┐  ALSA   ┌─────────┼──────────┐                   │
 │  │ 🎤 MIC   │────────▷│ murmurd │  :64738  │                   │
 │  └──────────┘         │ (Mumble,│ya activo) │                   │
 │                       │ audio   │bidirecc.  │                   │
 │                       └─────────┼──────────┘                    │
 │                                 │ localhost                      │
 │  ┌──────────────────────────────┴────────────────────────────┐  │
 │  │  OASIS  :3000   (Node.js · SSB · cero JS en browser)     │  │
 │  │                                                           │  │
 │  │   GET /video  ──▷ proxy µStreamer MJPEG                   │  │
 │  │   GET /audio  ──▷ bridge Mumble Opus→OGG (ffmpeg)        │  │
 │  │                                                           │  │
 │  │   HTML:  <img src="/video">  +  <audio src="/audio">     │  │
 │  │                                                           │  │
 │  │   ┌─────────────────────────────────────┐                 │  │
 │  │   │ node-datachannel (P2P DataChannels) │                 │  │
 │  │   │ texto · archivos · señalización     │                 │  │
 │  │   └─────────────────────────────────────┘                 │  │
 │  └───────────────────────────────────────────────────────────┘  │
 └──────────────────────────────────────────────────────────────────┘
          │                │                  │
          ▼                ▼                  ▼
   ┌────────────┐  ┌─────────────┐   ┌──────────────┐
   │ 📺 BROWSER │  │ 🔊 MUMBLE  │   │ 📡 PEER P2P │
   │ (SIN JS)   │  │ (cliente    │   │ node-data-   │
   │ <img>MJPEG │  │  nativo)    │   │ channel      │
   │ <audio>OGG │  │  RTT ~20ms  │   │ texto/files  │
   └────────────┘  └─────────────┘   └──────────────┘
el único servidor cuya salida directa es lo que oasis necesita

Componentes

µStreamer
:8080
Lenguaje: C (95.8%) · pikvm/ustreamer
Licencia: GPL-3.0 · PiKVM project
RAM: ~5–15 MB
Encode: JPEG vía V4L2 M2M (HW) o CPU
Salida: MJPEG HTTP multipart
Bonus: --drop-same-frames (ahorro BW)
Install: apt install ustreamer
murmurd (Mumble)
:64738
Audio bidireccional · Opus codec
Ya instalado y corriendo → +0 MB
Compatible Tor (TCP tunnel)
Latencia: ~20 ms (cliente nativo)
Bridge HTTP: ~200 ms (ffmpeg Opus→OGG)
→ Protocolo Mumble en poster-protocolo
node-datachannel
P2P
DataChannels WebRTC sin media
Texto, archivos, señalización
Corre dentro de Oasis (Node.js)
No transporta audio ni vídeo

Ficha Rápida

PropiedadEstado
Cero JS en browser✔
Cámara CSI✔
Cámara USB✔
Audio bidireccional✔
Funciona sobre Tor✔
Escritura a microSD✘ (no)
HW JPEG encode (M2M)✔
HLS para remoto✘
WebRTC P2P (media)✘
DataChannels P2P (data)✔
RAM nuevos procesos~10-20 MB

¿Cuándo Elegir Arq. 6?

✔ SÍ cuando:
· Solo operas en LAN (sin peers remotos)
· Cada MB de RAM es crítico (1 GB compartido)
· Quieres el pipeline más simple posible
· Quieres HW JPEG encode (M2M) para CSI

✘ NO cuando:
· Necesitas HLS o WebRTC para remoto
→ Usa Arq. 3 (Mumble + go2rtc)

☞ Setup Técnico

1. INSTALAR µSTREAMER
sudo apt install ustreamer
2. INICIAR µSTREAMER (según cámara)
# ── CSI (v3 cam, Bookworm) — HW encode JPEG vía M2M ── sudo modprobe bcm2835-v4l2 libcamerify ustreamer \ --host 127.0.0.1 \ --port 8080 \ --encoder=m2m-image \ --workers=3
# ── USB (webcam UVC) — CPU encode multihilo ── ustreamer \ --host 127.0.0.1 \ --port 8080 \ --device=/dev/video0 \ --workers=3 \ --drop-same-frames=20
3. MUMBLE (ya corriendo)
# murmurd ya activo en :64738 # bridge audio para <audio> en browser: ffmpeg -i mumble://localhost:64738 \ -c:a libvorbis -f ogg pipe:1 | \ node oasis-audio-bridge.js
4. HTML EN OASIS (cero JS)
<!-- webrtc_view: lo que ve el browser --> <img src="/video" alt="stream"> <audio src="/audio" controls autoplay></audio>
5. PROXY EN OASIS (Node.js)
// routes — proxy µStreamer MJPEG app.get('/video', (req, res) => { const upstream = http.get( 'http://127.0.0.1:8080/stream', (mjpeg) => { res.writeHead(200, mjpeg.headers); mjpeg.pipe(res); } ); req.on('close', () => upstream.destroy()); });

Arq. 6 vs Arq. 3 — ¿Por Qué Arq. 6 Gana Aquí?

Arq. 3 (go2rtc + Mumble) Arq. 6 (µStreamer + Mumble)
RAM nuevos ~20 MB (go2rtc) ~10 MB (µStreamer) ★
Formatos vídeo MJPEG, HLS, RTSP, WebRTC MJPEG solamente
Audio Igual (Mumble) Igual (Mumble)
HW JPEG encode ✘ (go2rtc no usa M2M) ✔ (V4L2 M2M nativo) ★
CPU vídeo CSI @ 720p ~5–10% ~3–8% (M2M HW) ★
HLS para remoto ✔ ✘ — solo LAN
Paquete Debian ✘ (binario manual) ✔ apt install ★
★ = ventaja de Arq. 6. Si necesitas HLS/remoto → go2rtc (Arq. 3) cubre mejor el escenario remoto/Tor.