feat(stream): STREAM_BROWSER flag + make toolbar-hide/subtitles broadcast-wide

- Add STREAM_BROWSER (.env) gating screen-share/browser mode. false => the
  /자비스 stream command stays voice + API/MCP only (no Go-Live); true (default)
  => screen share as before. (Browser-driven info retrieval in true mode is a
  follow-up build; the bot has no browser-control tools yet.)
- Make the two test-time fixes broadcast-wide defaults via broadcast-helper.mjs:
  it now also watches every tab for HTML5 fullscreen and toggles Chrome window
  fullscreen so the address bar is hidden for ANY video (xfwm4 won't hide it on
  'f' alone), restoring on exit. Subtitles were already enforced per video.
  scenario.mjs drops its own fullscreen toggle and relies on the helper.
- Revert the test-settings env vars from .env.example (not wanted).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-10 16:17:29 +09:00
parent f93b241575
commit ef6f6ff57d
5 changed files with 51 additions and 34 deletions

View File

@@ -91,8 +91,37 @@ async function session() {
const ctx = b.contexts()[0];
for (const p of ctx.pages()) await arm(p);
ctx.on('page', arm); // new tabs
// Broadcast-wide: when any tab enters HTML5 fullscreen (a video 'f'), hide
// Chrome's toolbar by putting the WINDOW into Chrome-initiated fullscreen -
// xfwm4 won't hide it on HTML5 fullscreen alone, so the address bar would
// otherwise show on the broadcast. Restore when fullscreen exits.
let winFs = false;
const cdp = await b.newBrowserCDPSession();
const setWindowFs = async (fs) => {
try {
const { targetInfos } = await cdp.send('Target.getTargets');
const t = targetInfos.find((x) => x.type === 'page' && x.url.startsWith('http'));
if (!t) return;
const { windowId } = await cdp.send('Browser.getWindowForTarget', { targetId: t.targetId });
await cdp.send('Browser.setWindowBounds', { windowId, bounds: { windowState: fs ? 'fullscreen' : 'normal' } });
winFs = fs;
} catch { /* best-effort */ }
};
const fsTimer = setInterval(async () => {
try {
let anyFs = false;
for (const p of ctx.pages()) {
if (await p.evaluate(() => !!document.fullscreenElement).catch(() => false)) { anyFs = true; break; }
}
if (anyFs && !winFs) await setWindowFs(true);
else if (!anyFs && winFs) await setWindowFs(false);
} catch { /* best-effort */ }
}, 600);
console.log('broadcast-helper armed on', ctx.pages().length, 'tab(s)');
await new Promise((resolve) => b.on('disconnected', resolve));
clearInterval(fsTimer);
}
// Reconnect across Chrome restarts so the broadcast stays ad-free.