B-roll Avatar Camera (the avatar SEEN doing something)
The realistic action counterpart of the broll skills, starring our own avatar:
broll-story → an illustrated 6-panel storyboard animated by seedance-2 (great
for invented side-characters / stylized vignettes).
broll-generator → presenter-free synthetic B-roll; broll-finder → real footage.
broll-avatar-camera → OUR avatar, photoreal, DOING something — a single realistic
action start frame (built like a camera angle) animated by prunaai/p-video-avatar,
the same model as our talking-heads, driven by the beat's narration audio.
Why p-video-avatar (the same model as the talking-heads, not plain p-video): it keeps
the avatar's face/wardrobe/room identical to the talking-head beats, and it's
audio-driven — feed it the beat's narration slice and the avatar lip-syncs to it (when
the mouth is visible) while the clip length matches the beat. The action itself is directed
by the video_prompt param ("takes a book from a shelf while talking") and negative_prompt
keeps unwanted stuff out. The clip is muted on disk; avatar-reel-composer re-lays the
single master narration over it (so no double audio — the lip-sync visuals stay in sync because
the same slice drove them).
When to use
The reel needs a beat where the avatar is seen DOING something in their own world while a
narration line plays — to complement the words with action, where the movement matters more
than the speech (the centered talking-head beats already carry the spoken delivery). Think:
taking a book off a shelf, walking through the garden, tending the plants, building
a sandcastle, lighting a candle, writing numbers, holding/handling an object — shot from
varied angles. It's the "show, don't tell" insert between talking-head beats, the photoreal
cousin of broll-story but starring the real avatar.
- Face/mouth visible in the action shot → the avatar lip-syncs the beat as a bonus (looks
like them saying that line while doing the thing). This is the sweet spot for this skill.
- Face-free (true first-person POV of the hands, back-to-camera) or a precise object move
with an exact start AND end pose → a talking-avatar model has no face to anchor; use
seedance-2 with start+end frames instead (see REFERENCE.md).
Prerequisites
- gpt-image-2 ready (shared Replicate token) — builds the action start frame.
- Replicate token (shared, auto-discovered) for
prunaai/p-video-avatar.
- The beat's narration audio slice (e.g.
antiguo/reels/NNN_slug/scenes/chunk_sN.mp3, or a
cut from narration.mp3) — this DRIVES the clip (lip-sync + length).
- ffmpeg on PATH — mutes the clip.
pip3 install -r scripts/requirements.txt (replicate, pillow).
- A scene profile for the avatar (the same
subject/wardrobe/scene/light JSON used by
avatar-camera-angles; e.g. antiguo/scene.json) and an avatar reference image
(antiguo/refs/antiguo_hero.png).
Pipeline
scene profile + avatar ref + an ACTION description
│
1 build_frame.py → gpt-image-2 → ONE action start frame (2:3 master + 9:16 crop, or 3:2 master + 16:9 crop with --crop169)
│
2 make_broll_camera.py → prunaai/p-video-avatar
│ inputs: image (start frame) + audio (beat slice) + video_prompt (action) + negative_prompt
│ → download → mute (-an) → <avatar>/broll/camera/<NNN>_<slug>.mp4 + manifest.json
│
3 hand off to avatar-reel-composer as a broll scene (broll_source: existing)
Hard rules (project)
- SHORT, positive ACTION in
--video-prompt. This is the model's "how the person behaves
while speaking" — put the action here, one short clause, positive: "takes a book from a shelf and looks at it while talking". Drop scene dressing/qualifiers and never write
"hold still / static / no camera movement" — negative/static instructions confuse it. Name what
the avatar DOES; lip-sync is automatic from the audio.
- Drive with the beat's narration audio. Pass
--audio = the exact narration slice for this
beat. It lip-syncs the avatar (if the mouth is visible) and sets the clip length to the
beat, so the clip matches its slot. (--voice-script exists only as a generic built-in-TTS
fallback for quick motion scouting — it is not the avatar's cloned voice.)
- Muted output. The clip is muted on disk;
avatar-reel-composer re-lays the master
narration. The same slice drove the lip-sync, so it stays in sync. (--keep-audio only for a
standalone QA preview.)
- Identity stays locked because it's the same model as the talking-heads. Build the start
frame from the avatar
--ref + scene profile so the room/wardrobe match.
- Prefer clear gross-motor actions. Reaching, taking a book, walking, sweeping, planting read
cleanly.
p-video-avatar holds handled objects far better than plain p-video (a book stays
coherent — cf. the old 006 page/book flip), but still keep the action simple.
- Face-free or precise object move → use seedance-2 start+end instead. A talking-avatar model
needs a face to anchor; for a true hands-only POV, a back-to-camera walk, or an exact
start→end object move, generate a start and an end frame and interpolate with seedance-2
(
--start-image / --end-image). See REFERENCE.md.
- No frozen frames / no Ken Burns. The clip length follows the audio, so pass the exact beat
slice and the clip matches its slot (the composer trims, never freezes). Project rule since Cap. 6.
- Feed a 9:16 frame for a 9:16 reel clip, or a 16:9 frame (
build_frame.py --crop169) for a 16:9 YouTube clip — p-video follows the input image's ratio.
Workflow
1 — Build the action start frame (the creative step)
Author the ACTION shot and render it with gpt-image-2 (locks wardrobe/room/light from the scene
profile, composes the action). For an action where the avatar lip-syncs, keep the face/mouth
in frame (--face visible); for an over-the-shoulder use --face partial:
python3 .cursor/skills/broll-avatar-camera/scripts/build_frame.py \
--ref antiguo/refs/antiguo_hero.png \
--scene-file antiguo/scene.json \
--face visible \
--action "three-quarter shot of the old mystic standing at his bookshelf, reaching up to \
pull a thick leather-bound tome from an upper shelf; upper body visible, indigo robe, candlelight" \
--crop916 -o antiguo/broll/camera/_frames/ --slug antiguo_shelf_reach
Review the printed reel_916 frame; re-roll (--count, or tweak --action) until it reads
right. Preview the prompt first with --print-prompt.
2 — Animate it, driven by the beat audio (the mechanical step)
Put the action in --video-prompt (short, positive) and the beat slice in --audio:
python3 .cursor/skills/broll-avatar-camera/scripts/make_broll_camera.py \
--avatar-dir antiguo \
--image antiguo/broll/camera/_frames/antiguo_shelf_reach_916.png \
--audio antiguo/reels/NNN_slug/scenes/chunk_s4.mp3 \
--action "takes a book from a shelf and looks at it while talking" \
--slug antiguo-shelf-book
Writes <avatar>/broll/camera/<NNN>_<slug>.mp4 (muted, length = the audio) + a manifest entry,
and prints a JSON summary. Useful flags: --audio PATH (the beat slice — lip-sync + length),
--negative-prompt "…" (override the action-broll preset) / --use-profile-negative (reuse the
avatar's talking_profile.json), --strength-negative-prompt, --resolution 1080p, --seed,
--disable-prompt-upsampling (verbatim action prompt), --keep-audio (QA preview),
--voice-script "…" (generic built-in TTS, scouting only).
3 — Hand off to avatar-reel-composer
Drop the clip into a storyboard broll scene; the composer lays the single master narration over
it (the same slice that drove the lip-sync → in sync):
{ "id": "s4", "type": "broll", "broll_source": "existing",
"broll_clip": "antiguo/broll/camera/001_antiguo-shelf-book.mp4",
"motion": "none",
"text": "the contiguous slice of the narration spoken over this beat" }
Notes / troubleshooting
- Action goes in
--video-prompt, short + positive. If the avatar only talks and doesn't
act, name the gesture explicitly ("takes a book… ", "writes numbers…"). If it warps, shorten
the prompt and drop scene dressing / any static-negative phrasing.
- The audio is the driver. Length follows the audio; pass the exact beat slice so the clip
matches its slot. Lip-sync shows only where the mouth is visible — that's expected and fine for
an action beat (the movement is the point).
- Held objects are much more coherent than with plain
p-video, but a heavy object move is
still safer as a seedance-2 start+end interpolation.
- Face-free beats (hands-only POV, back-to-camera): don't use this script (no face to anchor);
use seedance-2 start+end (REFERENCE.md) or shoot the action with the face partially in frame.
- Cost:
p-video-avatar is billed like the talking-heads (per second at 720p/1080p); the clip
is as long as the beat audio.
- Quick scout without burning the cloned voice:
--voice-script "…" uses the model's generic
built-in TTS just to preview the motion, then re-run with the real --audio beat.
Additional resources
- Action-shot prompt internals, p-video-avatar schema, seedance-2 start+end recipe, examples:
REFERENCE.md
- Frame builder reuses:
~/.cursor/skills/gpt-image-2 (image gen). Sibling: avatar-talking-video
(centered talking-heads, same model) and avatar-camera-angles (talking-head re-frames).
Consumer: avatar-reel-composer (broll_source: existing).
1---2name: broll-avatar-camera3description: Generate a short B-roll clip of OUR OWN avatar DOING something on camera — an ACTION shot that COMPLEMENTS the narration (movement matters more than words), not a centered talking head. Built on the SAME model as our talking-heads (prunaai/p-video-avatar) so the avatar's face/wardrobe/room stay consistent. Pipeline: build ONE action start frame with the gpt-image-2 skill (locking wardrobe/room/light from the scene profile), then animate it with p-video-avatar driven by the beat's narration audio, with the action in video_prompt and exclusions in negative_prompt; the clip is muted and the master narration is re-laid by avatar-reel-composer. For a face-free beat or a precise object move with exact start+end poses, use seedance-2 instead. Use when the user wants the avatar SEEN doing an activity in-scene (reaching, tending, building, holding an object) under a narration line, or mentions broll-avatar-camera, p-video-avatar action shots, video_prompt/negative_prompt, or an action insert of the real avatar.4---56# B-roll Avatar Camera (the avatar SEEN doing something)78The **realistic action** counterpart of the broll skills, starring **our own avatar**:910- `broll-story` → an **illustrated** 6-panel storyboard animated by seedance-2 (great11 for invented side-characters / stylized vignettes).12- `broll-generator` → presenter-free synthetic B-roll; `broll-finder` → real footage.13- **`broll-avatar-camera` → OUR avatar, photoreal, DOING something** — a single realistic14 action start frame (built like a camera angle) animated by **`prunaai/p-video-avatar`**,15 the **same model as our talking-heads**, driven by the beat's narration audio.1617**Why `p-video-avatar` (the same model as the talking-heads, not plain `p-video`):** it keeps18the avatar's face/wardrobe/room **identical** to the talking-head beats, and it's19**audio-driven** — feed it the beat's narration slice and the avatar **lip-syncs** to it (when20the mouth is visible) while the clip **length matches the beat**. The action itself is directed21by the **`video_prompt`** param ("takes a book from a shelf while talking") and **`negative_prompt`**22keeps unwanted stuff out. The clip is **muted on disk**; `avatar-reel-composer` re-lays the23single master narration over it (so no double audio — the lip-sync visuals stay in sync because24the same slice drove them).2526## When to use2728The reel needs a beat where the avatar is **seen DOING** something in their own world while a29narration line plays — to **complement the words with action**, where the **movement matters more30than the speech** (the centered talking-head beats already carry the spoken delivery). Think:31**taking a book off a shelf**, **walking** through the garden, **tending the plants**, **building32a sandcastle**, lighting a candle, writing numbers, holding/handling an object — shot from33**varied angles**. It's the "show, don't tell" insert between talking-head beats, the photoreal34cousin of `broll-story` but starring the real avatar.3536- **Face/mouth visible** in the action shot → the avatar **lip-syncs** the beat as a bonus (looks37 like them saying that line while doing the thing). This is the sweet spot for this skill.38- **Face-free** (true first-person POV of the hands, back-to-camera) **or a precise object move**39 with an exact start AND end pose → a talking-avatar model has no face to anchor; use40 **seedance-2 with start+end frames** instead (see REFERENCE.md).4142## Prerequisites4344- **gpt-image-2** ready (shared Replicate token) — builds the action start frame.45- **Replicate token** (shared, auto-discovered) for `prunaai/p-video-avatar`.46- **The beat's narration audio slice** (e.g. `antiguo/reels/NNN_slug/scenes/chunk_sN.mp3`, or a47 cut from `narration.mp3`) — this DRIVES the clip (lip-sync + length).48- **ffmpeg** on PATH — mutes the clip.49- `pip3 install -r scripts/requirements.txt` (replicate, pillow).50- A **scene profile** for the avatar (the same `subject`/`wardrobe`/`scene`/`light` JSON used by51 `avatar-camera-angles`; e.g. `antiguo/scene.json`) and an avatar reference image52 (`antiguo/refs/antiguo_hero.png`).5354## Pipeline5556```57scene profile + avatar ref + an ACTION description58 │591 build_frame.py → gpt-image-2 → ONE action start frame (2:3 master + 9:16 crop, or 3:2 master + 16:9 crop with --crop169)60 │612 make_broll_camera.py → prunaai/p-video-avatar62 │ inputs: image (start frame) + audio (beat slice) + video_prompt (action) + negative_prompt63 │ → download → mute (-an) → <avatar>/broll/camera/<NNN>_<slug>.mp4 + manifest.json64 │653 hand off to avatar-reel-composer as a broll scene (broll_source: existing)66```6768## Hard rules (project)6970- **SHORT, positive ACTION in `--video-prompt`.** This is the model's "how the person behaves71 while speaking" — put the **action** here, one short clause, positive: `"takes a book from a72 shelf and looks at it while talking"`. Drop scene dressing/qualifiers and **never** write73 "hold still / static / no camera movement" — negative/static instructions confuse it. Name what74 the avatar DOES; lip-sync is automatic from the audio.75- **Drive with the beat's narration audio.** Pass `--audio` = the exact narration slice for this76 beat. It lip-syncs the avatar (if the mouth is visible) and **sets the clip length** to the77 beat, so the clip matches its slot. (`--voice-script` exists only as a generic built-in-TTS78 fallback for quick motion scouting — it is **not** the avatar's cloned voice.)79- **Muted output.** The clip is muted on disk; `avatar-reel-composer` re-lays the master80 narration. The same slice drove the lip-sync, so it stays in sync. (`--keep-audio` only for a81 standalone QA preview.)82- **Identity stays locked** because it's the same model as the talking-heads. Build the start83 frame from the avatar `--ref` + scene profile so the room/wardrobe match.84- **Prefer clear gross-motor actions.** Reaching, taking a book, walking, sweeping, planting read85 cleanly. `p-video-avatar` holds handled objects far better than plain `p-video` (a book stays86 coherent — cf. the old `006` page/book flip), but still keep the action simple.87- **Face-free or precise object move → use seedance-2 start+end instead.** A talking-avatar model88 needs a face to anchor; for a true hands-only POV, a back-to-camera walk, or an exact89 start→end object move, generate a start and an end frame and interpolate with **seedance-2**90 (`--start-image` / `--end-image`). See REFERENCE.md.91- **No frozen frames / no Ken Burns.** The clip length follows the audio, so pass the exact beat92 slice and the clip matches its slot (the composer trims, never freezes). Project rule since Cap. 6.93- **Feed a 9:16 frame** for a 9:16 reel clip, or a **16:9 frame** (`build_frame.py --crop169`) for a 16:9 YouTube clip — p-video follows the input image's ratio.9495## Workflow9697### 1 — Build the action start frame (the creative step)98Author the ACTION shot and render it with gpt-image-2 (locks wardrobe/room/light from the scene99profile, composes the action). For an action where the avatar lip-syncs, keep the **face/mouth100in frame** (`--face visible`); for an over-the-shoulder use `--face partial`:101102```bash103python3 .cursor/skills/broll-avatar-camera/scripts/build_frame.py \104 --ref antiguo/refs/antiguo_hero.png \105 --scene-file antiguo/scene.json \106 --face visible \107 --action "three-quarter shot of the old mystic standing at his bookshelf, reaching up to \108pull a thick leather-bound tome from an upper shelf; upper body visible, indigo robe, candlelight" \109 --crop916 -o antiguo/broll/camera/_frames/ --slug antiguo_shelf_reach110```111Review the printed `reel_916` frame; re-roll (`--count`, or tweak `--action`) until it reads112right. Preview the prompt first with `--print-prompt`.113114### 2 — Animate it, driven by the beat audio (the mechanical step)115Put the **action** in `--video-prompt` (short, positive) and the **beat slice** in `--audio`:116```bash117python3 .cursor/skills/broll-avatar-camera/scripts/make_broll_camera.py \118 --avatar-dir antiguo \119 --image antiguo/broll/camera/_frames/antiguo_shelf_reach_916.png \120 --audio antiguo/reels/NNN_slug/scenes/chunk_s4.mp3 \121 --action "takes a book from a shelf and looks at it while talking" \122 --slug antiguo-shelf-book123```124Writes `<avatar>/broll/camera/<NNN>_<slug>.mp4` (muted, length = the audio) + a manifest entry,125and prints a JSON summary. Useful flags: `--audio PATH` (the beat slice — lip-sync + length),126`--negative-prompt "…"` (override the action-broll preset) / `--use-profile-negative` (reuse the127avatar's `talking_profile.json`), `--strength-negative-prompt`, `--resolution 1080p`, `--seed`,128`--disable-prompt-upsampling` (verbatim action prompt), `--keep-audio` (QA preview),129`--voice-script "…"` (generic built-in TTS, scouting only).130131### 3 — Hand off to avatar-reel-composer132Drop the clip into a storyboard `broll` scene; the composer lays the single master narration over133it (the same slice that drove the lip-sync → in sync):134```json135{ "id": "s4", "type": "broll", "broll_source": "existing",136 "broll_clip": "antiguo/broll/camera/001_antiguo-shelf-book.mp4",137 "motion": "none",138 "text": "the contiguous slice of the narration spoken over this beat" }139```140141## Notes / troubleshooting142- **Action goes in `--video-prompt`, short + positive.** If the avatar *only talks* and doesn't143 act, name the gesture explicitly ("takes a book… ", "writes numbers…"). If it warps, shorten144 the prompt and drop scene dressing / any static-negative phrasing.145- **The audio is the driver.** Length follows the audio; pass the exact beat slice so the clip146 matches its slot. Lip-sync shows only where the mouth is visible — that's expected and fine for147 an action beat (the movement is the point).148- **Held objects** are much more coherent than with plain `p-video`, but a heavy object move is149 still safer as a **seedance-2 start+end** interpolation.150- **Face-free beats** (hands-only POV, back-to-camera): don't use this script (no face to anchor);151 use **seedance-2 start+end** (REFERENCE.md) or shoot the action with the face partially in frame.152- **Cost:** `p-video-avatar` is billed like the talking-heads (per second at 720p/1080p); the clip153 is as long as the beat audio.154- **Quick scout** without burning the cloned voice: `--voice-script "…"` uses the model's generic155 built-in TTS just to preview the motion, then re-run with the real `--audio` beat.156157## Additional resources158- Action-shot prompt internals, p-video-avatar schema, seedance-2 start+end recipe, examples:159 [REFERENCE.md](REFERENCE.md)160- Frame builder reuses: `~/.cursor/skills/gpt-image-2` (image gen). Sibling: `avatar-talking-video`161 (centered talking-heads, same model) and `avatar-camera-angles` (talking-head re-frames).162 Consumer: `avatar-reel-composer` (`broll_source: existing`).