Hypernatural

TechniqueBy HypernaturalVersion 2, Oct 29, 2026

gemini-shot-recreation-brief

Have Gemini watch one reference shot with its sound at 24 fps and break it down: camera, timed motion beats for every person, other motion, sound effects, dialogue, music and what a recreation must get right. Then turn that into a recreation brief for a video model, with your direction overriding it where it reads the shot wrong. Use when recreating a shot beat for beat, shot-for-shot, or with a new actor.

SKILL.md

Shot recreation brief

Give it one shot's clip, cut exactly from the source, and a sentence or two of context. Gemini watches it at 24 fps with sound and returns an analysis: the camera, the motion beats (a new beat every 0.2–0.5 s, with times), the expression arc, other motion, timed sound effects, dialogue, music, and recreation notes. You turn the analysis plus your direction into the brief a video model gets. The brief's timing line matches the model's minimum length, so the render acts in real time and trims to the shot. To get the dialogue and cast of a whole video, use gemini-script-from-video.

Inputs

  • The shot as its own clip at the source's frame rate (ffmpeg-scene-cuts for the boundaries). Its length and frame count from ffprobe-inspect-media.
  • Context: what the spot is, who's who (by what they wear), and what the shot is. Name the main character, so the beats use the name.

Run it

  1. Analyse. Send the clip, sampled at 24 fps and at high media resolution, with the prompt in references/prompt.md (duration, frame count and context filled in) to Gemini 3.1 Pro through run, asking for JSON in the schema there. Find its id with models("gemini") and describe it before the first run (earlier jobs used gemini-3.1-pro-preview):
    run("<gemini id>", {
      "contents": [{"role": "user", "parts": [
        {"fileData": {"mimeType": "video/mp4", "fileUri": "<shot>.mp4"},
         "videoMetadata": {"fps": 24}},
        {"text": "<the filled prompt>"}]}],
      "generationConfig": {"responseMimeType": "application/json",
                           "responseSchema": <the schema in references/prompt.md>,
                           "mediaResolution": "MEDIA_RESOLUTION_HIGH"}},
      into="<shot folder>", unit="<shot>_analysis")
    
    The clip is a local path; the engine uploads it. Save the answer as <shot>_analysis.json next to the clip. Shots are independent: start every shot's analysis with wait: false, then tasks(wait: true, calls: [...], until: "any"), and read each against its stills (step 2) as it lands. The gateway's Gemini adapter is being built in hn4a; describe gives its exact fields.
  2. Read it against the stills. Look at the shot's first and last frames next to the analysis, and note where it is wrong: sides, camera, sizes of movements.
  3. Write the brief with references/brief.md. The timing line depends on the model's floor and on whether the last frame is pinned. Your direction replaces the analysis's camera, action, other motion or notes where they are wrong. Write the end state yourself. Save it as direction/<shot>_<model>_<first_only|first_last>.txt.

What you get

<shot>_analysis.json and a readable version of it for the job's notes, then one brief per model and pinning. Each brief is a set of plain-text lines: the timing, camera, action, other motion, look, end state, dialogue or "Nobody speaks.", sounds, "no music", and must-get-right.

Tips and traps

  • Gemini sometimes mirrors frame-left and frame-right. Trust the stills. Your action direction overrides the beats where they disagree.
  • It calls slow push-ins "locked off". When the camera moves, write the camera direction yourself. The brief then drops "locked off", "static" and "hazy" from the analysis's lens notes so the two don't contradict each other.
  • Act in real time, then hold. Never speed up. A model whose floor is longer than the shot is told to play the action at natural speed and hold the final pose, and the render is trimmed to the shot. Spreading the action over the clip and speeding it up afterwards read badly. With a pinned last frame, the hold is on that frame.
  • Spell out counts and sizes. "Blinks exactly once"; a sip "a third of the way, base below her chin"; "keep every movement exactly as small as described". Vague beats come back bigger.
  • Sounds marked "added" (post-production effects) stay out of the brief, and so does music. Narration and score go back in at the edit.
  • Dialogue in the analysis is for timing only. Lip-synced lines go through a dialogue or lip-sync route, not through this brief.

Check it

Every beat in the brief should be visible in the reference clip at roughly its time, the end state should match the last still, and the timing line should name the model's real render length. After rendering, check the take landed where the brief said with python-check-pinned-frames.

Go make something cool.

Install the app, open your agent, describe the video. That's the whole onboarding.

Sticker HypernaturalSticker BannerSticker TVBoy