WebRTC de baja latencia
Player WebRTC sobre LiveKit con latencia sub-segundo para "ver en vivo ahora" y videollamadas. Tokens de subscribe efímeros por room.
Una capa de gestión sobre un SFU LiveKit: ingest multi-protocolo, WebRTC sub-segundo, HLS en vivo, grabación a tu propio S3, una API REST y un SDK drop-in. Acá está el panorama técnico completo — el mano a mano con Ant Media, todas las funciones, la API y el SDK.
Seguí la señal de punta a punta: un dispositivo publica una vez, el origen la pasa por tu app y sus plugins, la replica a los nodos edge y la reparte a cada espectador en WebRTC sub-segundo o HLS.
Topología de StreamHub: un dispositivo de ingesta (cámara, teléfono o encoder) publica una única señal por RTMP, WHIP o SRT al nodo origen que corre StreamHub Core (SFU LiveKit, API REST, apps multi-tenant). Dentro del origen la señal pasa por una app tenant cuyos plugins — yolo, deface, scheduled-live, live-chat — la procesan y enriquecen. El origen luego replica la señal a los nodos edge del clúster, y cada edge la reparte a muchos espectadores a la vez por WebRTC sub-segundo y HLS.
Una señal de entrada — RTMP, WHIP o SRT desde cualquier cámara, teléfono o encoder.
La app y sus plugins enriquecen la señal: detección, enmascarado de privacidad, programación, chat.
El origen replica a los nodos edge; cada espectador recibe WebRTC sub-segundo o HLS en vivo.
StreamHub cubre el feature-set de Ant Media Server Enterprise para streaming real — medido, no prometido — y suma las piezas que siempre nos faltaron: webhooks firmados, tenancy por app y un marketplace de plugins. Licencia AGPL, gratis mientras dura la beta, y tu media nunca sale de tu infra.
de latencia WebRTC — p50 medido sobre 601 muestras en producción
de licencia — open source (AGPL). Ant Media EE: ~USD 109/mes por instancia
para instalar — curl | sudo bash en Ubuntu 24.04 / 26.04 LTS
StreamHub · Open source (AGPL). Sin licencia por instancia — gratis mientras dura la beta.
Ant Media EE · Propietario. ~USD 109/mes (~USD 1.068/año) por instancia.
StreamHub · 0.19s p50, medido end-to-end sobre 601 muestras en producción.
Ant Media EE · ~0.5s según su marketing. Ambos son sub-segundo de verdad.
StreamHub · Cada evento se postea firmado con HMAC-SHA256, verificable en tu backend.
Ant Media EE · Webhooks sin firma — confiás en quien llama.
StreamHub · MP4 a tu propio bucket por app + snapshots periódicos, VODs indexados con paginación y descarga presignada.
Ant Media EE · También graba MP4/WebM a S3 — acá hay paridad.
StreamHub · Cada app es un tenant real: rooms, S3, base de datos, tokens, cuotas, teams y roles aislados.
Ant Media EE · Las applications separan settings y streams.
StreamHub · @streamhub/adaptor shimea el WebRTCAdaptor de Ant Media: mismos callbacks y métodos, sin reescribir.
Ant Media EE · Su propio SDK WebRTCAdaptor.
StreamHub · Marketplace con verticales andando: detección YOLO, cockpit CCTV, radio, watermark, live chat.
Ant Media EE · SDK de plugins en Java — los construís vos.
StreamHub · Origin + edge; un edge se suma con un comando y un token. Instalador one-liner idempotente, TLS incluido.
Ant Media EE · Cluster origin + edge (feature EE); instalación por script más setup de licencia.
StreamHub · Prometheus /metrics nativo + Grafana, y logs con retención de 30 días directo en el panel.
Ant Media EE · Pipeline de monitoreo vía Kafka hacia Grafana.
Ant Media EE es un producto maduro y hoy sigue adelante en granularidad de configuración (~170 settings por app), SDKs móviles nativos y restream multi-destino — esto último está arriba de nuestro roadmap. Si eso es lo que te bloquea hoy, preferimos decírtelo ahora.
Cambiás el import del SDK — tus callbacks siguen funcionando.
WebRTC, RTMP, WHIP, RTSP y HLS; grabación a tu S3; realtime, multi-tenant, webhooks firmados y un SDK WebRTC liviano. Sobre LiveKit, self-hosted.
Entrá por donde quieras, salí en WebRTC de baja latencia o en HLS embebible.
Player WebRTC sobre LiveKit con latencia sub-segundo para "ver en vivo ahora" y videollamadas. Tokens de subscribe efímeros por room.
Push desde OBS/ffmpeg a rtmp://…:1935/live/<key>. Stream key + password opcional: StreamHub corta el push que no se validó antes.
Endpoint WHIP para publicar desde el navegador o encoders modernos por WebRTC, sin pasar por RTMP.
Tirá de una fuente remota (rtsp://camara/stream) y republicala en la room. Ideal para cámaras IP y NVRs.
Egress HLS segmentado servido en /hls/<app>/<room>/index.m3u8 (video.js, CORS abierto). ~6-15s, embebible en cualquier lado.
La media es tuya: se sube a tu bucket. Las salidas van a YouTube, Twitch o tu CDN.
Egress a MP4 y subida a tu propio bucket S3 (AWS, Wasabi, MinIO). Un bucket/prefijo por app; las claves nunca viven en el YAML.
Cada grabación queda como VOD en tu S3 con snapshot, metadatos (duración/resolución/codec) y URL pública o presignada.
Cortá la grabación cada N minutos: cada parte es su propio MP4 = su propio VOD, indexado y con callback recording_part_ready.
Capturá un JPEG cada N segundos durante la grabación, subido a tu S3. También snapshots on-demand de cualquier room.
Reenviá una room a un RTMP/RTMPS externo (YouTube/Twitch/custom) con el widget Transmitir: webcam del navegador → restream.
Chat, reacciones y viewers sobre data-channels; webhooks firmados de todo lo que pasa.
Chat sobre data-channels de LiveKit (con emojis). El backend puede inyectar mensajes y dispara el callback chat_message.
Reacciones animadas flotantes sobre el topic reaction: corazones y likes en tiempo real, con su callback reaction.
Conteo de subscribers reales por stream en vivo, excluyendo publishers y participantes ocultos/QC. Exportado a Prometheus.
StreamHub postea un JSON firmado (HMAC-SHA256) por CADA evento: room, participantes, ingress/egress, grabación, VOD y HLS.
Páginas públicas /play y /embed + snippet iframe. Players WebRTC y HLS sin auth, con panel de chat/reacciones/viewers incluido.
Apps aisladas, transcoding adaptativo con GPU opcional y métricas Prometheus de todo.
Ladder de renditions vía simulcast de LiveKit + ingress multi-layer para un player adaptativo por app, sin config extra.
Detección de GPU por nodo (NVIDIA nvidia-smi / VAAPI /dev/dri) y hwaccel auto/gpu/cpu por app. Nunca falla si no hay GPU.
Cada "app" es un tenant: rooms/streams namespaced, su S3, sus VODs/DB, sus tokens y callbacks. Totalmente aisladas.
Equipos aislados por tenant, roles/permisos y cuotas: apps, streams concurrentes, minutos de grabación y GB de egress al mes.
Métricas Prometheus en /metrics (streams, viewers, VODs, uploads S3, callbacks, GPU…), health probe, stats y logs consultables.
Registro global streamhub.db + una vods.db por app. Sin base pesada que operar: SQLite por tenant y media en S3 por app.
Todo lo que antes hacías por SSH, ahora en el panel: tableros por app, logs, VODs, cluster, configuración del server y backups.
Cada app tiene su propio tablero: streams activos, viewers en vivo, ingress/egress y actividad de grabación, filtrable por tenant.
Logs globales y por app con rotación a 30 días, consultables y paginados desde la API y el panel. Sin SSH.
Listado paginado de VODs por app con snapshots y metadatos, más descarga en un click vía URLs S3 presignadas.
Cada nodo con sus stats y su salud, directo en el dashboard. Un edge se suma al cluster con un token y un comando.
Configuración general del server desde el backoffice, estilo Ant Media: ajustá el server sin tocar archivos por SSH.
Backups automáticos de las bases SQLite y la config por app, con un camino documentado de restore y rollback.
Todo por API, todo self-hosteable. Sumás el SDK y empezás a publicar en pocas líneas.
Un SDK JavaScript liviano: sumás @streamhub/adaptor (npm o un <script>) y StreamHubAdaptor te deja publicar y suscribirte por WebRTC en pocas líneas.
API bajo /api/v1 con envelope { data, error }. Apps, ingress, grabación, VODs, tokens, broadcast y HLS: todo por HTTP.
Auth built-in (signup/login JWT, teams, superadmin) + API tokens sk_ para server-to-server. Bearer en todos los endpoints.
Rooms audio-only (voz estilo Discord) + modo radio: un locutor publica y los oyentes entran subscribe-only ocultos, con listen-token público.
Self-hosteable de punta a punta (Docker + LiveKit). En beta y gratis. ¿No querés operarlo? Lo hosteamos por vos.
Un stack completo y self-hostable, documentado de punta a punta. Una API REST (global y por app), webhooks firmados, config por app, integraciones nativas y un deploy en un comando. Cada ruta vive detrás de un único dominio, con un explorador OpenAPI en vivo.
Guías a fondo por función, de WebRTC a las cuotas.
Superficie REST de todo el server, protegida por tokens sk_.
Todo acotado a una única app tenant.
Eventos entrantes de LiveKit y POST firmados salientes.
El config.yaml por app, sin secretos.
Clientes nativos y de dispositivos, y el protocolo que habla cada uno.
Un curl | sudo bash — o docker compose up.
Cómo está construido y hacia dónde va.
Autenticá con un sk_
token. Los nombres de sala llevan el prefijo de la app (live + demo → live-demo).
# Scaffold an isolated tenant: config, per-app SQLite, S3 prefix, samples
curl -s -X POST https://streamhub.digitalhub.com.ar/api/v1/apps \
-H "Authorization: Bearer $STREAMHUB_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"live","displayName":"Live","roomPrefix":"live"}'
// Every callback is a signed POST. Verify the HMAC-SHA256 over the raw body.
import crypto from 'node:crypto';
app.post('/streamhub', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.header('X-StreamHub-Signature'); // "sha256=<hex>"
const expected =
'sha256=' + crypto.createHmac('sha256', SECRET).update(req.body).digest('hex');
if (!sig || !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)))
return res.status(401).end();
const evt = JSON.parse(req.body.toString('utf8')); // { event, app, data }
switch (evt.event) {
case 'stream_started': /* a publisher/ingress went live */ break;
case 'vod_ready': /* recording uploaded to your S3 */ break;
case 'recording_failed': /* upload failed, local file kept */ break;
}
res.status(200).end();
});
# Open source — one command provisions a full node (Ubuntu 24.04/26.04 LTS):
curl -fsSL https://www.streamhub.studio/install.sh | sudo bash
# docker + LiveKit + ingress/egress + core + nginx/TLS + seeded API token. Idempotent.
# Prefer to wire the pieces yourself? (non-interactive install)
curl -fsSL https://www.streamhub.studio/install.sh | sudo bash -s -- \
--non-interactive --domain media.example.com --email you@example.com
# then edit /opt/streamhub/.env (LiveKit keys, per-app S3, PUBLIC_BASE_URL)
# Swagger / OpenAPI: /api/v1/docs Metrics: /metrics Health: /api/v1/health
Esto es un recorrido, no el mapa completo — la referencia entera cubre arquitectura, operación, testing y cada variable de entorno. Exploralo en vivo en los docs OpenAPI, o leé los streamhub-docs en el repo.
@streamhub/adaptor es un SDK JavaScript liviano para publicar y suscribirte por WebRTC, construido sobre livekit-client. Habla el mismo idioma que el WebRTCAdaptor de Ant Media — mismos callbacks por string, mismos métodos — así que un front-end existente de Ant Media migra cambiando el import, no reescribiéndolo.
- import { WebRTCAdaptor } from "@antmedia/webrtc_adaptor";
+ import { StreamHubAdaptor } from "@streamhub/adaptor";
// Same callbacks, same methods — your Ant Media front-end keeps working.
const adaptor = new StreamHubAdaptor({ /* config below */ });
npm install @streamhub/adaptor livekit-client
import { StreamHubAdaptor } from "@streamhub/adaptor";
const adaptor = new StreamHubAdaptor({
// StreamHub mints the LiveKit token for you (prefer a pre-minted token + wsUrl in prod)
streamhubApiUrl: "https://streamhub.digitalhub.com.ar/api/v1",
appName: "live",
streamhubApiToken: STREAMHUB_TOKEN, // dev only — mint server-side for production
mediaConstraints: { video: true, audio: true },
localVideoId: "localVideo", // <video id="localVideo"> preview element
callback: (info, obj) => {
if (info === "initialized") adaptor.joinRoom("demo", "camera-1");
else if (info === "joinedTheRoom") adaptor.publish(obj.streamId); // send cam + mic
else if (info === "publish_started") console.log("on air");
},
callbackError: (err, msg) => console.warn(err, msg),
});
<!-- No build step? Drop in one script tag and you're ready. -->
<script src="https://streamhub.digitalhub.com.ar/sdk/streamhub-adaptor.global.js"></script>
<script>
const viewer = new StreamHubAdaptor({ isPlayMode: true, /* ...config */ });
</script>
<!-- The mint call returns a ready-to-paste embed. Public player, no SDK needed. -->
<iframe
src="https://streamhub.digitalhub.com.ar/embed/live/live-demo"
width="640" height="360" frameborder="0"
allow="autoplay; fullscreen; camera; microphone"
allowfullscreen>
</iframe>
mismos callbacks — initialized, publish_started, newStreamAvailable, data_received… — cambiás el import y tu código queda
joinRoom, publish, play, sendData, switchVideoCameraCapture, enableStats…
cambiá cámara o micrófono al vuelo y ajustá el bitrate por emisor, en vivo
chat y reacciones viajan por DataPackets de LiveKit; canPublishData va en cada token
LiveKit maneja simulcast y streaming adaptativo de forma nativa. Para producción, emití los tokens del lado del server y pasá token + wsUrl para que el token de administración nunca llegue al navegador.
Instalá un nodo completo en Ubuntu LTS con un comando, o entrá a la app hosteada.