Plataforma

Todo por dentro

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.

Arquitectura

Entra una señal, salen miles

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.

Arquitectura de streaming de StreamHub Diagrama animado: un dispositivo de ingesta transmite al nodo origen, los plugins procesan la señal, el origen la replica a los nodos edge y los edges la reparten a muchos espectadores. RTMP · WHIP · SRT replicación WebRTC · HLS Dispositivo de ingesta Origen — StreamHub Core SFU LiveKit · API · apps app: cams App (tenant) PLUGINS yolo deface scheduled-live live-chat Nodos edge edge-01 edge-02 Espectadores
Ingesta

Una señal de entrada — RTMP, WHIP o SRT desde cualquier cámara, teléfono o encoder.

Proceso

La app y sus plugins enriquecen la señal: detección, enmascarado de privacidad, programación, chat.

Distribución

El origen replica a los nodos edge; cada espectador recibe WebRTC sub-segundo o HLS en vivo.

StreamHub vs Ant Media EE vs Wowza

Todo lo que le pedís a un media server comercial, open source y self-hosted

StreamHub cubre el feature-set por el que licenciarías Ant Media Server Enterprise o Wowza 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.

0.19s

de latencia WebRTC — p50 medido sobre 601 muestras en producción

$0

de licencia — open source (AGPL). Ant Media EE: ~USD 109/mes por instancia; Wowza: licencia por instancia o SaaS facturado por uso

1 línea

para instalar — curl | sudo bash en Ubuntu o Debian

Licencia y precio

StreamHub · Open source (AGPL). Sin licencia por instancia — gratis mientras dura la beta. Solo pagás si lo hosteamos nosotros.

Ant Media EE · Propietario. ~USD 109/mes (~USD 1.068/año) por instancia.

Wowza · Propietario. Streaming Engine: licencia por instancia por suscripción. Wowza Video: SaaS facturado por uso.

Self-hosteable

StreamHub · Sí — tus servidores, tus datos. Instalador de una línea en Ubuntu/Debian, TLS incluido.

Ant Media EE · Sí — self-hosted o su nube administrada.

Wowza · Streaming Engine: sí (Linux/Windows). Wowza Video: solo nube (SaaS).

Latencia WebRTC

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.

Wowza · WebRTC soportado; históricamente más fuerte en flujos RTMP/HLS. Tier real-time sub-segundo en Wowza Video.

Ingest y playback RTMP / HLS

StreamHub · Entrada RTMP/RTMPS, WHIP, RTSP y SRT; salida WebRTC + HLS en vivo.

Ant Media EE · Entrada RTMP, WebRTC, SRT; salida HLS/DASH.

Wowza · Soporte de protocolos muy amplio: entrada RTMP, SRT, RTSP; salida HLS/DASH. Un punto fuerte.

RTMP passthrough / entrega sin transcodear

StreamHub · Nuevo: un push RTMP H.264/AAC remuxeado directo a HLS (ffmpeg -c copy), sin pasar por el SFU — sin encode, CPU casi nula, sin GPU. Solo HLS (sin WebRTC / ABR / grabación), pero ahora cubre el caso barato RTMP→HLS que un server LiveKit no podía hacer.

Ant Media EE · Un punto fuerte — crédito donde corresponde: Ant Media reempaqueta de forma nativa una fuente RTMP a HLS/DASH (y WebRTC) sin re-encodear. El ingest barato sin transcodear es toda su propuesta.

Wowza · También fuerte: Streaming Engine transmuxea / reempaqueta RTMP a HLS/DASH sin re-encodear — una capacidad histórica de Wowza.

Ingest SRT

StreamHub · Nuevo: push SRT sobre el plano passthrough — contribución UDP con retransmisión y un presupuesto de latencia de ~120 ms por defecto, remuxeado directo a HLS con CPU casi nula; la key viaja como streamid. Alcance honesto: un push SRT es solo HLS (sin WebRTC/ABR desde ahí); una fuente srt:// remota igual se puede tirar hacia el camino de transcode vía URL ingress.

Ant Media EE · Ingest SRT nativo alimentando su pipeline completo — WebRTC, HLS/DASH y ABR desde una fuente SRT. Un punto genuinamente fuerte.

Wowza · SRT nativo en Streaming Engine — ingest y también stream targets SRT (salida); una de las implementaciones SRT más veteranas del rubro.

Ingest de radio audio-only / baja CPU

StreamHub · El ingest audio-only descarta la pista de video → solo el transcode trivial AAC→Opus, ~1-2% de CPU por canal sin GPU. Radio/podcast sin granja de transcode; el WebRTC + HLS + features de sala quedan intactos.

Ant Media EE · Soporta streaming audio-only; los canales de audio de bajo footprint están dentro de lo suyo.

Wowza · Soporta streaming audio-only; los flujos audio-only eficientes son estándar en Streaming Engine.

Webhooks

StreamHub · Cada evento se postea firmado con HMAC-SHA256, verificable en tu backend.

Ant Media EE · Webhooks sin firma — confiás en quien llama.

