← Back to the pipeline

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:

  1. 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.
  2. 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.
  3. ots_a: over A's shoulder, facing B (extracted from a dolly of duo_wide_ref).
  4. 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.

ShotFramingStart frame
Line 1 (A speaks)Duo wideduo_wide
Line 2 (B speaks)OTS on Bots_a
Line 3 (A speaks)OTS on Aots_b
Line 4 (B speaks)OTS on Bots_a (reused)
Line 5 (A speaks)Duo wideduo_wide (reused)

Why this method

MethodSpatial consistencyFraming varietyFailure mode
Independent generation per shotPoor: each shot feels like a different roomHighBackground drift
Edit from the anchor with an image modelMedium: details drift (window shape, beam count)HighHallucinated background elements
Panorama pipeline (a sibling skill)Good: different walls per angleMediumSpatial relationships still approximate
Crop the masterPerfect: zero driftLowNone, but very constrained
Camera move out of the master (this skill)Excellent: continuous motion preserves geometryHighCharacters move if the prompt is weak

Prerequisites

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:

duo_wide (video start frame)duo_wide_ref (dolly source)
Background descriptionOnly what the camera sees behind themEnumerate the side walls
Resulting geometrySpacious; side walls often crop outNarrower; walls visible on both sides
Used forWide dialogue beatsDolly 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:

"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:

  1. Characters stationary throughout: no stepping, arm waving, head turning.
  2. A smooth dolly: no jumps, cuts or sudden accelerations.
  3. A clean medium OTS on the final frame: subject waist up, foreground character reduced to a shoulder-and-hair sliver.
  4. No phantom characters or cloning, especially on the dolly toward the woman.
  5. 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 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:

Critical prompt ingredients

ElementWhy 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:

Close-ups from the OTS

MethodQualityPerspectiveNotes
Zoom from the OTS (preferred)Good, native resolutionFlat, telephoto, flattering for faces"Camera stays in place, zooms in with the lens, telephoto zoom, no dolly"
Dolly inGood, native resolutionExaggerated wide-angle distortion on facesAvoid for close-ups
Crop the OTSSoft, upscaled from a small regionSame as sourceLast 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:

Known issues

When not to use this

Download SKILL.md Read the blocking pipeline Contact me