diff --git a/optional-skills/creative/hyperframes/SKILL.md b/optional-skills/creative/hyperframes/SKILL.md index 16a5c8d1bac5a..b05c6cde91bbd 100644 --- a/optional-skills/creative/hyperframes/SKILL.md +++ b/optional-skills/creative/hyperframes/SKILL.md @@ -43,11 +43,13 @@ Do **not** use this skill for: npx hyperframes init my-video # scaffold a project cd my-video npx hyperframes lint # validate before preview/render -npx hyperframes preview # live-reload browser preview (port 3002) +npx hyperframes preview # live-reload preview (long-lived server, port 3002) npx hyperframes render --output final.mp4 # render to MP4 npx hyperframes doctor # diagnose environment issues ``` +`preview` is a **long-lived** Next.js server that holds Chrome render workers open. Always stop it when done (see [Cleanup](#cleanup)) — a forgotten preview keeps idle `chrome-headless-shell` workers alive that, on GPU-less hosts (WSL, containers, CI), spin a CPU core each indefinitely via software WebGL (swiftshader). + Render flags: `--quality draft|standard|high` · `--fps 24|30|60` · `--format mp4|webm` · `--docker` (reproducible) · `--strict`. Full CLI reference: [references/cli.md](references/cli.md). @@ -150,8 +152,23 @@ npx hyperframes render --quality high --output final.mp4 # final delivery Use the 7-step capture-to-video workflow in [references/website-to-video.md](references/website-to-video.md): capture → DESIGN.md → SCRIPT.md → storyboard → composition → render → deliver. +## Cleanup + +`render` is one-shot (workers exit when it finishes). `preview` is **not** — it runs a background Next.js server that keeps Chrome workers resident until you stop it. Never leave one running: on GPU-less hosts each idle worker's swiftshader process pegs a CPU core, and a preview left open for days stacks up multiple. + +Stop a preview when the user is done reviewing (or before starting a new one): + +```bash +pkill -f "hyperframes.*preview" # the Studio server (frees port 3002) +pkill -f chrome-headless-shell # its render workers; only safe if nothing else uses them +``` + +If unsure whether other tools use `chrome-headless-shell`, check first: `pgrep -af chrome-headless-shell`. Recover a wedged host (many idle workers spinning CPU) the same way — see [references/troubleshooting.md](references/troubleshooting.md#runaway-cpu-from-leftover-preview-workers). + ## Pitfalls +- **Leaving `preview` running** — it's a long-lived server holding Chrome workers; on WSL/containers/CI those idle workers spin a CPU core each (software WebGL). Stop it when done — see [Cleanup](#cleanup). + - **`HeadlessExperimental.beginFrame' wasn't found`** — Chromium 147+ removed this protocol. Ensure you're on `hyperframes@>=0.4.2` (auto-detects and falls back to screenshot mode). Escape hatch: `export PRODUCER_FORCE_SCREENSHOT=true`. See [hyperframes#294](https://github.com/heygen-com/hyperframes/issues/294) and [references/troubleshooting.md](references/troubleshooting.md). - **System Chrome (not `chrome-headless-shell`)** — renders hang for 120s then timeout. Run `npx puppeteer browsers install chrome-headless-shell` (setup.sh does this). `hyperframes doctor` reports which binary will be used. - **`repeat: -1` anywhere** — breaks the capture engine. Always compute a finite repeat count. diff --git a/optional-skills/creative/hyperframes/references/troubleshooting.md b/optional-skills/creative/hyperframes/references/troubleshooting.md index 8f561310d8cbd..9a50d1dd0ed09 100644 --- a/optional-skills/creative/hyperframes/references/troubleshooting.md +++ b/optional-skills/creative/hyperframes/references/troubleshooting.md @@ -132,6 +132,29 @@ npx hyperframes render --docker --docker-args "--cap-add=SYS_ADMIN" The headless browser needs namespace permissions for sandboxing. +## Runaway CPU from leftover preview workers + +**Symptom:** load average climbs and stays high; `top` shows several `chrome-headless-shell --type=gpu-process` at ~300%+ CPU each, alive for hours/days, even when you're not rendering. + +**Cause:** `npx hyperframes preview` is a long-lived server that keeps Chrome render workers resident. On hosts with no real GPU (WSL, containers, most CI), each idle worker falls back to software WebGL (`swiftshader`) whose GPU process busy-spins a CPU core. A preview left open — or several started over time — stacks these up. + +**Diagnose:** + +```bash +pgrep -af chrome-headless-shell # list the workers + their parent flags +pgrep -af "hyperframes.*preview" # the preview server(s) holding them open +uptime # confirm elevated load average +``` + +**Fix:** stop the preview server and its workers (see [SKILL.md#cleanup](../SKILL.md)): + +```bash +pkill -f "hyperframes.*preview" +pkill -f chrome-headless-shell # only if no other tool uses it — check pgrep first +``` + +**Avoid:** never leave a `preview` running after review; use `render` (one-shot, self-cleaning) for output. Keep `--workers` low on shared/GPU-less hosts. + ## Bug reports Include `npx hyperframes info` output + the full error log. File at [github.com/heygen-com/hyperframes](https://github.com/heygen-com/hyperframes/issues).