SOLAR NET HUB

Arq. 5

RPi-WebRTC + node-datachannel + proxy HTTP
Software Specification — RPi 3B — Solo CSI, WebRTC Nativo, P2P Real
web-rtc-ext.md · EXT-3 / EXT-5D / EXT-6 Camino D

☞ Deep-Dive Specs

RPi-WebRTC — compilación, config, MMAL/libcamera, señalización
Media Proxy — consumer WebRTC→MJPEG/OGG, rutas Oasis
Deploy & Ops — cross-compile, systemd, riesgos, fallback
~40 MBRAM RPi-WebRTC
~40–60 MBProxy + ffmpeg
~80–100 MBTotal stack
⚠️ Solo CSINo USB
0JS en browser SNH

☞ Esquema de Arquitectura

 ┌──────────────────────────────────────────────────────────────────┐
 │              RASPBERRY PI 3B  ·  SOLAR NET HUB                  │
 │              BCM2837 · Cortex-A53 · VideoCore IV                │
 │                                                                  │
 │  ┌──────────┐  MMAL/   ┌─────────────────────────┐              │
 │  │ 🎥 CAM   │─libcam──▷│ RPi-WebRTC     :8889    │              │
 │  │ CSI ONLY │ zero-copy│ ┌───────────────────────┐│              │
 │  └──────────┘          │ │H.264 HW encode (VC IV)││              │
 │                        │ │Opus audio (ALSA)      ││              │
 │  ┌──────────┐  ALSA    │ │ICE + DTLS-SRTP        ││              │
 │  │ 🎤 MIC   │────────▷│ │DataChannel (SCTP)     ││              │
 │  └──────────┘          │ │Señalización HTTP+WS   ││              │
 │                        │ └───────────────────────┘│              │
 │                        └──────────┬──────────────┘               │
 │                                   │ WebRTC (localhost)           │
 │  ┌────────────────────────────────┴──────────────────────────┐   │
 │  │  OASIS  :3000   (Node.js · SSB · cero JS en browser)     │   │
 │  │                                                           │   │
 │  │  ┌─────────────────────────────────────────────────────┐  │   │
 │  │  │ WebRTC Consumer (node-datachannel)                  │  │   │
 │  │  │ Conecta como peer a RPi-WebRTC (localhost)          │  │   │
 │  │  │ Recibe H.264 RTP → ffmpeg decode → MJPEG            │  │   │
 │  │  │ Recibe Opus RTP  → ffmpeg decode → OGG/WAV          │  │   │
 │  │  └────────────┬──────────────────┬─────────────────────┘  │   │
 │  │               │                  │                        │   │
 │  │  GET /video → MJPEG stream  GET /audio → OGG stream      │   │
 │  │                                                           │   │
 │  │  webrtc_view → <img src="/video"> + <audio src="/audio"> │   │
 │  │                                                           │   │
 │  │  ┌─────────────────────────────────────┐                  │   │
 │  │  │ node-datachannel (P2P DataChannels) │                  │   │
 │  │  │ texto · archivos · señalización SSB │                  │   │
 │  │  └─────────────────────────────────────┘                  │   │
 │  └───────────────────────────────────────────────────────────┘   │
 └──────────────────────────────────────────────────────────────────┘
          │                │                │
          ▼                ▼                ▼
   ┌────────────┐  ┌─────────────┐  ┌─────────────┐
   │ 📺 BROWSER │  │ 📡 PEER     │  │ 🔊 BROWSER  │
   │ LAN (no JS)│  │ REMOTO      │  │ REMOTO      │
   │ <img>MJPEG │  │ WebRTC P2P  │  │ WebRTC P2P  │
   │ <audio>OGG │  │ nativo !!   │  │ video+audio │
   │ vía proxy  │  │ ICE+DTLS    │  │ ~100ms lat. │
   └────────────┘  └─────────────┘  └─────────────┘
★ WebRTC nativo en el Pi: H.264 HW zero-copy, sin ffmpeg en captura, P2P real con browsers remotos — pero solo CSI ★

