7.5 KiB
Stream Control
Plan de contrôle web pour piloter des enregistrements OBS répartis sur plusieurs VM/VPS (Windows et Ubuntu) depuis une seule interface.
┌────────────┐ HTTPS + WS ┌──────────────────┐ WS sortant ┌──────────────────┐
│ Navigateur │ ───────────────►│ Serveur de │◄────────────────│ Agent (VM) │
│ dashboard │◄─── temps réel ─│ contrôle │──── commandes ─►│ └► OBS (4455) │
└────────────┘ │ Express + SQLite│ └──────────────────┘
└──────────────────┘ ┌──────────────────┐
◄────────────────│ Agent (VM) … │
└──────────────────┘
Le sens des connexions est le point clé : ce sont les agents qui se connectent au
serveur, pas l'inverse. Aucun port entrant à ouvrir sur les VM d'enregistrement, aucune
IP publique nécessaire, et obs-websocket reste sur 127.0.0.1.
Fonctionnalités
- Découverte automatique des agents par jeton d'enrôlement, ou provisionnement manuel.
- État temps réel par VM : OBS connecté, enregistrement en cours, durée, taille du fichier, scène active, FPS, frames perdues, CPU, espace disque restant.
- Commandes unitaires ou groupées : démarrer/arrêter/mettre en pause/découper un enregistrement, démarrer/arrêter un stream, changer de scène, de profil, de collection, changer le dossier d'enregistrement.
- Journal d'évènements horodaté, persistant et diffusé en direct.
- Reconnexion automatique de bout en bout (agent → serveur, agent → OBS, dashboard → serveur).
Prérequis
- Node.js 22+ sur le serveur et sur chaque VM (le serveur utilise
node:sqlite). - OBS 28+ sur chaque VM, avec Outils → Paramètres du serveur WebSocket activé. Note le port (4455 par défaut) et le mot de passe.
Démarrage rapide (développement)
npm install
cp .env.example .env # renseigne ADMIN_PASSWORD, SESSION_SECRET, ENROLLMENT_TOKEN
npm run dev # serveur :8080 + dashboard Vite :5173
Puis, dans un autre terminal, un agent local :
cd packages/agent
cp agent.config.example.json agent.config.json # colle le ENROLLMENT_TOKEN dans "token"
npm run dev
L'agent s'enrôle, reçoit son jeton permanent, le réécrit dans agent.config.json, et
apparaît dans le dashboard sur http://localhost:5173.
Déploiement
Serveur de contrôle
npm ci && npm run build
npm start # sert l'API, le WebSocket et le dashboard compilé sur $PORT
Mets-le derrière un reverse proxy TLS (exemple nginx) et
installe l'unité systemd deploy/stream-control-server.service.
ADMIN_PASSWORD et SESSION_SECRET sont obligatoires hors développement.
Agent Ubuntu
Copie packages/agent/dist, packages/agent/node_modules et agent.config.json dans
/opt/stream-control-agent, puis installe
deploy/stream-control-agent.service.
Agent Windows
Un service Windows classique tourne en session 0 et ne verrait pas OBS. Utilise la tâche planifiée « à l'ouverture de session » fournie :
.\deploy\windows-agent-task.ps1 -AgentDir 'C:\stream-control-agent' -RunAsUser 'VM01\obs'
Configuration
Serveur — .env (voir .env.example)
| Variable | Rôle |
|---|---|
PORT, HOST |
Écoute HTTP/WebSocket |
ADMIN_PASSWORD |
Mot de passe du dashboard |
SESSION_SECRET |
Clé HMAC des sessions (32+ octets aléatoires) |
ENROLLMENT_TOKEN |
Jeton d'auto-enregistrement ; vide = désactivé |
DB_PATH |
Fichier SQLite |
STATUS_INTERVAL_MS |
Fréquence de remontée d'état des agents |
AGENT_TIMEOUT_MS |
Délai avant de déclarer un agent hors-ligne |
Agent — agent.config.json (ou variables d'environnement)
| Clé | Variable | Rôle |
|---|---|---|
serverUrl |
SERVER_URL |
wss://control.exemple.com/ws/agent |
token |
AGENT_TOKEN |
Jeton d'enrôlement puis jeton propre à l'agent |
name |
AGENT_NAME |
Nom affiché (défaut : hostname) |
obs.host/port/password |
OBS_HOST / OBS_PORT / OBS_PASSWORD |
Repli local ; le serveur pousse la config de référence |
insecureTls |
INSECURE_TLS=1 |
Accepter un certificat auto-signé |
Les paramètres OBS édités dans le dashboard sont poussés à chaud vers l'agent : pas besoin de se connecter à la VM pour changer un mot de passe obs-websocket.
API HTTP
Toutes les routes hors /api/login exigent Authorization: Bearer <jeton de session>.
| Méthode | Route | Rôle |
|---|---|---|
POST |
/api/login |
Ouvre une session ({ password }) |
GET |
/api/agents |
Liste des agents et de leur état |
POST |
/api/agents |
Provisionne un agent, renvoie son jeton une seule fois |
PATCH |
/api/agents/:id |
Nom, notes, paramètres OBS, auto-connexion |
POST |
/api/agents/:id/token |
Régénère le jeton (coupe la session en cours) |
DELETE |
/api/agents/:id |
Supprime l'agent |
POST |
/api/agents/:id/command |
{ action, params }, attend le résultat de l'agent |
POST |
/api/commands/bulk |
Même action sur plusieurs agents, résultat par agent |
GET |
/api/logs?limit= |
Journal récent |
GET |
/healthz |
Sonde de vie (non authentifiée) |
Actions disponibles : obs.connect, obs.disconnect, obs.refresh, record.start,
record.stop, record.pause, record.resume, record.split, stream.start,
stream.stop, scene.set, profile.set, collection.set, recordDirectory.set,
agent.ping.
Structure
| Paquet | Rôle |
|---|---|
| packages/shared/ | Types du protocole, partagés par les trois autres |
| packages/server/ | API REST, passerelle agents, diffusion dashboard, SQLite |
| packages/agent/ | Binaire à déployer sur chaque VM, pilote OBS |
| packages/web/ | Dashboard React/Vite |
Points d'entrée utiles : packages/shared/src/index.ts (le protocole), packages/server/src/hub.ts (état central et dispatch), packages/agent/src/obs.ts (traduction action → obs-websocket).
Sécurité
- Les jetons d'agent ne sont stockés qu'en SHA-256 ; le clair n'est affiché qu'à la création.
- Le mot de passe obs-websocket n'est jamais renvoyé au navigateur (masqué en
********). - Les sessions dashboard sont des jetons HMAC à durée limitée, sans état serveur.
- Sers l'application en HTTPS/WSS : jetons d'agent et de session circulent dans les en-têtes et les URL de WebSocket.
- Après un
POST /api/agents/:id/token, l'agent est déconnecté jusqu'à ce que sonagent.config.jsonsoit mis à jour.
Pistes d'évolution
Enregistrements programmés (cron par agent), rapatriement automatique des fichiers
(rclone/S3 déclenché à record.stop), alertes sur seuil d'espace disque ou de frames
perdues, comptes utilisateurs multiples, groupes d'agents.