Feat : STRCHA Stream status

This commit is contained in:
jeanotx32
2026-08-11 00:52:33 +02:00
parent 6f11b72cbb
commit b529417940
13 changed files with 1038 additions and 14 deletions

View File

@@ -27,12 +27,16 @@ IP publique nécessaire, et obs-websocket reste sur `127.0.0.1`.
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).
- [Pause automatique pendant les shows privés](#pause-automatique-pendant-les-shows-privés)
(Stripchat), avec reprise et rappel du plein écran au retour du flux public.
## 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.
- Pour le rappel du plein écran sous Ubuntu : `xdotool` et une session X11
(voir [Prérequis pour le rappel du plein écran](#prérequis-pour-le-rappel-du-plein-écran)).
## Démarrage rapide (développement)
@@ -108,6 +112,65 @@ planifiée « à l'ouverture de session » fournie :
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.
## Pause automatique pendant les shows privés
Quand un streamer bascule en show privé, le flux public est remplacé par un écran
d'attente : l'enregistrement continue mais ne capte plus rien d'utile, et le lecteur
sort du plein écran. L'agent peut surveiller le statut du streamer et réagir seul.
Configuration par agent, dans *Configuration → Surveillance du stream* :
| Réglage | Effet |
| --- | --- |
| Pseudo du streamer | Celui de l'URL de sa page |
| Intervalle de sonde | Fréquence d'interrogation de l'API (10 s par défaut, plancher 3 s) |
| Lectures avant pause | Lectures « privé » consécutives exigées avant d'agir (2 par défaut) |
| Statuts « privé » | Statuts déclenchant la pause — retire `groupShow` pour continuer à enregistrer les shows de groupe |
| Touche / fenêtre / délai | Raccourci plein écran à renvoyer au lecteur après le show |
### Ce que fait l'agent
1. Il interroge `GET /api/front/v2/models/username/{pseudo}/cam` et lit `user.user.status`.
Valeurs relevées en production : `public`, `private`, `p2p`, `groupShow`, `idle`.
2. Statut privé confirmé → `PauseRecord`, en mémorisant que **c'est lui** qui a mis en pause.
3. Retour au public → `ResumeRecord`, puis envoi de la touche plein écran après le délai
configuré, le temps que le lecteur ait rechargé le flux.
Trois garde-fous, parce qu'une automatisation qui coupe un enregistrement au mauvais
moment coûte plus cher que quelques secondes d'écran d'attente enregistrées :
- **La pause exige plusieurs lectures consécutives, la reprise agit immédiatement.** Une
fausse pause perd du contenu réel ; une fausse reprise ne coûte rien.
- **Une sonde en échec ne déclenche jamais rien.** API injoignable ou réponse inattendue :
l'agent conserve le dernier état connu et ne touche pas à l'enregistrement.
- **Une pause manuelle n'est jamais reprise automatiquement.** L'agent ne reprend que ce
qu'il a lui-même mis en pause.
Un passage `hors-ligne` (`idle`) ne provoque ni pause ni reprise : seul le retour effectif
du flux public relance l'enregistrement.
### Prérequis pour le rappel du plein écran
L'envoi de touche se fait au niveau du système, pas via OBS.
| OS | Mécanisme | À prévoir |
| --- | --- | --- |
| Ubuntu | `xdotool windowactivate` + XTEST | `apt install xdotool`, session **X11** (pas Wayland), `DISPLAY` accessible à l'agent |
| Windows | `SetForegroundWindow` + `SendKeys` | L'agent doit tourner dans la session interactive — d'où la tâche planifiée plutôt qu'un service |
| macOS | AppleScript System Events | Autorisation Accessibilité (prévu pour le développement) |
Dans les deux cas la fenêtre du lecteur passe **au premier plan** : les navigateurs
ignorent les évènements clavier synthétiques envoyés sans focus (`XSendEvent`). Sans
conséquence sur une VM d'enregistrement dédiée, gênant si quelqu'un s'en sert en même
temps.
Le bouton ⛶ sur la fiche de l'agent renvoie la touche à la demande, et ⟳ force une sonde
immédiate — les deux servent à valider le titre de fenêtre sans attendre un vrai show privé.
Si le rappel du plein écran s'avère fragile sur ta VM, l'alternative sans clavier est de
lancer le navigateur en mode kiosque (`chromium --kiosk`) : il n'y a alors plus de plein
écran à restaurer.
## API HTTP
Toutes les routes hors `/api/login` exigent `Authorization: Bearer <jeton de session>`.
@@ -128,7 +191,7 @@ Toutes les routes hors `/api/login` exigent `Authorization: Bearer <jeton de ses
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`.
`watch.check`, `hotkey.fullscreen`, `agent.ping`.
## Structure
@@ -142,7 +205,9 @@ Actions disponibles : `obs.connect`, `obs.disconnect`, `obs.refresh`, `record.st
Points d'entrée utiles : [packages/shared/src/index.ts](packages/shared/src/index.ts)
(le protocole), [packages/server/src/hub.ts](packages/server/src/hub.ts) (état central et
dispatch), [packages/agent/src/obs.ts](packages/agent/src/obs.ts) (traduction
action → obs-websocket).
action → obs-websocket), [packages/agent/src/watcher.ts](packages/agent/src/watcher.ts)
(sonde de statut et machine à états pause/reprise),
[packages/agent/src/hotkey.ts](packages/agent/src/hotkey.ts) (envoi de touche par OS).
## Sécurité