4técnicas vídeo
4técnicas audio
3fases deploy
79%HLS nativo
100%MJPEG
★ Restricción Oasis: cero JS en browser · Todo debe funcionar con HTML puro ★
Técnicas de Vídeo (sin JS)
| Técnica | HTML | Latencia | BW | Browser |
| MJPEG <img> |
<img src="/video"> |
100–300 ms |
Alto (×10 vs H.264) |
Universal ✔ |
| HLS <video> |
<video src="/stream.m3u8"> |
2–6 s |
Bajo (H.264) |
Chrome 142+, Safari 6+, Android · ~79% |
| JPEG + meta refresh |
<img> + <meta refresh> |
1–10 s |
Mínimo |
Universal ✔ |
| GIF animado |
<img src="/live.gif"> |
1–3 s |
Alto (GIF ineficiente) |
Universal ✔ |
MJPEG: servidor envía multipart/x-mixed-replace — cada parte es un JPEG. El browser actualiza <img> automáticamente.
HLS: ffmpeg genera playlist .m3u8 + segmentos .ts; servidor sirve archivos estáticos. Chrome 142+ (2026) lo soporta nativo sin JS.
⚠️ Cobertura HLS sin JS: no existe un formato único sin JS que cubra el 100% de navegadores. Firefox desktop no soporta HLS nativo. Estrategia recomendada: HLS nativo donde aplique + fallback MJPEG para el resto. (Fuente: web-rtc.md §2.1)
Técnicas de Audio (sin JS)
| Técnica | HTML | Latencia | Browser | BW |
| WAV/PCM chunked |
<audio src="/audio" autoplay> |
~50 ms |
Universal ✔ |
1.4 Mbps stereo |
| OGG/Opus chunked |
<audio src="/audio" autoplay> |
~200 ms |
Chrome, Firefox, Edge, Opera · No: Safari <17 |
~32-128 kbps |
| MP3 chunked |
<audio src="/audio" autoplay> |
~500 ms |
Universal ✔ |
~128 kbps |
| HLS audio |
<video src="/audio.m3u8"> |
2–6 s |
Igual que vídeo HLS |
~64 kbps AAC |
Todos usan Transfer-Encoding: chunked con el Content-Type adecuado. El browser reproduce sin JS.
☞ Mapa de Latencia
LATENCIA
50ms 200ms 1s 3s 6s
│ │ │ │ │
█ WAV █ MJPEG │ │ │ audio
│ █ OGG │ │ │
│ │ MP3─────█ │ │ vídeo
│ │ │ HLS─────█──────────█
│ │ █ refresh │ │
└──────────┴─────────┴─────────┴──────────┘
LAN ok Internet ok
★ Recomendación por Fase
| Fase | Vídeo | Audio | Por qué |
| 1: localhost |
MJPEG <img> |
WAV/PCM |
Latencia mínima, BW irrelevante |
| 2: LAN |
MJPEG <img> |
OGG/Opus |
MJPEG tolerable (~5 Mbps); Opus ahorra BW |
| 3: Internet |
HLS <video> |
HLS integrado |
MJPEG inviable (×10 BW). HLS H.264 ~10× más eficiente |
Fase 3 con HLS: Firefox desktop sin soporte nativo → fallback a MJPEG o mensaje "usa Chrome/Safari".
Soporte Browser sin JS
| Browser | HLS nat. | MJPEG | HTTP Prog. |
| Chrome 142+ | ✔* | ✔ | ✔ |
| Firefox desk. | ✘ | ✔ | ✔ |
| Safari 14+ | ✔ | ✔ | ✘ |
| Android Chrome | ✔* | ✔ | ✔ |
| iPhone Safari | ✔ | ✔ | ✘ |
* HLS nativo vía HTML, no vía MSE
No existe un formato único sin JS que cubra el 100%. De ahí la estrategia dual: MJPEG (universal) + HLS (eficiente donde se soporta).
☞ Estrategia Dual: MJPEG + HLS
Chrome 142+ (2026) soporta HLS nativo en <video src=".m3u8"> sin JavaScript. Combinado con Safari (soporte desde 2012), HLS nativo cubre ~79% de browsers.
┌────────────────────────────────────────────────────────────┐
│ Oasis :3000 (Node.js) │
│ │
│ User-Agent? │
│ │ │
│ ├──── Chrome 142+ / Safari / Android ────┐ │
│ │ ▼ │
│ │ <video src="/stream.m3u8" autoplay> │
│ │ (HLS: H.264, baja BW, ~79% global) │
│ │ │
│ └──── Firefox desktop / otros ───────────┐ │
│ ▼ │
│ <img src="/video"> │
│ <audio src="/audio" autoplay> │
│ (MJPEG + OGG: universal, alta BW) │
└────────────────────────────────────────────────────────────┘
<video src="/webrtc/media/stream.m3u8" autoplay muted playsinline controls></video>
<img src="/webrtc/media/video" alt="Vídeo">
<audio src="/webrtc/media/audio" autoplay controls></audio>
Paquetes npm para el Pipeline Servidor
| Paquete | Función | dl/sem |
| mjpeg-server | Crea endpoint MJPEG desde JPEGs (multipart/x-mixed-replace) | 7.8k |
| mjpeg-proxy | Proxy MJPEG multi-cliente sobre una sola fuente | 4.3k |
| mjpeg-consumer | Consume stream MJPEG HTTP y emite buffers JPEG | 71k |
| ffmpeg-stream | Wrapper Node.js streams sobre ffmpeg (I/O como streams) | 6.6k |
| ffmpeg -f hls | Genera .m3u8 + .ts directamente. Sin dep npm extra | — |
¿Quién Sirve el Media?
§2.1 asume que Node.js (Oasis) hace todo: recibe pistas, decodifica con ffmpeg, sirve MJPEG/HLS. Pero existe otra vía: un servidor media dedicado al lado (§2.2).
| Node.js directo (§2.1) | Servidor media (§2.2) |
| MJPEG | ffmpeg → mjpeg-server → <img> | go2rtc / µStreamer → proxy |
| HLS | ffmpeg -f hls → serve static | go2rtc / MediaMTX auto-HLS |
| CPU Node.js | Alta (ffmpeg child) | Baja (solo proxy HTTP) |
| Complejidad | Media (código propio) | Baja (config YAML) |
| Poster | — | Arq. 3 · Arq. 6 |
Las arquitecturas elegidas (Arq. 3 y 6) usan servidor media dedicado. Node.js solo hace proxy HTTP y sirve HTML.
Impacto CSI vs. USB en Retransmisión (EXT-4)
| Formato entrega | Pipeline CSI | Pipeline USB | Δ CPU |
| MJPEG <img> |
rpicam-vid --codec mjpeg → HTTP |
ffmpeg -f v4l2 mjpeg → -c:v copy → HTTP |
~0% |
| HLS <video> |
rpicam-vid h264 → ffmpeg -f hls |
ffmpeg mjpeg → h264_v4l2m2m → -f hls |
CSI ~5% · USB ~15% |
Para Fase 3 (Internet) con HLS, CSI ahorra ~10% CPU vs. USB. Ver
CSI vs. USB para detalles.
MJPEG
HLS
multipart
.m3u8
OGG/Opus
WAV/PCM
chunked
autoplay
mjpeg-server
ffmpeg -f hls
User-Agent
cero JS