:8889

RPi-WebRTC Streamer

Servidor WebRTC nativo C++ para RPi — captura CSI zero-copy, H.264 HW, Opus, señalización embebida

Identidad del Componente

CampoValor
Repogithub.com/kclyu/rpi-webrtc-streamer
LenguajeC++ (basado en libwebrtc / Chromium)
LicenciaBSD
RAM típica~30–50 MB
Binario~25–40 MB (libwebrtc compilada estáticamente)
CPU RPi 3B~15–20% (encode HW 10–15% + stack ICE/DTLS 5%)
CapturaMMAL (legacy) / libcamera (moderno) — solo CSI
EncodeH.264 HW VideoCore IV/VI, zero-copy
AudioALSA → Opus (libwebrtc AudioEncoder)
TransporteSRTP sobre DTLS, ICE completo
DataChannel✔ SCTP sobre DTLS
Estado⚠️ Mantenimiento irregular (último commit significativo: 2023)

Key Concept

A diferencia de go2rtc, MediaMTX o Janus (que son genéricos), RPi-WebRTC se compila contra las APIs de la GPU del RPi para acceder al encoder H.264 HW sin pasar por ffmpeg ni V4L2. El binario integra libwebrtc completa: señalización, ICE, DTLS-SRTP, codec negotiation y encode/capture — todo en un solo proceso C++.

Arquitectura Interna

  ┌───────────────────────────────────────────────────────────────┐
  │               RPi-WebRTC Streamer (C++)                       │
  │                                                               │
  │  ┌─────────────┐   MMAL/libcamera   ┌──────────────────────┐ │
  │  │ 🎥 Cam CSI  │───────────────────▷│ RaspiCamEncoder      │ │
  │  └─────────────┘    (zero-copy)     │ (H.264 HW encode)    │ │
  │                                     └──────────┬───────────┘ │
  │  ┌─────────────┐   ALSA             ┌──────────┴───────────┐ │
  │  │ 🎤 Mic      │──────────────────▷│ AudioEncoder (Opus)   │ │
  │  └─────────────┘                    └──────────┬───────────┘ │
  │                                                │              │
  │                                     ┌──────────┴───────────┐ │
  │                                     │ libwebrtc stack      │ │
  │                                     │ PeerConnection       │ │
  │                                     │ ICE + DTLS + SRTP    │ │
  │                                     │ DataChannel (SCTP)   │ │
  │                                     └──────────┬───────────┘ │
  │                                                │              │
  │  ┌───────────────────────────────────┐         │              │
  │  │ HTTP Server (señalización)        │◄────────┘              │
  │  │ WebSocket (ICE candidates)        │                        │
  │  │ Sirve: SDP offer/answer           │                        │
  │  │ Conf.: resolución, bitrate, etc.  │                        │
  │  └───────────────┬───────────────────┘                        │
  └──────────────────┼────────────────────────────────────────────┘
                     │ HTTP/WS (:8889)
                     ▼
               Peer (browser o Node.js consumer)

Captura: MMAL vs libcamera

MMAL (legacy)libcamera (moderno)
KernelRaspbian antiguoBookworm+ (dtoverlay=imx219/ov5647)
Módulos HWOV5647, IMX219, IMX477Todos los soportados por libcamera
Zero-copy✔ vía GPU memory✔ vía DMA-BUF
RPi-WebRTC✔ Rama principal⚠️ Fork / rama experimental
RecomendaciónSi kernel legacyPreferido en Bookworm
En Debian Bookworm (stack actual del SNH), MMAL está deprecado. Verificar que RPi-WebRTC soporta libcamera en la versión/fork elegida.

Señalización HTTP+WS

RPi-WebRTC tiene su propio servidor HTTP/WebSocket embebido. No necesita señalización externa. Sin embargo, para integrarse con Oasis (donde la señalización va por SSB), el proxy Node.js se conecta como peer local.
EndpointMétodoFunción
/offerPOSTEnviar SDP offer → recibir SDP answer
/wsWebSocketIntercambio de ICE candidates en tiempo real
/configGET/POSTConfigurar resolución, bitrate, etc.
/snapshotGETJPEG snapshot (si soportado)
Ejemplo: handshake desde Node.js
# Pseudocódigo del proxy media_proxy.js # 1. Crear PeerConnection (node-datachannel) const pc = new RTCPeerConnection(); # 2. POST SDP offer a RPi-WebRTC const offer = pc.createOffer(); const answer = await fetch('http://localhost:8889/offer', { method: 'POST', body: offer.sdp }); pc.setRemoteDescription(answer); # 3. Recibir tracks → pipe a ffmpeg → MJPEG/OGG HTTP pc.ontrack = (ev) => pipeToFfmpeg(ev.track);

Compilación: Cross-Compile x86 → ARM

libwebrtc no se compila en RPi directamente (horas, ~4 GB de toolchain). Se usa cross-compile desde x86_64.
1. Clonar repositorio + depot_tools
git clone https://github.com/kclyu/rpi-webrtc-streamer.git git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH=$PWD/depot_tools:$PATH
2. Fetch libwebrtc + parches RPi
cd rpi-webrtc-streamer ./scripts/build_env_setup.sh ./scripts/build_webrtc.sh arm
3. Compilar el streamer
./scripts/build_rws.sh # Resultado: out/rws (binario ARM, ~25-40 MB)
4. Deploy al RPi
scp out/rws pi@rpi:/opt/rpi-webrtc/ scp etc/webrtc_streamer.conf pi@rpi:/opt/rpi-webrtc/
Alternativa: buscar binarios pre-compilados en los Releases del repo o forks community. Verificar compatibilidad ARM vs ARM64.

Configuración: webrtc_streamer.conf

# /opt/rpi-webrtc/webrtc_streamer.conf (ejemplo mínimo) # Resolución y bitrate max_bitrate=1500000 resolution=640x480 framerate=25 # Servidor HTTP/WS websocket_enable=true direct_socket_enable=false wss_url=ws://localhost:8889 # Audio audio_enable=true audio_device=default # STUN (para peers remotos) stun_server=stun:stun.l.google.com:19302 # Log log_dir=/var/log/rpi-webrtc

Troubleshooting

SíntomaCausaFix
No se detecta cámara CSI MMAL deprecado en Bookworm Usar fork con soporte libcamera. Verificar dtoverlay en config.txt
Binario no arranca (SIGILL) Compilado para ARM64, device es ARM32 Recompilar con target armhf o usar device con OS 64-bit
ICE candidates vacíos Firewall bloquea UDP Abrir rango de puertos UDP o configurar TURN server
High CPU en encode Fallback a software encode Verificar que /dev/vchiq existe (VideoCore). ls /dev/vchiq
WebSocket connection refused Puerto 8889 ocupado Cambiar puerto en conf. Verificar con ss -tlnp | grep 8889
USB cam no funciona RPi-WebRTC no soporta USB Cambiar a Arq. 3 (go2rtc) o Arq. 6 (µStreamer)
RPi-WebRTC libwebrtc MMAL libcamera H.264 HW zero-copy VideoCore IV cross-compile SRTP :8889