Wowza · Wowza Video ofrece webhooks; en Streaming Engine necesitás módulos Java propios.

Grabación → S3

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.

Wowza · Grabación y nDVR soportados; entrega a S3 vía módulos/integraciones.

Multi-tenant

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.

Wowza · Applications por instancia de Streaming Engine; la tenancy corre por tu cuenta.

SDK de migración

StreamHub · @streamhub/adaptor shimea el WebRTCAdaptor de Ant Media: mismos callbacks y métodos, sin reescribir.

Ant Media EE · Su propio SDK WebRTCAdaptor.

Wowza · Sus propios SDKs y player (Flowplayer); sin shim compatible con Ant Media.

Marketplace de apps (Studio)

StreamHub · Diez apps completas con su propia base de datos, vista de página completa en el dashboard y export de un clic para correr de forma independiente: LPR, conteo de personas IN/OUT, intrusión perimetral, presencia en puestos, monitoreo de EPP (experimental), detección YOLO, difuminado de rostros, transcripción de VOD, cockpit CCTV y gestión de fleet de agentes.

Ant Media EE · Un SDK de plugins en Java más un ejemplo de detección de objetos con TensorFlow — sin marketplace de apps listas para usar; las verticales llave en mano las construís vos.

Wowza · Un SDK de módulos Java + una colección de módulos mantenidos — sin marketplace de apps; las verticales las armás vos.

Plugins

StreamHub · Extensiones livianas, in-process — players, overlays y paneles: player Vidstack, timestamp, watermark, calidad / salud del stream, radio, estudio de transmisión y vivo programado. Activalos por app.

Ant Media EE · SDK de plugins en Java — los construís vos; el player y los overlays no son slots enchufables del server.

Wowza · SDK de módulos Java + módulos mantenidos; el player es un producto aparte (Flowplayer).

Exportar apps a tu propia infra

StreamHub · Sí — cualquier app con worker se exporta como un bundle autocontenido (worker, Dockerfile, compose, plantilla de env) que corre en tu propia infra y habla de vuelta por la API REST y webhooks firmados con HMAC. API-first, no anidado.

Ant Media EE · Los plugins corren in-process en el media server (SDK Java); no hay concepto de export a standalone.

Wowza · Los módulos corren dentro de Streaming Engine; sin marketplace ni export de apps.

CCTV / analítica de video con IA

StreamHub · Apps de visión integradas sobre modelos abiertos — patentes (fast-alpr, MIT), conteo de personas IN/OUT (YOLOv8 + ByteTrack), intrusión perimetral con evidencia en disco, presencia en puestos de trabajo, monitoreo de EPP (experimental, solo advisory). Además Vision Edge: un clúster distribuido de nodos edge GPU/CPU que se conectan hacia el master (amigable con NAT) para aforo, conteo, multitud y demografía en tiempo real. Workers gestionados por el framework, eventos firmados con HMAC + MQTT, viable en CPU, GPU opcional.

Ant Media EE · SDK de plugins en Java más un plugin de ejemplo de detección de objetos con TensorFlow; la analítica CCTV lista para usar (patentes, conteo, intrusión) la construís vos.

Wowza · Sin analítica de video integrada — Streaming Engine se enfoca en el transporte; integrás servicios de CV externos vía su SDK de módulos.

Descubrimiento ONVIF de cámaras

StreamHub · Vía el StreamHub Agent en la LAN de las cámaras: onvif scan descubre cada cámara ONVIF (WS-Discovery + Profile S) y onvif sync las registra como ingest — pull RTSP o passthrough HLS de CPU casi nula — incluso con el servidor en la nube. Re-ejecuciones idempotentes, re-escaneo periódico opcional.

Ant Media EE · El alta de cámaras IP ONVIF existe en su panel para cámaras que el propio servidor alcanza; no hay agente de borde que descubra una LAN remota del cliente.

Wowza · Sin descubrimiento ONVIF — las fuentes RTSP/SRT se configuran por URL. Nota justa: ambos son media servers, no VMS.

Cluster e instalación

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.

Wowza · Origin/edge + load balancing en Streaming Engine; instalador más clave de licencia.

Observabilidad

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.

Wowza · Monitoreo REST/JMX en Streaming Engine; dashboards en Wowza Video.

Claves de stream primaria + backup

StreamHub · Failover integrado: dos claves RTMP a una sola sala, misma URL de player esté vivo el encoder que esté — redundancia estilo Dacast/Vimeo, sin cambiar la URL.

Ant Media EE · La redundancia es a nivel cluster (origin/edge); sin clave de backup por stream.

Wowza · Wowza Video expone URLs de fuente de backup; Streaming Engine vía alias de nombre de stream / source failover.

Visualización del pipeline en vivo

StreamHub · Diagrama de flujo animado por app (ingest → transcode → entrega → almacenamiento → plugins) renderizado desde la config real.

Ant Media EE · Métricas de dashboard y stats por stream; sin diagrama de topología por app.

Wowza · Stats de entrada/salida en Engine Manager; sin diagrama de pipeline en vivo.

