$npx -y skills add heygen-com/hyperframes --skill talking-head-recutPackage an existing talking-head / interview / podcast video with timed, designed GRAPHIC OVERLAY cards — kinetic titles, lower-thirds, data callouts, quotes, side panels, picture-in-picture — synced to the transcript, on a 16:9 / 9:16 / 4:5 canvas of your choice; the clip plays
| 1 | > **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update talking-head-recut`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them. |
| 2 | |
| 3 | # Talking Head Recut |
| 4 | |
| 5 | Talking Head Recut takes a local video that **plays in full** and layers a sequence of |
| 6 | timed, designed **graphic cards** onto it — titles, lower-thirds, data callouts, |
| 7 | quotes, side panels, picture-in-picture — synced to what's being said. The agent |
| 8 | designs the cards (timing + content) and **writes each card's HTML directly in the |
| 9 | conversation**, then assembles a single composition HTML and renders it to MP4 via |
| 10 | `hyperframes`. There is no fixed archetype list and no prescribed card structure — |
| 11 | the overlays emerge from what the transcript actually says. |
| 12 | |
| 13 | > **The front door is `/hyperframes`.** This skill packages an **existing talking-head clip** with **designed graphic cards** (titles, lower-thirds, data callouts, quotes, side panels, PiP) — not plain captions (the spoken words as text). **The clip plays untouched.** Any other intent — plain subtitles, a standalone graphic, a from-scratch video — or any uncertainty → read `/hyperframes` first: the intent layer owns every route decision. |
| 14 | |
| 15 | > **Graphic-packaging sibling of `embedded-captions`.** Captions add the _spoken words_ |
| 16 | > as a readable subtitle; this adds _designed graphics_ on top of the playing video. |
| 17 | > Plain subtitles → `embedded-captions`. Build a video from scratch → the creation |
| 18 | > workflows (`product-launch-video` / `faceless-explainer` / …). |
| 19 | |
| 20 | Routed through `/hyperframes`, the intent layer confirms only the input (which clip) and **announces** the render-strategy questions as deferred asks — aspect, layout, style group, and card count stay at Step 7, where the probed footage and transcript ground the recommendations; the layer's run-shape questions don't apply. A `BRIEF.md`, when present, carries the confirmed input and any user notes — read it first. |
| 21 | |
| 22 | Inspectable intermediate files in the work directory: |
| 23 | |
| 24 | - `metadata.json` — duration / width / height / fps |
| 25 | - `audio.mp3` — extracted audio |
| 26 | - `transcript.json` — a flat **word array** `[{ text, start, end }, …]` (Whisper; no `segments`, no `words` wrapper) |
| 27 | - `storyboard.json` — lightweight card outline (the agent's plan) |
| 28 | - `public/cards/card-XX.html` — one HTML fragment per card |
| 29 | - `public/index.html` — final assembled composition |
| 30 | - `output.mp4` — rendered video |
| 31 | |
| 32 | ## CLI Resolution |
| 33 | |
| 34 | ```bash |
| 35 | # hyperframes — transcription (local Whisper) + rendering the assembled HTML to MP4 |
| 36 | npx hyperframes --help |
| 37 | ``` |
| 38 | |
| 39 | This skill runs entirely on the **hyperframes** CLI plus system `ffmpeg` / `ffprobe`. |
| 40 | Transcription is local **Whisper** via `hyperframes transcribe` — no third-party |
| 41 | service, API key, or rate-limited proxy. |
| 42 | |
| 43 | ## Workflow |
| 44 | |
| 45 | ### 1. Check Environment |
| 46 | |
| 47 | ```bash |
| 48 | npx hyperframes doctor # ffmpeg, headless browser, render deps |
| 49 | # confirm bundled assets: |
| 50 | ls "<SKILL_DIR>/assets/fonts" "<SKILL_DIR>/assets/vendor/gsap.min.js" |
| 51 | ``` |
| 52 | |
| 53 | Required: |
| 54 | |
| 55 | - `ffmpeg` / `ffprobe` (system) |
| 56 | - `<SKILL_DIR>/assets/fonts/*.woff2`, `<SKILL_DIR>/assets/vendor/gsap.min.js` (bundled inside this skill, staged to work dir in Step 9) |
| 57 | |
| 58 | Transcription needs no key — `hyperframes transcribe` runs Whisper locally (Step 4). |
| 59 | |
| 60 | Strongly recommended on macOS for `hyperframes render`: |
| 61 | |
| 62 | ```bash |
| 63 | export PRODUCER_BROWSER_GPU_MODE=hardware |
| 64 | ``` |
| 65 | |
| 66 | ### 2. Create a Work Directory |
| 67 | |
| 68 | All artifacts live under `videos/<project-name>/` — the same convention as the other |
| 69 | video workflows (`product-launch-video` / `faceless-explainer` / `pr-to-video`). Keep |
| 70 | the cwd at the workspace root; everything below writes under this one subdirectory. |
| 71 | |
| 72 | ```bash |
| 73 | VIDEO_PATH="/absolute/path/input.mp4" |
| 74 | WORK_DIR="videos/$(basename "$VIDEO_PATH" | sed 's/\.[^.]*$//')" |
| 75 | mkdir -p "$WORK_DIR" |
| 76 | ``` |
| 77 | |
| 78 | ### 3. Extract Audio and Metadata |
| 79 | |
| 80 | ```bash |
| 81 | # metadata — duration / width / height / fps |
| 82 | ffprobe -v error -select_streams v:0 \ |
| 83 | -show_entries stream=width,height,r_frame_rate \ |
| 84 | -show_entries format=duration -of json "$VIDEO_PATH" > "$WORK_DIR/metadata.json" |
| 85 | # audio |
| 86 | ffmpeg -y -i "$VIDEO_PATH" -vn -acodec libmp3lame -q:a 2 "$WORK_DIR/audio.mp3" |
| 87 | ``` |
| 88 | |
| 89 | Outputs: `metadata.json` (read `width`/`height`/`duration`; fps = the `r_frame_rate` |
| 90 | fraction evaluated, e.g. `30000/1001 → 29.97`) + `audio.mp3`. |
| 91 | |
| 92 | ### 4. Transcribe |
| 93 | |
| 94 | ```bash |
| 95 | npx hyperframes transcribe "$WORK_DIR/audio.mp3" -d "$WORK_DIR" --json --model small.en |
| 96 | ``` |
| 97 | |
| 98 | Local **Whisper** — no |