★ ~2.000 paquetes npm mencionan "webrtc" · La mayoría son wrappers de browser · Las opciones backend-only viables son pocas ★
§1.6.1 — Librerías WebRTC para Node.js (sin navegador)
| Librería | Tipo | dl/sem | Licencia | Estado | DC | Media | Notas clave |
|---|---|---|---|---|---|---|---|
| node-datachannel | Binding C++ (libdatachannel) | 42.5k | MPL 2.0 | ✅ Activo (v0.32) | ✔ | ✔ | ~8 MB binario. WS integrado. Polyfill RTCPeerConnection. |
| werift | Implementación pura TS | 27.2k | MIT | ✅ Activo (v0.22) | ✔ | ✔ | 100% TypeScript. Sin binarios. Simulcast recv, BWE sender. |
| mediasoup | SFU (Node + workers C++) | 20.3k | ISC | ✅ Activo (v3.19) | ✔ | ✔ | SFU de producción. Multi-stream, simulcast, SVC. 6.4 MB. |
| livekit-server-sdk | SDK para LiveKit (Go) | 365k | Apache 2.0 | ✅ Activo (v2.15) | ✔ | ✔ | SDK Node.js ≠ WebRTC en Node. LiveKit es un server Go aparte. |
| node-webrtc (wrtc) | Binding libwebrtc | ~2k | BSD | ⚠️ Archivado (2022) | ✔ | ✔ | Referencia histórica. 80+ MB. Builds rotos Node 18+. No usar. |
| simple-peer | Wrapper sobre wrtc/browser | ~150k | MIT | ⚠️ Bajo mant. | ✔ | ✔ | En Node depende de wrtc (archivado). En browser funciona bien. |
| peerjs-server | Solo señalización | ~10k | MIT | ✅ Activo | ✘ | ✘ | No hace WebRTC — solo coordina SDP entre browsers. |
§1.6.2 — Librerías en Otros Lenguajes
| Librería / Servidor | Lenguaje | Tipo | ★ | Licencia | DC | Media | Notas clave |
|---|---|---|---|---|---|---|---|
| libdatachannel | C/C++ | Librería | ~2.7k | MPL 2.0 | ✔ | ✔ | Base de node-datachannel. Ligera. Bindings: Rust, Node, Unity, WASM. |
| Pion/webrtc | Go | Librería | ~14k | MIT | ✔ | ✔ | La referencia Go. go2rtc y MediaMTX están sobre Pion. Pura Go, sin CGO. |
| go2rtc | Go (Pion) | Servidor media | ~7k | MIT | ✘ | ✔ | MJPEG, HLS, WebRTC, RTSP. Captura v4l2/ALSA directa. ~15 MB binario. |
| MediaMTX | Go (Pion) | Servidor media | ~13k | MIT | ✘ | ✔ | RTSP↔HLS↔WebRTC auto-conv. rpicam nativo (zero-copy CSI). |
| Janus Gateway | C | Gateway WebRTC | ~8.5k | GPL 3.0 | ✔ | ✔ | SFU/MCU por plugins. Requiere JS en cliente para handshake. |
| aiortc | Python | Librería | ~4.5k | BSD | ✔ | ✔ | WebRTC puro Python (asyncio). Útil ML/AI. Python no está en stack SNH. |
| LiveKit | Go | SFU completa | ~22k | Apache 2.0 | ✔ | ✔ | SFU más popular. TURN integrado. E2EE. SDKs JS/Python/Go/Rust/Swift/Kotlin. |
☞ §1.6.3 — Mapa de Decisión
┌─────────────────────────────────────────────────────────────────┐
│ MAPA DE DECISIÓN: WebRTC backend │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ¿Necesitas P2P puro (2 peers)? │
│ → node-datachannel (binding C++, ligero) │
│ → werift (TypeScript puro, sin compilar, portable) │
│ │
│ ¿Necesitas SFU (muchos peers, rooms)? │
│ → mediasoup (SFU embebida en Node.js) │
│ → LiveKit (servidor Go aparte, cloud-ready) │
│ │
│ ¿Necesitas servir media al browser SIN JS? │
│ → go2rtc (MJPEG/HLS sin ffmpeg, binario Go) │
│ → MediaMTX (rpicam nativo CSI, auto-conversión) │
│ → µStreamer (MJPEG puro, C, ultra-ligero) │
│ → ffmpeg directo → HLS estático (mínimo, sin servidor) │
│ │
│ ¿Solo señalización (WebRTC corre en browsers)? │
│ → peerjs-server, socket.io, o SSB nativo │
│ │
└─────────────────────────────────────────────────────────────────┘
P2P: node-datachannel vs. werift
| Criterio | node-datachannel | werift |
|---|---|---|
| Runtime | C++ nativo (N-API) | 100% TypeScript |
| CPU media | Menor (GC no aplica) | Mayor (sujeto a V8 GC) |
| Compilación | Requiere prebuild/C++ | npm install sin compilar |
| Binario | ~8 MB addon | ~3.5 MB (JS/TS) |
| API | Propia + polyfill RTC | Hacia API browser (v2.0) |
| WebSocket | ✔ cliente + servidor | ✘ externo |
| Media tracks | Completa (SRTP) | Completa (simulcast recv) |
| Interop | Chrome, Firefox | Chrome, Firefox, Pion, aiortc |
| Riesgo | Si C++ no compila en ARM | Si TS es lento en RPi 1 GB |
Ambas son viables para P2P en el SNH. node-datachannel gana en CPU; werift gana en portabilidad.
SFU: mediasoup vs. LiveKit
| Criterio | mediasoup | LiveKit |
|---|---|---|
| Arquitectura | Se embebe en Node.js | Servidor Go independiente |
| RAM | ~50-80 MB | >100 MB + Redis |
| Escala | Decenas de peers | Miles (cloud-scale) |
| Señalización | Signaling-agnostic | Propia (rooms, tokens JWT) |
| TURN | Externo | Integrado |
| SDKs cliente | mediasoup-client (JS) | JS, Python, Go, Rust, Swift… |
| E2EE | Via SFrame | ✔ Nativo |
| RPi 3B | ⚠️ Heavy para 1 GB | ✘ Inviable |
Ambos son overkill para 2 peers P2P. Relevantes si Oasis evoluciona a salas grupales.
Servidores Media: MJPEG/HLS sin JS en Cliente
| go2rtc | MediaMTX | µStreamer | ffmpeg directo | |
|---|---|---|---|---|
| Salida sin JS | MJPEG, HLS, JPEG | MJPEG, HLS | MJPEG, JPEG | HLS (.m3u8 + .ts) |
| CSI zero-copy | Via exec rpicam | ✔ rpiCamera nativo | Via M2M HW | Via rpicam-vid pipe |
| USB directo | ✔ V4L2 | Necesita ffmpeg | ✔ V4L2 | ✔ V4L2 |
| Audio | ✔ ALSA directo | ✔ | ✘ Solo vídeo | ✔ |
| RAM | ~20-40 MB | ~15-30 MB | ~5-15 MB | ~30-60 MB |
| Config | YAML simple | YAML extenso | CLI flags | Comando largo |
| Tor | ⚠️ MJPEG/HLS sí | ⚠️ MJPEG/HLS sí | ✔ HTTP puro | ✔ HLS estático |
| Poster | Arq. 3 | Impact spec | Arq. 6 | Retransmisión |
Alternativas Evaluadas para Oasis
| Opción | Descripción | Veredicto |
|---|---|---|
| JS en cliente | getUserMedia + RTCPeerConnection en el navegador | ✘ Rechazado: "no client-side JS" (mantenedores Oasis) |
| node-datachannel + ffmpeg | DataChannels + media vía ffmpeg como captura/decode | ✔ Stack WebRTC puro: ligero, binarios pequeños, acceso HW |
| werift + ffmpeg | 100% TypeScript, sin compilar binarios | ✔ Viable: más portable, menor rendimiento media |
| Mumble (audio) + go2rtc (vídeo) | Reutilizar murmurd + go2rtc para vídeo | ✔ Candidata fuerte: cero código audio, Tor-compatible |
| Mumble (audio) + µStreamer (vídeo) | murmurd + µStreamer MJPEG | ✔ Ultra-ligera: ~10-20 MB total, solo LAN |
| mediasoup SFU | SFU embebida en Node.js | ⚠️ Overkill para 2 peers. Si evoluciona a salas: reconsiderar. |
| LiveKit | SFU Go + Redis | ✘ Inviable: >100 MB RAM, diseño cloud-scale, no embebido. |
| Janus Gateway | Gateway C con plugins | ⚠️ Requiere JS en cliente para WebRTC handshake. |
Las 2 arquitecturas elegidas combinan caminos: Arq. 3 (Mumble+go2rtc+node-datachannel) y Arq. 6 (Mumble+µStreamer+node-datachannel). Ver Matriz de Decisión.
El Cambio de Paradigma: Transmisión ≠ Consumo
El paradigma Web ≠ paradigma HTML5 (subconjunto). Hay una web HTML/CSS sin JavaScript en cliente. WebRTC debe verse como un paradigma de transmisión / consumo de la transmisión: se usa tecnología estándar para transmitir, pero se disocia en la capa de consumo, actuando como relay.
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ TRANSMISIÓN │ │ CONSUMO │
│ │ │ │
│ WebRTC estándar: │ │ HTML/CSS puro: │
│ · SDP, ICE, DTLS, SRTP │ │ · <img src="/mjpeg"> │
│ · DataChannels (SCTP) │ │ · <video src="/hls"> │
│ · node-datachannel │ │ · <audio src="/ogg"> │
│ · werift │ │ · sin JS en cliente │
│ · go2rtc / MediaMTX │ │ │
│ │ │ Mumble VoIP: │
│ Mumble VoIP: │ │ · gumble → ffmpeg → OGG │
│ · Opus, TCP fallback │ │ · <audio src="/audio"> │
│ · OCB-AES128 │ │ │
└──────────────┬──────────────┘ └─────────────────────────────┘
│ ▲
│ Servidor media │
│ (go2rtc / µStreamer / │
│ ffmpeg / Oasis proxy) │
└───────────────────────────────┘
node-datachannel werift mediasoup LiveKit Pion libdatachannel go2rtc MediaMTX µStreamer Janus aiortc simple-peer