Canales lineales 24/7 + DVR

StreamHub · Sala persistente (sin recambio de SID cuando cae la fuente), watchdog auto-HLS y manifest DVR acotado + limpieza de segmentos.

Ant Media EE · Ingest continuo y playlists de stream; la ventana DVR es manual.

Wowza · Fuerte acá: nDVR integrado; lineal vía playlists SMIL / programadas.

Monitoreo de cluster incluido

StreamHub · Trae Prometheus + dashboards Grafana + agregación de logs Loki/Promtail en cada nodo, con instaladores idempotentes.

Ant Media EE · Expone métricas (Kafka/Prometheus); el stack Grafana + logs lo armás vos.

Wowza · Métricas REST/JMX; dashboards en Wowza Video. Sin stack de logs Loki incluido.

Offload a GPU propia

StreamHub · Los workers de IA/transcode se despachan a tus propios nodos GPU sobre el cluster (GRID); caen a local cuando no hay match.

Ant Media EE · Transcoding GPU en el nodo de media; sin pool externo de workers GPU.

Wowza · Aceleración GPU (NVENC/QSV) en el host del engine; sin offload externo de workers GPU.

Roles de nodo + bloqueo de login en edge

StreamHub · Roles standalone/master/edge por DB; un edge sirve playback pero bloquea el login de admin. Convertí standalone ↔ cluster en el lugar.

Ant Media EE · Roles de cluster origin/edge; sin bloqueo de login de admin por nodo.

Wowza · Origin/edge + load balancing; sin bloqueo de login del portal por nodo.

Player avanzado intercambiable (Vidstack)

StreamHub · El player de HLS + VOD es un slot de plugin: activá Vidstack por app — moderno, accesible, capaz de HLS/DASH/DRM — y /play + /embed lo toman. video.js queda como fallback; el WebRTC sub-segundo no se toca.

Ant Media EE · Trae su propio web player embebido y SDK JS de player; el player no es un slot enchufable del server — cambiar de player es cablearlo vos.

Wowza · El player es un producto aparte: Flowplayer (propiedad de Wowza, licencia separada) o traés tu propio player sobre HLS/DASH.

Control de plugins por stream

StreamHub · Los plugins de la app aplican a todos los streams en vivo por defecto; sacá un stream puntual de plugins específicos desde la API o la pestaña Streams — los demás los mantienen y los players lo respetan en vivo.

Ant Media EE · Los plugins se enganchan a nivel application (SDK Java); el comportamiento por stream corre por tu código de plugin.

Wowza · Los módulos se atan por application en Streaming Engine; la lógica por stream es Java propio.

Entrega VOD + CDN

StreamHub · VOD detrás de cualquier CDN delante de tu S3, HLS en vivo detrás de un CDN con cache headers correctos, o los propios nodos edge del cluster como CDN pull-through. StreamHub puede ser el backend de media de un OTT propio: vivo + VOD + CDN + player.

Ant Media EE · Integración con CDN documentada (p. ej. CloudFront delante); VOD desde S3; los edges del cluster distribuyen streams.

Wowza · Genuinamente fuerte acá: Wowza Video incluye entrega por CDN; Streaming Engine empuja stream targets a CDNs de terceros (Akamai, Fastly…).

Opción administrada

StreamHub · Opcional: operamos un clúster dedicado por vos — pagás infra + operación, nunca una licencia de software.

Ant Media EE · Nube administrada, precio por instancia.

Wowza · Wowza Video SaaS, facturado por uso.

Sin humo

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. Wowza es un veterano de 15+ años con la matriz de protocolos más amplia del rubro (SRT, transcoding y nDVR integrados) y un SaaS totalmente administrado. Si eso es lo que te bloquea hoy, preferimos decírtelo ahora.

¿Venís de Ant Media o de Wowza?

Desde Ant Media: cambiás el import del SDK — tus callbacks siguen funcionando. Desde Wowza: tus pipelines RTMP/HLS mapean directo al ingest de StreamHub.

Funciones

Un media server completo, self-hosted

WebRTC, RTMP, SRT, WHIP, RTSP y HLS; grabación a tu S3; realtime, multi-tenant, webhooks firmados, plugins de visión IA (patentes, conteo, perímetro) y un SDK WebRTC liviano. Sobre LiveKit, self-hosted.

Streaming

Ingest y salida multi-protocolo

Entrá por donde quieras, salí en WebRTC de baja latencia o en HLS embebible.

WebRTC de baja latencia

sub-segundo

Player WebRTC sobre LiveKit con latencia sub-segundo para "ver en vivo ahora" y videollamadas. Tokens de subscribe efímeros por room.

Ingest RTMP / RTMPS

RTMP · RTMPS · OBS

Push desde OBS/ffmpeg por RTMP o RTMPS cifrado con TLS a …:1935/live/<key>. Stream key + password opcional: StreamHub corta el push que no se validó antes.

RTMP passthrough (sin transcodear)

remux · CPU casi nula · sin GPU

