From 830b27470c6a5af0d86e711c98362783d1ee42a1 Mon Sep 17 00:00:00 2001 From: jeanotx32 Date: Thu, 13 Aug 2026 14:26:26 -0400 Subject: [PATCH] Feat : handle infinite throbber --- README.md | 44 ++++ packages/agent/src/firefox.ts | 48 ++++ packages/agent/src/index.ts | 215 ++++++++++++++++-- packages/shared/src/index.ts | 24 ++ packages/web/src/components/AgentSettings.tsx | 21 ++ 5 files changed, 338 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e41f588..0d173fb 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,9 @@ IP publique nécessaire, et obs-websocket reste sur `127.0.0.1`. - 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. +- Le plein écran est [mesuré, pas supposé](#mesurer-plutôt-que-demander), relu pendant la + capture et rétabli s'il se perd ; un + [lecteur figé](#lecteur-figé--rechargement-automatique) est détecté et la page rechargée. - [Clôture différée sur passage hors-ligne](#passage-hors-ligne) : une coupure brève ne découpe pas le fichier, une vraie fin de diffusion le termine. - [Enregistrement automatique](#enregistrement-automatique) d'un streamer sur une VM @@ -253,6 +256,47 @@ occupe le lecteur. Le constat part au journal **avec les mesures qui l'ont motiv après coup. Après trois rappels sans effet, la surveillance se suspend jusqu'au prochain enregistrement plutôt que d'insister toutes les 30 s. +##### Lecteur figé : rechargement automatique + +Le lecteur reste parfois bloqué sur son indicateur de chargement sans jamais repartir. Rien ne +le signale : la plateforme donne toujours le stream public, OBS continue d'enregistrer un +écran d'attente, et seul un rechargement de la page débloque la situation. L'agent le fait +maintenant lui-même, après **30 s sans la moindre avancée de la lecture** (réglable par agent +dans « Pilotage du navigateur », `0` désactive, plancher à 10 s). + +**Le blocage se mesure à la position de lecture, pas à l'apparition d'un indicateur.** +`video.currentTime` est une propriété standard de HTML : elle survivra à n'importe quelle +refonte de l'habillage du lecteur, là où guetter une classe CSS de *throbber* se casserait à +la première. Une mise en mémoire tampon de quelques secondes est normale sur un direct — c'est +l'absence prolongée d'avancée qui distingue la panne. + +**`paused` ne court-circuite rien, et c'est délibéré.** Vérifié en conditions réelles contre un +Firefox piloté : selon la façon dont le flux se rompt, le lecteur reste tantôt « en lecture » +avec son indicateur (`paused: false`, `readyState` retombé à 2), tantôt suspendu de lui-même +(`paused: true`). Les deux se soldent par une position qui n'avance plus et appellent le même +remède ; les distinguer aurait laissé passer la moitié des cas. + +La reprise rejoue **exactement la séquence d'ouverture** — rechargement, attente que le lecteur +démarre, plein écran, puis qualité — le code étant partagé avec le démarrage de capture plutôt +que dupliqué. Pendant ce temps les deux surveillances s'abstiennent : un rechargement fait +forcément perdre plein écran et lecture, et les laisser réagir déclencherait la reprise en +cours d'exécution. + +Trois garde-fous, parce que recharger pendant un enregistrement n'est pas anodin : + +- **uniquement pendant une capture active et non suspendue** — hors capture il n'y a rien à + sauver, et une pause de show privé arrête légitimement la lecture ; +- **uniquement si la veille donne le stream public**, quand elle est activée. Sans ce second + garde-fou, un opérateur ayant désactivé la mise en pause automatique verrait la page se + recharger en boucle à chaque fin de diffusion — le flux s'arrête alors légitimement sans + qu'OBS se mette en pause ; +- **trois rechargements enchaînés au maximum.** Si recharger n'y change rien, la cause est + ailleurs, et boucler ne ferait que hacher le fichier toutes les 30 s. Le compteur repart dès + que la lecture avance à nouveau, et à chaque nouvelle capture. + +Le constat part au journal avec les relevés qui l'ont motivé (« position 412,3 s, readyState 2 »), +pour distinguer après coup un flux qui manque de données d'un lecteur qui s'est suspendu. + **Un seul envoi à la fois, et pas plus d'un toutes les 10 s.** Deux mécanismes indépendants peuvent réclamer ce rappel : la séquence d'ouverture (une fois, à l'arrivée sur la page) et la surveillance de l'agent, qui le redemande de lui-même après un show privé. Sans diff --git a/packages/agent/src/firefox.ts b/packages/agent/src/firefox.ts index c665826..54b92c3 100644 --- a/packages/agent/src/firefox.ts +++ b/packages/agent/src/firefox.ts @@ -79,6 +79,27 @@ export function describeMetrics( return parts.join(', '); } +/** + * Instantané de la lecture, tel que le lecteur le rapporte. + * + * Lu sur l'élément `