El mercado de plugins: extender sin bifurcar
Nueve plugins integrados y un framework que los descubre desde el sistema de archivos — sin un registro central que editar. Cómo StreamHub deja que las funciones se enchufen tanto al backend como al panel.
Funciones que se enchufan, no que se bifurcan
StreamHub incluye un pequeño framework de plugins para que las funciones se conecten al backend y al panel sin editar ningún registro central. Un plugin es simplemente un archivo colocado en una carpeta conocida; el framework lo descubre, lo lista en el mercado de Plugins por app, valida su configuración contra un esquema tipado y — cuando el plugin lo declara — gobierna el ciclo de vida de su proceso worker.
La instalación es por app, y cada plugin se habilita, configura y desinstala de forma independiente.
Los nueve plugins integrados
| Plugin | Qué hace |
|---|---|
| Cockpit | Grilla CCTV con arrastrar-y-soltar de todos los streams en vivo de la app. |
| Quality | Test de ancho de banda + latencia como un semáforo verde/ámbar/rojo. |
| Radio | Radio WebRTC solo-audio: salí al aire, contá oyentes. |
| Video Streaming | Salí en vivo desde webcam + micrófono, reenviá la sala a RTMP. |
| Timestamp | Un sello de fecha/hora estilo CCTV sobre el reproductor. |
| Watermark | Una marca de agua de texto en una esquina del reproductor. |
| Scheduled Live | Una portada con cuenta regresiva que oculta el stream hasta el estreno. |
| YOLO | Un worker Python corre detección de objetos y postea cajas al overlay. |
| Deface | Un worker Python detecta rostros; el reproductor los difumina del lado cliente. |
Cómo funciona el descubrimiento
- Backend — dejás un
plugin.meta.tsque exporta por defectodefinePlugin({...}). Un servicio de registro recorre el sistema de archivos e importa cada manifiesto. Ese manifiesto es la fuente de verdad delid, lacategory(tool|processor|panel), el slot de UI (app-tab|panel|player-overlay) y suconfigSchema— donde cada campo tiene un default, así una instalación fresca es válida al instante. - Frontend — dejás un
index.tsxque exporta por defecto unPluginModule; el descubrimiento lo toma víaimport.meta.glob.
Workers, gobernados por vos
Un plugin que declara needsWorker: true provee un worker.spawn(ctx) puro que devuelve {command, args, env}. El framework entonces gobierna todo el ciclo de vida del proceso — habilitarlo lo arranca, deshabilitarlo lo detiene, y start/stop/status/logs se exponen por la API. YOLO y Deface arrancan un proceso Python así; el core nunca necesita saber qué es el worker en realidad.
Instalar un plugin
curl -X POST $BASE/apps/live/plugins/cockpit/install \
-H "Authorization: Bearer $TOKEN"
curl -X PATCH $BASE/apps/live/plugins/cockpit \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"enabled": true}'
Esa es toda la historia de extensibilidad: las funciones son archivos, el descubrimiento es automático y el mercado es por app.