Ingest barato estilo AntMedia que un server LiveKit normalmente no puede hacer: tomás un push RTMP H.264/AAC y lo remuxeás directo a HLS (ffmpeg -c copy), sin pasar por el SFU — sin encode de video, así la CPU queda casi ociosa sin GPU y escala ancho. El trade es honesto: solo HLS (sin WebRTC/sub-segundo), una sola rendition (sin ABR), la fuente ya tiene que ser H.264/AAC, y sin grabación ni features de sala. Apagado por defecto (env-gated); excluyente con el transcoding.

Ingest SRT

SRT · UDP · ~120 ms

Push por SRT para enlaces de contribución largos y con pérdida: UDP con retransmisión y un presupuesto de latencia de ~120 ms por defecto, donde RTMP-sobre-TCP sufre. Corre sobre el mismo plano passthrough — remux directo a HLS (ffmpeg -c copy), CPU casi nula, sin GPU — así que aplica el mismo trade honesto: salida solo HLS, la fuente ya en H.264/AAC. La key viaja como streamid (la key ES la credencial, sin usuario/contraseña), con el flujo de alta completo en el dashboard. ¿Necesitás WebRTC desde una fuente SRT? Tirá de ella con un URL ingress srt:// hacia el camino de transcode.

Ingest de radio audio-only

radio · podcast · ~1-2% CPU

Marcás un ingress RTMP como audio-only y el ingress descarta la pista de video entrante — sin ningún encode de video, solo el transcode trivial de audio AAC→Opus. Para un canal de radio o podcast esto baja la CPU de ingress de ~85%/canal a ~1-2%, el camino sin GPU a carga muy baja. Sigue saliendo WebRTC + HLS con todas las features de sala.

WHIP

WebRTC-HTTP

Endpoint WHIP para publicar desde el navegador o encoders modernos por WebRTC, sin pasar por RTMP.

RTSP relay

RTSP pull

