Arq. 1 — go2rtc: CSI vs. USB
go2rtc.yaml — CSI:
streams:
solar-cam:
- v4l2:///dev/video0
solar-mic:
- alsa:///default
api:
listen: "127.0.0.1:1984"
go2rtc.yaml — USB:
streams:
solar-cam:
- v4l2:///dev/video0
solar-mic:
- alsa:///default
api:
listen: "127.0.0.1:1984"
| go2rtc + CSI | go2rtc + USB |
| Captura | V4L2 o exec rpicam-vid | V4L2 directo (MJPEG/YUYV) |
| H.264 HW | Sí, vía rpicam-vid exec | Solo si webcam lo entrega nativo |
| RAM | ~20-30 MB | ~20-40 MB (si re-encode) |
| CPU | ~5-10% | ~10-20% |
| Docker | --device /dev/video0 --device /dev/vchiq | --device /dev/video0 |
Arq. 2 — MediaMTX: CSI vs. USB
MediaMTX tiene ventaja diferencial para CSI: soporta rpicam nativo (rpiCamera) sin ffmpeg. Para USB necesita ffmpeg como fuente.
mediamtx.yml — CSI (zero-copy nativo):
paths:
solar-cam:
source: rpiCamera
rpiCameraWidth: 1280
rpiCameraHeight: 720
rpiCameraFPS: 25
rpiCameraCodec: h264
rpiCameraProfile: baseline
rpiCameraLevel: "3.1"
rpiCameraBitrate: 1000000
mediamtx.yml — USB (requiere ffmpeg):
paths:
solar-cam:
runOnInit: >
ffmpeg -f v4l2 -input_format mjpeg
-video_size 1280x720 -framerate 25
-i /dev/video0 -c:v h264_v4l2m2m -b:v 1M
-f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH
runOnInitRestart: yes
| MediaMTX + CSI | MediaMTX + USB |
| Fuente | rpiCamera nativo (zero-copy) | ffmpeg exec → RTSP local |
| ffmpeg | ❌ No necesario | ✅ Necesario |
| CPU | ~5% | ~15-20% |
| Config | 10 líneas YAML | 10 líneas YAML + ffmpeg cmd |
| Auto-conv | RTSP → HLS → WebRTC automática |
★ MediaMTX: óptima para CSI · subóptima para USB ★
★ go2rtc: equilibrada para ambas ★
Arq. 3 — Mumble Hybrid (go2rtc): CSI vs. USB
Hereda el análisis de go2rtc (Arq. 1). El audio va por Mumble → independiente de CSI/USB.
Arq. 3 + CSI Arq. 3 + USB
════════════ ════════════
🎤 Mic ──► murmurd (audio) 🎤 Mic ──► murmurd (audio)
🎥 CSI ──► go2rtc (v4l2/rpicam) 🎥 USB ──► go2rtc (v4l2 MJPEG)
│ │
└─ MJPEG/HLS → <img>/<video> └─ MJPEG/HLS → <img>/<video>
Audio: idéntico (Mumble) Audio: idéntico (Mumble)
Vídeo: ~5-10% CPU Vídeo: ~10-20% CPU
RAM: ~65 MB RAM: ~75 MB
Si se usa USB, go2rtc sigue siendo preferible a MediaMTX: captura V4L2 directa sin ffmpeg.
Arq. 6 — µStreamer: CSI vs. USB
| µStreamer + CSI | µStreamer + USB |
| Captura | V4L2 + M2M HW encode | V4L2 MJPEG directo |
| CPU | ~3-8% | ~15-30% |
| Formato salida | MJPEG (siempre) | MJPEG (siempre) |
| H.264 USB | N/A | Ignora H.264 integrado (usa MJPEG) |
| RAM | ~10 MB | ~15 MB |
µStreamer siempre sirve MJPEG. No hace HLS ni H.264 streaming. Para Arq. 6 eso es una feature: latencia mínima en LAN.
Arq. 5 — RPi-WebRTC: Solo CSI
RPi-WebRTC NO soporta cámaras USB. Si se usa USB, esta arquitectura queda descartada.
🎥 Cam CSI ──MMAL──► RPi-WebRTC ──WebRTC──► Node.js consumer
🎤 Mic ─────ALSA───► :8889 (node-datachannel)
│ H.264 HW encode │
│ + Opus audio ├─ GET /video → MJPEG
│ + DataChannel └─ GET /audio → OGG
| Criterio | Arq. 5 |
| Cámara | Solo CSI (MMAL/libcamera) |
| RAM | ~80-100 MB (RPi-WebRTC ~40 MB + decode Node.js) |
| CPU | ~15-20% encode HW + ~10% decode en Node.js |
| Estado | ⚠️ Mantenimiento irregular desde 2023 |
| JS en cliente | Requiere WebRTC API → incompatible con "cero JS" |
| Viabilidad | Solo como fuente para go2rtc (patrón composable) |
Patrón composable: RPi-WebRTC → go2rtc (WHEP) → MJPEG/HLS. Ventaja: encode HW zero-copy. Desventaja: ~50 MB RAM por 2 procesos media.
☞ Resumen: ¿Qué Arquitectura para Qué Cámara?
| Arquitectura | CSI | USB | USB H.264 | Recomendación |
| Arq. 1 go2rtc | ✔ bueno | ✔ bueno | ✔ óptimo |
Equilibrada para ambas |
| Arq. 2 MediaMTX | ✔ óptimo | ⚠️ necesita ffmpeg | ⚠️ |
Solo si CSI |
| Arq. 3 Mumble+go2rtc | ✔ bueno | ✔ bueno | ✔ óptimo |
★ Contexto: remoto + Tor · ambas |
| Arq. 4 Janus | ⚠️ heavy | ⚠️ heavy | ⚠️ |
Descartada (RAM) |
| Arq. 5 RPi-WebRTC | ✔ zero-copy | ✘ | ✘ |
Solo CSI, mantenimiento dudoso |
| Arq. 6 µStreamer+Mumble | ✔ ultra-light | ✔ ok | ✔ |
★ Contexto: solo LAN / RAM crítica |
★ Arq. 3 (go2rtc) gana para USB · Arq. 6 (µStreamer) gana para CSI en LAN ★
go2rtc
MediaMTX
µStreamer
RPi-WebRTC
rpiCamera
MMAL
YAML
Docker