A pipeline skill, sanitized
OTS coverage as a camera move out of the master
This is one of the Claude Code skills my renderers run. It is the “Coverage” step of the eight on the main page: each over-the-shoulder shot is a camera move out of the approved wide, so the room and the eye-lines carry over, and a single face pass restores the likeness the video model drifts. Below is the skill file itself with project names, paths and keys removed. Download it as SKILL.md.
---
name: ots-coverage-from-the-master
description: Generate over-the-shoulder keyframes for a two-character conversation by dollying a virtual camera out of an approved wide two-shot with an image-to-video model, then extracting the final frame. Invoke when a scene needs OTS coverage that stays in the same room as the master.
---
OTS coverage as a camera move out of the master
A sanitized copy of one of the ~30 Claude Code skills behind the AI production pipeline at stolenduck.com. Project names, file paths, API keys and the cross-links to sibling skills are removed; the method, the prompts and the things that were tested and rejected are as the team runs them. Character names are A and B.
The idea
Generate each over-the-shoulder keyframe by dollying a virtual camera from an approved wide two-shot to the OTS position, then extracting the last frame. Because the background transforms through continuous motion instead of being re-imagined per shot, the room, the props and the eye-lines carry over from the master. The one thing the video model reliably breaks is the subject's face, so the skill ends with a single face-restoration pass.
The anchor set
For any two-character conversation scene, generate the anchors up front. There are two distinct wides, with different jobs:
duo_wide: the clean, camera-facing wide used as the start frame for any wide dialogue beat. Its prompt describes only what the camera sees behind the characters ("sunlit window"); it does not enumerate the side walls, so the room reads spacious.duo_wide_ref: the wide used as the source for the OTS dollies and the mid-shot zoom. Its prompt enumerates the side walls (shelving left, a window right, a door right) because the dolly will reveal them as it moves. It often comes out narrower, corridor-like; that is a feature here.ots_a: over A's shoulder, facing B (extracted from a dolly ofduo_wide_ref).ots_b: over B's shoulder, facing A (same).
The two wides can be one image when the geometry happens to work both ways. On most scenes the two roles conflict (camera-facing pushes the walls out of frame; wall context for the dollies pulls them back in), so generate both.
These anchors are then the start frames for every video clip in the scene. Each dialogue line maps to one of them, which locks the visual baseline: no per-shot keyframe generation, no drift between shots.
| Shot | Framing | Start frame |
|---|---|---|
| Line 1 (A speaks) | Duo wide | duo_wide |
| Line 2 (B speaks) | OTS on B | ots_a |
| Line 3 (A speaks) | OTS on A | ots_b |
| Line 4 (B speaks) | OTS on B | ots_a (reused) |
| Line 5 (A speaks) | Duo wide | duo_wide (reused) |
Why this method
| Method | Spatial consistency | Framing variety | Failure mode |
|---|---|---|---|
| Independent generation per shot | Poor: each shot feels like a different room | High | Background drift |
| Edit from the anchor with an image model | Medium: details drift (window shape, beam count) | High | Hallucinated background elements |
| Panorama pipeline (a sibling skill) | Good: different walls per angle | Medium | Spatial relationships still approximate |
| Crop the master | Perfect: zero drift | Low | None, but very constrained |
| Camera move out of the master (this skill) | Excellent: continuous motion preserves geometry | High | Characters move if the prompt is weak |
Prerequisites
- An approved wide two-shot: the master, or
duo_wide_reffrom the anchor set. - An image-to-video model that locks the first frame. The team runs the dollies on Seedance 2.0, or 2.5 when 2.0 does not land the move, and extracts keyframes at 1080p. The final dialogue clips are mostly Seedance 2.5 at 720p, with another model for the occasional shot it cannot render; the demo scene on the main page is a 1080p render, and production runs at 720p for throughput and cost.
- An image model that can edit from references for the face pass (the team uses Nano Banana).
opencv-pythonfor frame extraction.
Pipeline
Step 1: generate the wide two-shots
Generate with character references plus an environment reference, using a lean prompt: short, explicit screen-direction language, concrete heights with a comparison, no scaffolding paragraphs and no abstract jargon ("3/4 angle", "open stance"). The lean template reliably produces natural posture; stacked jargon causes an iteration spiral.
Both wides must have:
- Both characters clearly visible and positioned on the 180° line.
- 9:16 aspect ratio (vertical, mobile first).
- Characters at "a close conversational distance, about two feet apart". "A few feet apart" reads too far in 9:16.
- A on the left, B on the right, with explicit screen direction (
facing screen-right/facing screen-left). State the taller character's height difference ("towering over her by 8–9 inches"). - A visible gap. Add "They are NOT touching and NOT embracing, clear space between their bodies" if the model collapses them into an embrace.
duo_wide (video start frame) | duo_wide_ref (dolly source) | |
|---|---|---|
| Background description | Only what the camera sees behind them | Enumerate the side walls |
| Resulting geometry | Spacious; side walls often crop out | Narrower; walls visible on both sides |
| Used for | Wide dialogue beats | Dolly source for ots_a, ots_b; zoom source for duo_mid |
Append the house style block to every keyframe prompt:
Clean digital, no grain, no flares, no bokeh. Sharp across frame. Natural available light, no staged setup. Naturalistic color, no grade push, true skin tones.
Step 1b: the mid two-shot (duo_mid)
A 4-second pure zoom from duo_wide, no character step-in (a step-in brings them too close). Sample frames at 4 fps and pick the best framing from the zoom progression.
model: image-to-video
image: duo_wide
duration: 4
audio: off
"The man and woman remain completely still, feet planted, stationary and
silent. The camera smoothly zooms in with the lens, framing both characters
from the waist up in a medium two-shot. No character movement, no stepping,
no dolly, pure telephoto zoom only."
Extracting at 4 fps yields about 17 frames across the 4 seconds. The zoom runs from wide to very tight; pick an early-to-mid frame where both characters are still fully visible with good waist-up framing, typically around 1.5–2.0 s. The later frames over-zoom into torso crops.
Step 2: the two dolly videos
Fire two generations from the same wide, one per direction. The short "dollies [direction] and forward" prompt produces the best results: it gives a lateral and a depth direction and states the desired end state without over-prescribing the motion.
OTS facing B (dolly behind A):
model: image-to-video
image: duo_wide_ref
duration: 6
audio: off
"The man and woman remain completely still, feet planted, stationary and
silent as the camera slowly dollies [direction away from A, e.g. 'right']
and forward, moving behind the [A, e.g. 'woman on the left'] to frame an
over-the-shoulder shot focused on the [B, e.g. 'man']."
OTS facing A (dolly behind B):
model: image-to-video
image: duo_wide_ref
duration: 6
audio: off
"The man and woman remain completely still, feet planted, stationary and
silent as the camera slowly dollies [direction away from B, e.g. 'left']
and forward, moving behind the [B, e.g. 'man on the right'] to frame an
over-the-shoulder shot focused on the [A, e.g. 'woman']."
Both can run in parallel.
Prompt language tested and found inferior:
- "orbit": sometimes completes the rotation, inconsistent, over-prescriptive.
- "180 degree arc": overshoots past the OTS.
- "semicircle": decent framing, less consistent rotation.
- Longer prompts with "waist up", "medium shot", "completes the orbit": more prescriptive was not better.
"Feet planted" was added after characters walked during the dolly in open environments (lobbies, exteriors), where the model has visual room to move. Cozy interiors are less prone to it.
Step 3: QA the videos
Check each video for:
- Characters stationary throughout: no stepping, arm waving, head turning.
- A smooth dolly: no jumps, cuts or sudden accelerations.
- A clean medium OTS on the final frame: subject waist up, foreground character reduced to a shoulder-and-hair sliver.
- No phantom characters or cloning, especially on the dolly toward the woman.
- Consistent background: elements shift naturally with perspective, no hallucinated objects.
Step 4: extract the last five frames
The camera is still settling at the end of the dolly, so the best composition is not always the very last frame. Extract the last five to get a menu of near-final compositions.
import cv2, os
def extract_last_n(video_path, out_dir, n=5):
os.makedirs(out_dir, exist_ok=True)
cap = cv2.VideoCapture(video_path)
total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = cap.get(cv2.CAP_PROP_FPS)
for i, frame_num in enumerate(range(max(0, total - n), total)):
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_num)
ok, frame = cap.read()
if ok:
cv2.imwrite(os.path.join(out_dir, f"end_{i+1:02d}_{frame_num / fps:.2f}s.png"), frame)
cap.release()
Step 5: pick the OTS keyframe
- The foreground head or shoulder may occlude too much of the subject on the last frame; back up one or two frames for a cleaner framing.
- The last frame is the tightest OTS; earlier endings are slightly wider.
- The two directions may not land on the same frame number. Pick independently.
The selected frame becomes the _ots keyframe for that direction. Output: a 1080×1920 PNG.
Step 6: fix face drift in one reference pass (every OTS frame)
The video model reliably drifts the subject's face during the dolly. The extracted frame has the right framing, the right geometry and, critically, the right eye-line, but an off-model face. Restore the likeness in one image-edit call with two inputs, [ots_frame, character_closeup_reference], and instruct it to refine identity only:
Correct ONLY the in-focus [man/woman]'s facial identity to exactly match the [man/woman] in the second reference image: same brows, eyes, nose, mouth, jaw, complexion. Keep their EXACT current head angle and gaze direction (they are turned [screen-left/right], looking toward the [lower-left/right] at the foreground [partner]). Do not rotate the head, do not make them face the camera, do not change where they are looking. Keep hair, expression, wardrobe, pose, background and the soft foreground shoulder unchanged. Only refine the face, blending seamlessly.
Because the existing head and gaze are kept and only identity is refined, the physically correct eye-line from the dolly survives and the framing is untouched.
Verify with a neutral gaze check on the still: "Is the in-focus subject looking at the foreground person, or at the camera, or into the distance?" Body and head direction are not enough; check the eyes. For a small leftover (eyes reading half-closed), do one more single-reference touch-up on that detail only.
Approaches tested and rejected:
- Gray-patch mask and repaint: needs a hand-found face box, and the model's pixel bounding boxes are unreliable (verified: it returned background coordinates).
- Featureless dissolve, then repaint (two passes): works, but the frontal reference drags the head into a camera stare unless fought with orientation-lock language. More calls for no gain over the single pass.
- Remove the whole subject and re-insert from the full-body reference: too much freedom; the model re-poses and rescales the subject and destroys the framing and eye-line.
Critical prompt ingredients
| Element | Why it matters |
|---|---|
| "completely still, feet planted" | Without it, characters walk in open environments |
| "stationary and silent" | Prevents gesture, head turns and mouth movement during the dolly |
| "slowly" | Prevents jump cuts and sudden acceleration |
| "dollies [direction] and forward" | Lateral and depth direction together; beats "orbit", "arc", "semicircle" |
| "to frame an over-the-shoulder shot focused on" | States the end state without constraining the path |
The prompt is intentionally short. Longer prompts tested worse.
Duration
Six seconds is the sweet spot. Four to five seconds rushes the camera to the endpoint; ten gives the characters time to start moving and drift out of frame.
Tuning the framing distance
The default prompt lands in a good medium-OTS range. If the two directions do not match in intimacy, the last-five-frames menu usually has a matching pair: choose an earlier ending for the tighter direction rather than changing the prompt. If the prompt still needs adjusting: too wide, add "pushing in close" (never with "tight close-up", which overcorrects into an extreme close-up with artifacts); too tight, add "medium" before "over-the-shoulder shot".
Controlling the revealed background
As the camera dollies it reveals parts of the room that were not in the wide, and the model invents what it cannot see (doors, windows, empty walls) where the real set has something specific (a counter that continues along the wall). Two approaches, cheapest first:
- Describe the wall in the prompt (try first). Append a sentence about what is on the wall the camera is moving toward. This keeps the locked first frame, the key advantage of image-to-video.
- Reference-to-video mode, passing the environment photo as a reference. It does not lock the first frame, so the start composition can drift from the wide. Only if the first approach fails.
Close-ups from the OTS
| Method | Quality | Perspective | Notes |
|---|---|---|---|
| Zoom from the OTS (preferred) | Good, native resolution | Flat, telephoto, flattering for faces | "Camera stays in place, zooms in with the lens, telephoto zoom, no dolly" |
| Dolly in | Good, native resolution | Exaggerated wide-angle distortion on faces | Avoid for close-ups |
| Crop the OTS | Soft, upscaled from a small region | Same as source | Last resort |
Generating the dialogue clips from the anchors
Each line maps to one anchor as its start frame; every clip in the scene reuses the same anchors.
The prompt has three sections, each doing one job: the speaker, their emotion and the dialogue only (never describe the listener: it cues the model to reveal them, which causes camera drift and random cuts); the image-quality block; then camera and audio ("Handheld, micro-shake, no camera cuts. No background music."). Generate audio on, so the model speaks the quoted line. Do not pass a last frame for dialogue clips: locking the end frame produces artifacts as the model interpolates back to the same image. For short lines (under six words), append "...then pauses." so the model fills the back half with silence instead of padding the front and clipping the line.
Things that looked helpful and were not:
- Wardrobe descriptions in dialogue prompts (added once to fix clothing drift) cue the model to reveal both characters, which produces worse problems: camera drift, random cuts, ethnicity drift on partially occluded listeners. The minor wardrobe drift is the lesser evil.
- Mentioning the off-screen character ("toward the woman who is off-frame") makes the model invent dialogue for them; one test produced a hallucinated "What?" in a second voice. The keyframe already encodes the listener through the speaker's gaze.
- Directional eye-line language ("looking off-screen to his right, screen-left from the camera") tends to flip the gaze the wrong way. Left/right confusion is a real failure mode. Use "maintains his eye-line while he speaks" and let the keyframe carry the direction.
- Negating motion the keyframe shows. If the keyframe has a character mid-stride, stacked negation ("does NOT walk, does NOT take steps") will not override it. Regenerate the keyframe to a stationary one, or give a simple positive instruction ("remains in the doorway while calling out").
Known issues
- Background hallucination on reveal, above.
- Phantom cloning: another model exhibited it when dollying toward certain characters; Seedance at six seconds has not, but watch for it.
- Mouth movement: aggressive push-in prompts can trigger speech animation. "Silent" helps but is not bulletproof at tight framings.
- Resolution: keyframes are extracted at 1080p; the final dialogue clips render at 720p, which is the trade the team makes for Seedance 2.5’s dialogue quality.
When not to use this
- Single-character shots: no OTS needed; generate directly or crop.
- The wide itself still needs generating: this skill assumes the anchor exists.
- A specific target frame is required: use the model's last-frame parameter instead of an open-ended dolly.
- Non-conversation OTS (action, chases): the "stationary and silent" constraint does not apply.