Tirá de una fuente remota (rtsp://camara/stream) y republicala en la room. Ideal para cámaras IP y NVRs.

HLS en vivo

video.js

Egress HLS segmentado servido en /hls/<app>/<room>/index.m3u8 (video.js, CORS abierto). ~6-15s, embebible en cualquier lado.

Claves primaria + backup

failover

Dos claves RTMP hacia la MISMA sala — primaria preferida, backup en standby. Misma URL de player esté vivo el encoder que esté: redundancia estilo Dacast/Vimeo sin cambiar la URL.

Canales lineales 24/7

always-on · DVR

Sala persistente que sobrevive un corte de la fuente (sin recambio de SID), watchdog que relanza un egress HLS caído y manifest DVR acotado con limpieza de segmentos. Distribución always-on estilo radio.

Ingest MPEG-TS / UDP (incl. multicast)

MPEG-TS · UDP · SSM · remux

Tirá de un transport stream MPEG-TS estilo broadcast por UDP — unicast o multicast, incluyendo multicast source-specific de RFC 4607 — y remuxealo directo a HLS (ffmpeg -c copy), sin pasar por LiveKit. Cada fuente udp:// se parsea, se valida contra una lista permitida y se reconstruye en el servidor, así nada de lo que escribas llega a ffmpeg sin escapar. Mismo trade honesto que RTMP/SRT: solo HLS, la fuente ya tiene que ser H.264/AAC.

Grabación y salida

Grabá en tu propio S3, restreameá a donde quieras

La media es tuya: se sube a tu bucket. Las salidas van a YouTube, Twitch o tu CDN.

Grabación a TU S3

AWS · Wasabi · MinIO

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.

VOD listo para reproducir

VOD

Cada grabación queda como VOD en tu S3 con snapshot, metadatos (duración/resolución/codec) y URL pública o presignada.

Split MP4 por partes

split N min

Cortá la grabación cada N minutos: cada parte es su propio MP4 = su propio VOD, indexado y con callback recording_part_ready.

Snapshots periódicos

JPEG cada Ns

Capturá un JPEG cada N segundos durante la grabación, subido a tu S3. También snapshots on-demand de cualquier room.

Broadcast webcam → RTMP

YouTube · Twitch

Reenviá una room a un RTMP/RTMPS externo (YouTube/Twitch/custom) con el widget Transmitir: webcam del navegador → restream.

Entrega CDN y VOD

OTT-ready

Serví VOD con un CDN delante de tu S3 (base pública), HLS en vivo detrás de un CDN con cache headers correctos para CDN, o convertí los nodos edge del cluster en un CDN pull-through. Recetas híbridas para armar un OTT: vivo + VOD + CDN + player.

Templates de nombre + retención de VOD

${date:…} · retención 7-360d

Nombrá grabaciones y snapshots con placeholders — ${app} ${streamId} ${room} ${ts} ${date:…} ${var.NAME} — aplicados de forma segura ante traversal al archivo local y a la key de S3. Configurá una ventana de retención por app (7/30/90/180/360 días, o apagada) y un janitor borra la fila de la DB y el objeto en S3 cuando vence.

Realtime

Interacción en vivo y eventos

Chat, reacciones y viewers sobre data-channels; webhooks firmados de todo lo que pasa.

Chat en vivo

data-channel

Chat sobre data-channels de LiveKit (con emojis). El backend puede inyectar mensajes y dispara el callback chat_message.

Reacciones

reactions

Reacciones animadas flotantes sobre el topic reaction: corazones y likes en tiempo real, con su callback reaction.

Contador de viewers

en vivo

Conteo de subscribers reales por stream en vivo, excluyendo publishers y participantes ocultos/QC. Exportado a Prometheus.

Webhooks firmados

HMAC-SHA256

StreamHub postea un JSON firmado (HMAC-SHA256) por CADA evento: room, participantes, ingress/egress, grabación, VOD y HLS.

Players embebibles + compartir en un click

/play · /embed · compartir

Páginas públicas /play y /embed que auto-detectan el stream: si hay una playlist HLS en vivo arrancan en HLS — así los canales passthrough simplemente se ven — con toggle WebRTC | HLS en /play y panel de chat/reacciones/viewers incluido. Un menú Compartir en cada stream en vivo copia la URL del player, el iframe de /embed, el .m3u8 público o un snippet video.js autocontenido.

Player avanzado intercambiable

Vidstack · plugin

El player de HLS + VOD es un slot de plugin: activá el plugin Vidstack en una app y reemplaza al video.js integrado — moderno, modular, accesible, capaz de HLS/DASH/DRM. /play y /embed también lo resuelven; el WebRTC sub-segundo no se toca. La vista En vivo suma un selector Vidstack | video.js cuando hay un provider activo, cada uno con su propio embed.

Widget embebible con token

firmado · expira · sin sk_/JWT en la página

Firmá un link de reproducción y recibís un playUrl/embedUrl con expiración, acotado a la app+room, y su snippet de iframe — validado en el servidor por HMAC en cada request a /embed. Ponelo en cualquier página que no controlás: un token sk_ o un JWT nunca tiene que aparecer en el snippet.

CCTV y visión IA

Convertí las cámaras en sensores

Cinco apps de visión — de las diecisiete apps completas de Studio en todo el marketplace — que miran cualquier stream en vivo y emiten eventos firmados: modelos open source, viables en CPU por defecto (GPU opcional), un worker gestionado por app con start/stop/logs en el panel, descargable a tus nodos GPU vía GRID. Pensadas para instaladores de CCTV y empresas de seguridad — y como el resto de StreamHub, las apps son open source: nunca hay licencia de analítica por cámara. Lo que vendemos es despliegue, integración y operación gestionada.

Reconocimiento de patentes

LPR · ALPR · modelos abiertos

ALPR en tiempo real solo con modelos open source (fast-alpr, MIT: detección de patentes YOLOv9-t + OCR ONNX) — amigable con CPU, CUDA opcional. Lecturas deduplicadas con veredicto de lista blanca/negra (plate.detected / allowed / denied), snapshots y log SQLite por plugin, más un callback directo para cosas como abrir una barrera.

Conteo de personas

IN/OUT · YOLOv8 + ByteTrack

Conteo por cruce de línea sobre el stream en vivo: dibujás (y rotás) la línea de conteo sobre un frame en vivo directo en el dashboard, y tenés totales IN/OUT, ocupación en vivo y alertas de aforo (count.in / count.out / occupancy.limit). La lógica de conteo viene portada de un contador de entrada de local validado en producción.

Presencia en puestos de trabajo

zonas · horario

Dibujás zonas de puesto sobre un frame en vivo y recibís presence.absent cuando una zona queda vacía más allá del umbral, presence.returned cuando alguien vuelve y presence.after_hours fuera del horario laboral — con una línea de tiempo de ocupación por zona en su pestaña del dashboard.

Intrusión perimetral

horario armado · evidencia

Vigila zonas restringidas mientras está ARMADO — por horario diario (timezone IANA, reglas de fin de semana) o con un toggle manual de armado/desarmado. Cada intrusión guarda evidencia en disco (JPEG + clip sin re-encodear) y entra a una cola de alertas con acuse; el estado de armado y las alertas solo se leen autenticado.

Monitor de EPP

EXPERIMENTAL · casco · chaleco

Marca a una persona dentro de una zona de trabajo, en horario laboral, sin el casco o el chaleco reflectante requerido — solo violaciones sostenidas (N frames consecutivos + cooldown), cada una con su JPEG de evidencia. Alcance honesto: un modelo ONNX abierto de la comunidad, señales para que revise un humano — no un sistema de seguridad certificado.

Canal de eventos y datos de plugins

eventos firmados · MQTT

El canal del framework sobre el que corre la ola de visión: los workers postean los eventos de dominio que declara el manifiesto del plugin (auth por ingest-token, spoofing rechazado) y StreamHub los reenvía por los webhooks firmados con HMAC de la app + MQTT; lecturas de datos en vivo autenticadas alimentan la pestaña de cada plugin. Cualquier plugin que escribas lo tiene gratis.

Descubrimiento ONVIF vía el Agent

onvif scan · sync

Apuntá el StreamHub Agent a la LAN de las cámaras: onvif scan encuentra cada cámara ONVIF (WS-Discovery + Profile S, Python stdlib puro) y onvif sync las registra en StreamHub — pull RTSP o passthrough HLS de CPU casi nula por cámara, re-ejecuciones idempotentes, re-escaneo periódico opcional. Un comando pone en línea un sitio entero, incluso con el servidor en la nube.

Paquete de compliance

deface · watermark · audit

Las piezas de privacidad que un despliegue CCTV tiene que responder ya vienen incluidas: deface enmascara rostros en el player (detección en el servidor, enmascarado en el cliente), los overlays de watermark y timestamp marcan la evidencia, cada acción de admin/API queda en el audit trail, y las URLs de reproducción van firmadas.

Escala

Multi-tenant, adaptativo y observable

Apps aisladas, transcoding adaptativo con GPU opcional y métricas Prometheus de todo.

Transcoding adaptativo

720 / 480 / 240

Ladder de renditions vía simulcast de LiveKit + ingress multi-layer para un player adaptativo por app, sin config extra.

GPU opcional

NVENC · VAAPI

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.

Apps multi-tenant aisladas

apps

Cada "app" es un tenant: rooms/streams namespaced, su S3, sus VODs/DB, sus tokens y callbacks. Totalmente aisladas.

Teams, roles y cuotas

RBAC · quotas

Equipos aislados por tenant, roles/permisos y cuotas: apps, streams concurrentes, minutos de grabación y GB de egress al mes. La config de cada app suma sus propios topes de streams concurrentes y viewers por stream, sin límite por defecto.

Observabilidad

Prometheus

Métricas Prometheus en /metrics (streams, viewers, VODs, uploads S3, callbacks, GPU…), health probe, stats y logs consultables.

Per-app SQLite

SQLite

Registro global streamhub.db + una vods.db por app. Sin base pesada que operar: SQLite por tenant y media en S3 por app.

Offload a tu propia GPU

GRID

Los workers de plugins y de transcode se despachan a tus propios nodos GPU sobre el cluster (placement: grid) y caen a local cuando no hay nodo GPU. Ponés la GPU y el origin queda liviano.

Relay TURN para WebRTC multi-nodo

ICE · NAT traversal

Servidor TURN dedicado (`--turn`) que relaya el media WebRTC cuando los peers están detrás de NATs/firewalls restrictivos en un cluster multi-nodo — el cliente no necesita nada, los ICE servers llegan en la respuesta de join.

Operaciones

Un backoffice que maneja toda la flota

Todo lo que antes hacías por SSH, ahora en el panel: tableros por app, logs, VODs, cluster, configuración del server y backups.

Tablero por app

stats · filtros

Cada app tiene su propio tablero: streams activos, viewers en vivo, ingress/egress y actividad de grabación, filtrable por tenant.

Gestión de logs

retención 30 días

Logs globales y por app con rotación a 30 días, consultables y paginados desde la API y el panel. Sin SSH.

Biblioteca de VODs + descarga

paginado · presigned

Listado paginado de VODs por app con snapshots y metadatos, más descarga en un click vía URLs S3 presignadas.

Gestor de cluster

origin + edge

Cada nodo con sus stats y su salud, directo en el dashboard. Un edge se suma al cluster con un token y un comando.

Panel de configuración del server

sin editar YAML

Configuración general del server desde el backoffice, estilo Ant Media: ajustá el server sin tocar archivos por SSH.

Backups in-app + runbook

restore · rollback

Disparás, descargás y restaurás backups de las bases SQLite y la config por app directo desde el panel, con un camino documentado de rollback.

Audit trail

listo para ISO

Cada acción de admin y de API queda registrada en un audit trail — quién hizo qué, cuándo y desde dónde. Evidencia a mano para revisiones estilo ISO.

OS tuning + historial de recursos

sysctl · historial

Tuning del sistema operativo para cargas de media en un click, más dashboards de historial de CPU/memoria/disco/red por nodo para ver tendencias, no solo fotos.

Diagrama de pipeline en vivo

flujo animado

El Overview dibuja el pipeline real de cada app — ingest → transcode → entrega → almacenamiento → plugins — como un flujo animado desde GET /apps/:app/pipeline, con pulsos activo-vs-configurado. Respeta el tema y reduced-motion.

Monitoreo de cluster incluido

Prometheus · Grafana · Loki

Trae un overlay de observabilidad de cluster: un Prometheus central scrapeando cada nodo, dashboards Grafana y agregación de logs Loki/Promtail en toda la flota, con instaladores idempotentes.

Roles de nodo + edge lock

master · edge

Roles de nodo por DB (standalone / master / edge). Un edge sirve el portal público y el playback pero bloquea el login de admin, así un nodo de cluster no se usa como standalone. Convertí standalone ↔ cluster en el lugar.

Control de plugins por stream

opt-out

Los plugins de la app aplican a todos los streams en vivo por defecto; editá un stream puntual y apagá plugins específicos solo para ese stream — el resto los mantiene. Editor por stream en la pestaña Streams, y los players respetan el opt-out en vivo.

Versionado de apps + rollback

inmutable · sha256

Cada versión de una app se guarda de forma inmutable (DATA_DIR/appstore/), verificada por sha256 antes de correr. Fijá o volvé atrás cualquier app a una versión anterior desde el panel o la CLI `streamhub app` — un bundle alterado cae al builtin, nunca a un crash-loop. Doce de las apps del marketplace ya viven en sus propios repos versionados y se componen en el build fijadas por sha256 de contenido — indistinguibles de las built-in en runtime.

Wizard guiado de alta de apps

saltable

Crear una app abre un wizard orientado al propósito (vigilancia / radio / eventos / 1:1 / live shopping / general) que configura grabación, escala de viewers y plugins de visión por vos — siempre saltable, aplica todo best-effort con links directos a lo que configuró.

Streamflow — automatización por eventos

estilo n8n · secrets · nodos de ejecución

Motor visual de workflows disparado por cualquier evento del core, un plugin o el cluster: secrets encriptados por app (AES-256-GCM, write-only, nunca se leen de vuelta), export/import como JSON, y nodos de ejecución opcionales de código/SSH/shell/SQL — todos detrás de un flag de nodos peligrosos, apagado por defecto. Corre in-core, sin worker que gestionar.

Live Control — pausar / reanudar / finalizar

portadas · mute de audio

Tomá el control de un stream ya en vivo desde el panel o la API: pausalo detrás de una portada configurada (imagen, video en loop o tarjeta de texto) con el audio muteado, reanudalo de vuelta al vivo, o finalizalo con una tarjeta de cierre. Valores por defecto por app, override por stream, cada transición dispara un callback firmado.

Monitor Stream Health

stall · desync · silencio · MQTT

Un worker muestrea la salida HLS de cada stream en vivo y convierte anomalías — stalls, segmentos perdidos o discontinuos, desync de audio/video, silencio o pista de audio faltante, caídas de bitrate — en eventos de webhook firmado + MQTT + Streamflow, con una grilla de estado worst-first en el dashboard. Muy por debajo del 1% de CPU por stream con la cadencia default de 10s.

Timezone por app

IANA · hora local

Asignale a una app un timezone IANA y cada timestamp scoped a esa app en el dashboard — logs, inicio de streams, VODs, scheduled-live — se muestra en esa zona, así dos admins en dos husos ven la misma hora. También queda como default para cualquier horario de plugin que deje su propio timezone vacío.

SMTP por app + por usuario

usuario > app > global

Reemplazá el relay SMTP global por app o por usuario, resuelto usuario > app > global con fallback best-effort, así un override mal configurado nunca bloquea un magic-link o un email de alerta. Las contraseñas van encriptadas (secrets store por app, AES-256-GCM para la personal), con un endpoint de envío de prueba que saltea el gate de habilitado.

Devs

API, SDK drop-in y open source

Todo por API, todo self-hosteable. Sumás el SDK y empezás a publicar en pocas líneas.

SDK JS drop-in

@streamhub/adaptor

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 REST

/api/v1

API bajo /api/v1 con envelope { data, error }. Apps, ingress, grabación, VODs, tokens, broadcast y HLS: todo por HTTP.

Auth + API tokens

JWT · sk_ tokens

Auth built-in (signup/login JWT, teams, superadmin) + API tokens sk_ para server-to-server. Bearer en todos los endpoints.

Radio / audio-only

audio-only

Rooms audio-only (voz estilo Discord) + modo radio: un locutor publica y los oyentes entran subscribe-only ocultos, con listen-token público.

Open source o hosted

self-host · hosted

Self-hosteable de punta a punta (Docker + LiveKit). En beta y gratis. ¿No querés operarlo? Lo hosteamos por vos.

Documentación

Docs y API

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.

Funciones

Guías a fondo por función, de WebRTC a las cuotas.

  • WebRTC · ingest · HLS en vivo
  • Grabación → S3 · VOD
  • Transmisión · transcoding/GPU
  • Chat · reacciones · espectadores

API Global

Superficie REST de todo el server, protegida por tokens sk_.

  • GET /health · /stats
  • CRUD /apps
  • POST /tokens (emite sk_)
  • GET /logs
Abrir en Swagger →

API por app

Todo acotado a una única app tenant.

  • tokens · ingress · grabación
  • vods · streams · snapshots
  • HLS start/stop
  • config · capas de transcoding
Abrir en Swagger →

Webhooks y callbacks

Eventos entrantes de LiveKit y POST firmados salientes.

  • firma HMAC-SHA256
  • stream_started / _ended
  • vod_ready · recording_failed
  • chat_message · reaction

Referencia de config

El config.yaml por app, sin secretos.

  • recording · rtmp · webrtc
  • bucket S3 por app
  • bloque features
  • callbacks url + secret

Integraciones

Clientes nativos y de dispositivos, y el protocolo que habla cada uno.

  • Android (livekit-android)
  • iOS (LiveKitClient)
  • C++ (ffmpeg → RTMP)
  • ESP32-CAM → relay → RTMP

Self-hosting

Un curl | sudo bash — o docker compose up.

  • instalador one-liner (Ubuntu · Debian)
  • join-cluster con un token
  • runbook · backups · rollback
  • Prometheus + Grafana

Arquitectura

Cómo está construido y hacia dónde va.

  • core mono-Node + LiveKit
  • modelo de datos SQLite por app
  • cluster origin + edge
  • WebRTC vs HLS/CDN

La API REST en cinco llamadas

Autenticá con un sk_ token. Los nombres de sala llevan el prefijo de la app (live + demolive-demo).

base · https://streamhub.digitalhub.com.ar/api/v1
# 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"}'
# One call returns the LiveKit token + wsUrl + play/embed URLs
curl -s -X POST https://streamhub.digitalhub.com.ar/api/v1/apps/live/tokens \
  -H "Authorization: Bearer $STREAMHUB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"room":"demo","identity":"viewer-1","canPublish":false,"ttl":"10m"}'
# → { "data": { "token": "<jwt>", "wsUrl": "wss://media.digitalhub.com.ar",
#              "room": "live-demo", "playUrl": "...", "embedUrl": "...", "iframe": "..." } }
# RTMP push endpoint (also: whip, or url for RTSP/HLS pull)
curl -s -X POST https://streamhub.digitalhub.com.ar/api/v1/apps/live/ingress \
  -H "Authorization: Bearer $STREAMHUB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"inputType":"rtmp","room":"demo","enableTranscoding":true}'
# → { "data": { "ingressId": "IN_abc123", "streamKey": "sk-9f3c...", "roomName": "live-demo" } }

# then push with any RTMP encoder (OBS, ffmpeg, a drone...)
ffmpeg -re -i input.mp4 -c:v libx264 -c:a aac \
  -f flv "rtmp://media.digitalhub.com.ar:1935/live/<streamKey>"
# Room-composite MP4 → the app's own bucket (AWS / Wasabi / MinIO) → VOD + snapshot
curl -s -X POST https://streamhub.digitalhub.com.ar/api/v1/apps/live/recording/start \
  -H "Authorization: Bearer $STREAMHUB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roomName":"live-demo"}'