Key Concepts

¿Qué es RPi-WebRTC?
rpi-webrtc-streamer (kclyu) es un servidor WebRTC nativo en C++ compilado contra las APIs de la GPU del RPi. Accede al encoder H.264 HW directamente vía MMAL/libcamera, sin pasar por ffmpeg ni V4L2. Diferencia clave vs go2rtc/MediaMTX: estos son genéricos; RPi-WebRTC es exclusivo para RPi.
¿Por qué un proxy para el browser local?
RPi-WebRTC sirve WebRTC nativo → requiere JavaScript en el browser (RTCPeerConnection, setRemoteDescription). Esto viola la restricción de Oasis (cero JS en cliente). El proxy Node.js consume WebRTC en localhost y re-sirve como MJPEG/OGG puro (HTML <img> / <audio>).
El peer remoto (no el browser del SNH) SÍ puede usar WebRTC nativo con JS — RPi-WebRTC habla directo con Chrome/Firefox remotos.
¿Por qué solo CSI?
RPi-WebRTC se compila contra MMAL (legacy) o libcamera para acceder al encoder H.264 del VideoCore IV/VI. Estas APIs solo exponen cámaras CSI-2. Las cámaras USB (UVC/V4L2) no son compatibles con este path de captura.
Si necesitas cámara USB → esta arquitectura está descartada. Usar Arq. 3 o Arq. 6.
La gran ventaja: P2P WebRTC real
RPi-WebRTC es la única arquitectura que ofrece WebRTC P2P nativo con browsers remotos: video H.264 HW + audio Opus + DataChannels, con latencia ~100 ms, sin go2rtc ni MediaMTX intermedios. ICE completo (host/srflx/relay).
Arq. 3 y 6 usan MJPEG/HLS — no son P2P WebRTC real. Arq. 5 sí lo es.
Estado del proyecto: mantenimiento irregular
Último commit significativo: 2023. Fork community activo pero sin garantía. Si deja de compilar en aarch64 con kernels nuevos, se necesita mantener el fork. Mitigación: fallback a Arq. 3 (go2rtc genérico).

Componentes

RPi-WebRTC Streamer
:8889
Lenguaje: C++ (basado en libwebrtc / Chromium)
Repo: kclyu/rpi-webrtc-streamer
Licencia: BSD
RAM: ~30–50 MB
Binario: ~25–40 MB (cross-compile x86→ARM)
Captura: MMAL/libcamera (solo CSI, zero-copy)
Encode: H.264 HW VideoCore IV, sin ffmpeg
Audio: ALSA → Opus (libwebrtc AudioEncoder)
Transporte: SRTP sobre DTLS, ICE completo
Señalización: HTTP + WebSocket embebidos
DataChannel: ✔ (SCTP sobre DTLS)
Media Proxy (Node.js)
dentro de Oasis
~200 líneas · media_proxy.js
Se conecta como peer WebRTC a RPi-WebRTC (localhost)
Usa node-datachannel como consumer
Decode: H.264→MJPEG (ffmpeg pipe)
Decode: Opus→OGG (ffmpeg pipe)
Sirve: GET /video, GET /audio
node-datachannel
P2P
DataChannels WebRTC: texto, archivos
Señalización SDP/ICE vía SSB
También actúa como consumer en el proxy
Corre dentro de Oasis (Node.js)

Ficha Rápida

PropiedadEstado
Cero JS en browser SNH✔ (vía proxy)
Cámara CSI (zero-copy HW)
Cámara USB✘ No soportada
AudioOpus (ALSA→libwebrtc)
Audio bidireccional⚠️ Solo vía DataChannel
Funciona sobre Tor⚠️ Necesita TURN
MJPEG streaming✔ (vía proxy)
HLS para remoto✘ No nativo
WebRTC P2P (media)✔ Nativo !!
DataChannels P2P (data)
RAM nuevos procesos~80–100 MB
CPU vídeo (CSI)~15–20%

¿Cuándo Elegir Arq. 5?

