§2.1

Retransmisión al Navegador

Audio & Vídeo sin JavaScript — HTML/CSS puro
¿Cómo entrega el servidor media al browser sin una línea de JS?
web-rtc.md §2.1 + web-rtc-ext.md EXT-4
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écnicaHTMLLatenciaBWBrowser
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écnicaHTMLLatenciaBrowserBW
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

FaseVídeoAudioPor 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

BrowserHLS nat.MJPEGHTTP 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)               │
  └────────────────────────────────────────────────────────────┘
<!-- Fase 3: dual MJPEG/HLS (servidor detecta User-Agent) --> <!-- Chrome 142+, Safari, Android: --> <video src="/webrtc/media/stream.m3u8" autoplay muted playsinline controls></video> <!-- Fallback Firefox desktop, navegadores antiguos: --> <img src="/webrtc/media/video" alt="Vídeo"> <audio src="/webrtc/media/audio" autoplay controls></audio>

Paquetes npm para el Pipeline Servidor

PaqueteFuncióndl/sem
mjpeg-serverCrea endpoint MJPEG desde JPEGs (multipart/x-mixed-replace)7.8k
mjpeg-proxyProxy MJPEG multi-cliente sobre una sola fuente4.3k
mjpeg-consumerConsume stream MJPEG HTTP y emite buffers JPEG71k
ffmpeg-streamWrapper Node.js streams sobre ffmpeg (I/O como streams)6.6k
ffmpeg -f hlsGenera .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)
MJPEGffmpeg → mjpeg-server → <img>go2rtc / µStreamer → proxy
HLSffmpeg -f hls → serve staticgo2rtc / MediaMTX auto-HLS
CPU Node.jsAlta (ffmpeg child)Baja (solo proxy HTTP)
ComplejidadMedia (código propio)Baja (config YAML)
PosterArq. 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 entregaPipeline CSIPipeline 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