# → { "data": { "vodId": 12, "egressId": "EG_xyz789", "status": "recording" } }

# stop it (by VOD id or egress id); a vod_ready webhook fires when the upload finishes
curl -s -X POST https://streamhub.digitalhub.com.ar/api/v1/apps/live/recording/12/stop \
  -H "Authorization: Bearer $STREAMHUB_TOKEN"
# Start a live HLS egress for a stream (video.js-compatible, embeddable)
curl -s -X POST \
  https://streamhub.digitalhub.com.ar/api/v1/apps/live/streams/live-demo%2Fcamera-1/hls/start \
  -H "Authorization: Bearer $STREAMHUB_TOKEN"
# → { "data": { "playlistUrl":
#       "https://streamhub.digitalhub.com.ar/hls/live/live-demo/index.m3u8" } }

# the playlist itself needs no auth — point any HLS player at it
open https://streamhub.digitalhub.com.ar/hls/live/live-demo/index.m3u8
Webhooks firmados HMAC-SHA256
// 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();
});
Self-host en un comando curl | sudo bash
# Open source — one command provisions a full node (Ubuntu · Debian 12/13):
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

Un SDK WebRTC liviano — publicá y suscribite en pocas líneas

@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.

migrando desde Ant Media: cambiás un import
- 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 */ });
Instalar npm
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),
});
import { StreamHubAdaptor } from "@streamhub/adaptor";

