REVAMP : Firefox handling
All checks were successful
release / build (push) Successful in 25s
release / verify-windows (push) Successful in 1m15s

This commit is contained in:
jeanotx32
2026-08-12 01:46:14 +02:00
parent 3bd4d5f2ba
commit 77bfa0b8c5
14 changed files with 1223 additions and 108 deletions

View File

@@ -343,6 +343,43 @@ export function AgentSettings({ agent, targets, onClose, onCommand, notify }: Pr
</span>
</label>
<label className="field">
<span>Méthode de pilotage</span>
<select
value={browser.mode}
onChange={(event) =>
patchBrowser({ mode: event.target.value as BrowserSettings['mode'] })
}
>
<option value="bidi">WebDriver BiDi l'agent pilote Firefox (recommandé)</option>
<option value="launch">Lancement simple — une commande par page</option>
</select>
<span className="muted small">
{browser.mode === 'bidi' ? (
<>
L'agent ouvre Firefox une fois et garde un canal de commande : il navigue,
déclenche le plein écran et <strong>vérifie</strong> qu'il a pris. Seule
méthode qui fonctionne en session Wayland — elle ne passe pas par le serveur
d'affichage.
</>
) : (
<>
Une commande est lancée par page, et le plein écran passe par xdotool : il
faut alors une session Xorg, et l'effet de la touche reste invérifiable.
</>
)}
</span>
</label>
{browser.mode === 'bidi' && (
<p className="muted small">
Au premier passage en BiDi, l'agent ouvre une <em>nouvelle</em> fenêtre Firefox,
sur un profil qui lui est propre. Pointe la source « capture de fenêtre » d'OBS
dessus une fois : ensuite elle reste ouverte, y compris entre deux
enregistrements et lors d'un redémarrage de l'agent.
</p>
)}
<div className="row">
<label className="field grow">
<span>Commande du navigateur</span>
@@ -352,21 +389,55 @@ export function AgentSettings({ agent, targets, onClose, onCommand, notify }: Pr
placeholder="firefox"
/>
</label>
<label className="field grow">
<span>Arguments (séparés par des espaces)</span>
{browser.mode === 'launch' ? (
<label className="field grow">
<span>Arguments (séparés par des espaces)</span>
<input
value={browser.args.join(' ')}
onChange={(event) =>
patchBrowser({ args: event.target.value.split(/\s+/).filter(Boolean) })
}
placeholder="aucun"
/>
<span className="muted small">
Laisse vide : le lien part vers la fenêtre déjà ouverte.{' '}
<code>--new-window</code> en créerait une nouvelle à chaque capture, et OBS
perdrait sa cible.
</span>
</label>
) : (
<label className="field grow">
<span>Port de pilotage</span>
<input
value={String(browser.remotePort)}
onChange={(event) =>
patchBrowser({ remotePort: Number(event.target.value) || 9222 })
}
inputMode="numeric"
/>
<span className="muted small">
Écoute uniquement sur 127.0.0.1, à ne changer que si le port est déjà pris.
</span>
</label>
)}
</div>
{browser.mode === 'bidi' && (
<label className="field">
<span>Profil Firefox dédié</span>
<input
value={browser.args.join(' ')}
onChange={(event) =>
patchBrowser({ args: event.target.value.split(/\s+/).filter(Boolean) })
}
placeholder="aucun"
value={browser.profileDir}
onChange={(event) => patchBrowser({ profileDir: event.target.value })}
placeholder="~/.stream-control/firefox-profile (par défaut)"
/>
<span className="muted small">
Laisse vide : le lien part vers la fenêtre déjà ouverte. <code>--new-window</code>
{' '}en créerait une nouvelle à chaque capture, et OBS perdrait sa cible.
Un profil séparé est obligatoire : deux instances ne peuvent pas partager le
même, et pointer celui de l'opérateur redonnerait « Firefox est déjà ouvert ».
L'agent y écrit les réglages qui comptent pour un enregistrement — lecture
automatique autorisée, bandeau de plein écran supprimé, aucun onglet d'accueil.
</span>
</label>
</div>
)}
<div className="row">
<label className="field grow">
@@ -404,8 +475,18 @@ export function AgentSettings({ agent, targets, onClose, onCommand, notify }: Pr
</label>
<p className="muted small">
La touche et le titre de fenêtre utilisés pour le plein écran sont ceux
configurés ci-dessous, dans « Surveillance du stream ».
{browser.mode === 'bidi' ? (
<>
La touche du plein écran est celle configurée ci-dessous, dans « Surveillance du
stream ». Le titre de fenêtre, lui, ne sert plus : l'agent s'adresse à l'onglet,
pas à une fenêtre.
</>
) : (
<>
La touche et le titre de fenêtre utilisés pour le plein écran sont ceux
configurés ci-dessous, dans « Surveillance du stream ».
</>
)}
</p>
</fieldset>
@@ -574,14 +655,16 @@ export function AgentSettings({ agent, targets, onClose, onCommand, notify }: Pr
onChange={(event) => patchFullscreen({ key: event.target.value })}
/>
</label>
<label className="field grow">
<span>Titre de la fenêtre du lecteur</span>
<input
value={watch.fullscreen.windowMatch}
onChange={(event) => patchFullscreen({ windowMatch: event.target.value })}
placeholder="fragment du titre, ex. Stripchat"
/>
</label>
{browser.mode === 'launch' && (
<label className="field grow">
<span>Titre de la fenêtre du lecteur</span>
<input
value={watch.fullscreen.windowMatch}
onChange={(event) => patchFullscreen({ windowMatch: event.target.value })}
placeholder="fragment du titre, ex. Stripchat"
/>
</label>
)}
<label className="field small-field">
<span>Délai (s)</span>
<input