Files
javis_bot/bot/scripts/stream-test
javis-bot 0241628fed fix(stream-test): restore audio after ads, enforce subtitle rule broadcast-wide, commit the 60fps MV path
Addresses review of the ad/subtitle work:

- ad mute leak: the ad-skipper muted during an ad but never un-muted, so the
  main video stayed silent after the first ad. Save the pre-ad muted/playbackRate
  and restore them when the ad ends (verified: muted false -> true -> false).
- captions were only applied once when scenario.mjs ran, not for the whole
  broadcast. Move the rule (OFF by default, Korean ON if offered) into the
  persistent helper so it runs per video, and ENFORCE it every tick - one-shot
  did not hold because YouTube silently re-enabled captions (verified it now
  stays off across 8s).
- merge ad-skip.mjs + captions into broadcast-helper.mjs (one CDP process).
- the actual 60fps MV test now lives in the repo: scenario.mjs gains MV_QUERY
  (search + auto-pick the first >=60fps result) and WATCH_SECONDS, with the
  fullscreen-toolbar-hide fix. The broadcast runs via the committed
  stream-hold.ts (audio + keepalive), not an out-of-repo copy.
- document the test env vars (CDP_PORT, HOLD_MS, TEST_*, MV_QUERY, WATCH_SECONDS)
  in .env.example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 16:09:06 +09:00
..

stream-test

Operational scripts for manually verifying the selfbot Go-Live broadcast with a real browsing session captured from the X display.

Files

  • stream-hold.ts - joins the voice channel and keeps the Go-Live stream up until stopped. All params from .env (DISCORD_SELFBOT_TOKEN, DISCORD_GUILD_ID, DISCORD_VOICE_CHANNEL_ID, VNC_RESOLUTION, VNC_FRAMERATE, VNC_BITRATE_KBPS, STREAM_HW, VNC_DISPLAY).
  • human.mjs - human-like interaction helpers. Input is injected into the X server with xdotool (synthetic X input, not a physical HID device, but the browser and the captured screen see genuine pointer/keyboard events with a visibly moving cursor); Playwright only locates elements. Every action is such input: address-bar navigation (Ctrl+L + typing), search typing, clicking the video / settings menu / autoplay toggle / play button, fullscreen via the f key, and scrolling. Elements are brought into view with a real wheel scroll (no DOM scrollIntoView); if an element has no on-screen box the click fails rather than falling back to a synthetic click. The CDP/DOM API is used only to read state for verification, never to act.
  • scenario.mjs - the browse scenario (YouTube -> IU live -> 1080p -> fullscreen -> Naver -> 나무위키), driven with the human helpers. Connects to a Chrome already running with --remote-debugging-port (CDP_PORT, default 9222) on the streamed display. Captions default OFF, auto-enabling a Korean track when one exists.
  • ad-skip.mjs - persistent YouTube ad auto-skipper. Connects over CDP and injects a watcher into every tab (current and future) that clicks "Skip ad" the instant it appears, closes overlay ads, and fast-forwards unskippable ads (seek-to-end + 16x + mute). Run it alongside the broadcast. Reconnects across Chrome restarts.

Run

# keep the broadcast up (separate process / service)
bun bot/scripts/stream-test/stream-hold.ts

# Chrome on the streamed display with remote debugging, then:
node bot/scripts/stream-test/scenario.mjs

# keep YouTube ads auto-skipped for the whole broadcast (separate process):
node bot/scripts/stream-test/ad-skip.mjs

Recommended Chrome flags on the streamed display (avoids the "restore pages?" bubble after an unclean exit and keeps a single clean window):

google-chrome --remote-debugging-port=9222 --start-maximized \
  --hide-crash-restore-bubble --disable-session-crashed-bubble \
  --autoplay-policy=no-user-gesture-required <url>

Smooth capture (VNC keepalive)

TigerVNC only refreshes its framebuffer while a VNC client is attached. The Discord broadcast reads the framebuffer with x11grab (not as a VNC client), so with no viewer attached the captured screen idles at ~1.5 fps and the stream looks badly choppy while the cursor still moves smoothly (x11grab overlays the live cursor each frame). SelfbotStreamer fixes this automatically: it keeps a tiny headless RFB client (vnc-keepalive.ts) connected for the life of the stream, requesting incremental updates at the stream framerate. Measured: 3/30 distinct frames without it, ~57/60 with it. The keepalive authenticates with VNC_PASSWORD (or the ~/.config/tigervnc/passwd file) and is fail-open.

A/B framerate/resolution

Lower settings to compare what Discord actually delivers to viewers, e.g.:

VNC_RESOLUTION=1280x720 VNC_FRAMERATE=30 bun bot/scripts/stream-test/stream-hold.ts

Notes

  • Selfbot streaming violates Discord ToS; use a burner account.
  • Requires xdotool, an X display, and a system ffmpeg with x11grab/nvenc.
  • Prereqs (playwright, system Chrome) are not bot dependencies; install separately where you run the scenario.