const viewer = new StreamHubAdaptor({
  streamhubApiUrl:   "https://streamhub.digitalhub.com.ar/api/v1",
  appName:           "live",
  streamhubApiToken: STREAMHUB_TOKEN,
  isPlayMode:        true,                    // subscribe-only: no camera / mic
  callback: (info, obj) => {
    if (info === "initialized")        viewer.joinRoom("demo", "viewer-1");
    else if (info === "joinedTheRoom") viewer.play(obj.ATTR_ROOM_NAME);
    else if (info === "newStreamAvailable") {
      const el = document.createElement("video");
      el.autoplay = el.playsInline = true;
      el.srcObject = new MediaStream([obj.track]);   // obj.track is a MediaStreamTrack
      document.getElementById("remote").append(el);
    }
  },
});
¿Sin build? Sumá una sola etiqueta IIFE · CDN
<!-- 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>
Reproductor embebible <iframe>
<!-- 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>

Drop-in del WebRTCAdaptor de Ant Media

mismos callbacks — initialized, publish_started, newStreamAvailable, data_received… — cambiás el import y tu código queda

Métodos

joinRoom, publish, play, sendData, switchVideoCameraCapture, enableStats…

Control de dispositivo y bitrate

cambiá cámara o micrófono al vuelo y ajustá el bitrate por emisor, en vivo

Canales de datos

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.

¿Listo para levantarlo?

Instalá un nodo completo en Ubuntu o Debian con un comando, o empezá una prueba gratis del hosting gestionado.