✔ SÍ cuando:
· Usas solo cámara CSI (requisito hard)
· Necesitas WebRTC P2P nativo con peer remoto
· Quieres latencia <100 ms sin intermediarios
· Aceptas compilar/mantener RPi-WebRTC
· El peer remoto no pasa por Tor

✘ NO cuando:
· Usas o podrías usar cámara USB
→ Usa Arq. 3 o Arq. 6
· Necesitas funcionar sobre Tor
→ Usa Arq. 3 (Mumble TCP tunnel)
· Prefieres componentes bien mantenidos
→ RPi-WebRTC tiene mantenimiento irregular
· RAM es crítica (~80–100 MB es mucho para 1 GB)
→ Usa Arq. 6 (~10–20 MB)

☞ Ficha Técnica: RPi-WebRTC Streamer

CampoValor
LenguajeC++ (basado en libwebrtc de Google, parcheado para RPi)
Repogithub.com/kclyu/rpi-webrtc-streamer
LicenciaBSD (derivado de libwebrtc / Chromium)
ArquitecturaWebRTC nativo completo: señalización + ICE + DTLS-SRTP + H.264 HW
CapturaMMAL (legacy) / libcamera (moderno). Solo cámaras CSI
EncodeH.264 HW del VideoCore IV/VI, zero-copy. Sin ffmpeg
TransporteSRTP sobre DTLS, ICE completo (host / srflx / relay)
SeñalizaciónHTTP + WebSocket embebidos. Compatible AppRTC signaling
AudioALSA capture → Opus encode (libwebrtc AudioEncoder)
DataChannel✔ SCTP sobre DTLS (igual que browsers)
RAM típica~30–50 MB (libwebrtc pesada, pero encode es HW)
CPU RPi 3B~10–15% (encode HW) + ~5% (ICE/DTLS/SRTP) = ~15–20% total
Binario~25–40 MB (libwebrtc compilada estáticamente). Cross-compile x86→ARM
Estado⚠️ Mantenimiento irregular. Último commit significativo: 2023. Fork community activo
USB❌ No soportadas. Requiere MMAL/libcamera (solo CSI)

RPi-WebRTC vs. Otros Servidores Media

CriterioRPi-WebRTCgo2rtcMediaMTXµStreamer
Protocolo salida WebRTC nativo (SRTP) MJPEG, HLS, WebRTC, RTSP RTSP, HLS, WebRTC, MJPEG MJPEG, JPEG
Cam CSI ✔ MMAL/libcamera, zero-copy ✔ vía V4L2 (con copia) ✔ rpicam nativo (zero-copy) ✔ V4L2 M2M HW
Cam USB ✘ No ✔ V4L2 directo ✔ V4L2 directo ✔ V4L2 directo
Encode H.264 HW ✔ Nativo, sin ffmpeg ⚠️ Solo si fuente ya es H.264 ✔ rpicam nativo (CSI) ✘ Solo MJPEG
Browser sin JS ✘ Requiere JS (WebRTC API) ✔ MJPEG/HLS ✔ MJPEG/HLS ✔ MJPEG puro
Tor ✘ WebRTC+ICE incompatible ⚠️ MJPEG/HLS sí ⚠️ MJPEG/HLS sí ✔ HTTP puro
Señalización ✔ HTTP+WS embebidos ✔ API HTTP ✔ Hooks HTTP ✘ No tiene
RAM ~30–50 MB ~20–40 MB ~15–30 MB ~5–15 MB
Compilación Alta (libwebrtc, ~4 GB build) Baja (binario Go) Baja (binario Go) Baja (C, apt/make)
Madurez ⚠️ Irregular desde 2023 ✔ Activo (7k ★) ✔ Activo (13k ★) ✔ Activo (pikvm)

