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>