Patrón Composable: RPi-WebRTC como fuente para go2rtc

  ┌──────────────────────────────────────────────────────────────────┐
  │                    Raspberry Pi 3B (Solar Net Hub)               │
  │                                                                  │
  │  ┌──────────┐  MMAL   ┌───────────────┐  WebRTC   ┌─────────┐  │
  │  │ 🎥 CSI   │────────▷│ RPi-WebRTC    │──(WHEP)──▷│ go2rtc  │  │
  │  └──────────┘         │ H.264 HW      │           │ :1984   │  │
  │                       │ zero-copy      │           │         │  │
  │  ┌──────────┐  ALSA   │ + Opus audio  │           │ MJPEG   │  │
  │  │ 🎤 Mic   │────────▷│ :8889         │           │ HLS     │  │
  │  └──────────┘         └───────────────┘           │ JPEG    │  │
  │                                                   └────┬────┘  │
  │                                                        │       │
  │  ┌─────────────────────────────────────────────────────┤       │
  │  │ Node.js (Oasis :3000)                               │       │
  │  │ Sirve HTML con <img>/<video> apuntando a go2rtc     │       │
  │  └─────────────────────────────────────────────────────┘       │
  └────────────────────────────────────────────────────────────────┘
Ventaja: encode H.264 HW zero-copy (RPi-WebRTC) + re-serve sin re-encode como MJPEG/HLS (go2rtc). Lo mejor de ambos mundos.
Desventaja: dos procesos media (~30 MB + ~20 MB = ~50 MB) vs solo go2rtc (~20–40 MB) directo de V4L2. El beneficio de CPU puede no compensar el coste de RAM en 1 GB.

☞ Camino D: Implementación

FaseAlcanceFicheros / componentes
0. Detección HW Verificar CSI presente. Abortar si solo USB hardware_detect.js
1. DataChannel Idéntico al Camino A (P2P datos) webrtc_model.js, webrtc_view.js, backend.js
2. Señalización SSB Idéntico al Camino A signaling/ssb.js, signaling/index.js
3. Captura + encode RPi-WebRTC: CSI + H.264 HW + Opus. Server en :8889 rpi-webrtc-streamer (binario C++, ARM64)
3b. Proxy WebRTC→HTTP Node.js peer local → decode → MJPEG/OGG media_proxy.js (~200 lín, usa node-datachannel)
4. File transfer Idéntico al Camino A Extensión de webrtc_model.js
  webrtc_view.js ─── renderiza HTML con <img>/<video>/<audio> sin JS
       │
  backend.js ────── rutas GET/POST /webrtc/*
       │
  webrtc_model.js ── estado + node-datachannel (DataChannel para datos)
       │
  media_proxy.js ─── consume WebRTC de RPi-WebRTC (localhost:8889)
       │                └─ decode H.264→MJPEG (ffmpeg)
       │                └─ decode Opus→OGG (ffmpeg)
       │                └─ sirve GET /video, GET /audio
       │
  RPi-WebRTC ─────── binario C++: CSI → H.264 HW → WebRTC server (:8889)
       │
  signaling/ ────── abstracción: manual | ssb | ssb-lan

Riesgos & Mitigaciones

RiesgoProbabilidadImpactoMitigación
RPi-WebRTC deja de compilar en kernels nuevos Media-Alta Bloqueante Mantener fork o fallback a Arq. 3 (go2rtc)
libwebrtc ~4 GB build time Segura DX Cross-compile x86→ARM. Pre-build binario. CI/CD
Cámara USB en el futuro Media Bloqueante hardware_detect.js → cambio automático a Arq. 3
RAM ~80–100 MB en device de 1 GB Segura Alto Monitorizar con cgroups. Fallback a Arq. 6 (~10–20 MB)
Tor incompatible con WebRTC/ICE Segura Medio Para Tor: proxy MJPEG/HLS sin WebRTC, o usar Arq. 3 (Mumble)
⚠️ Mantenimiento RPi-WebRTC: último commit significativo ~2023, fork community activo. Evaluar viabilidad a largo plazo antes de depender de este componente en producción. (Fuente: web-rtc-ext.md EXT-3)
RPi-WebRTC MMAL libcamera H.264 HW zero-copy libwebrtc SRTP ICE DTLS media_proxy.js SCTP Solo CSI