Hypernatural

TechniqueBy HypernaturalVersion 2, Oct 29, 2026

python-cut-to-bar-grid

Cut a music video's clips onto the song's bar grid: each shot gets exactly the frames between its start and end bars so cuts never drift, optional stepping on twos (12 fps look) per shot, a start offset to skip an idle opening, a short clip holding its last frame, all joined with the song underneath, and a --check that finds every cut with ffmpeg's scene score and reports any more than a frame off. Use for every rough and final cut on a song.

SKILL.md

Cut clips to the bar grid

Give it the song, its beats.json and one clip per shot with the bars it covers; get the cut with the song underneath, every shot exactly the frames between its bars. Cuts land on the music by construction and the total never drifts, however many shots. To trim a single clip to a frame count, use ffmpeg-frame-exact-trim.

Inputs

  • beats.json from python-map-song-bars (its downbeats).
  • The song WAV the beats came from, which sets the cut's length. Cut to the WAV, not the source file (a WAV was 0.19 s shorter than its M4A reported).
  • One clip per shot, untrimmed, longer than its slot where possible. Shots must meet: each shot's end bar is the next one's start bar.
  • Bars: -1 is the song's start (an intro before the first downbeat), a fraction is part of a bar (40.5 is beat 3 of bar 40), past the last downbeat is the song's end.

Run it

Write references/cut_to_bar_grid.md's script into the job's scripts/ as cut_to_bar_grid.py, unchanged. Put the shots in a file, one --shot START END CLIP per line, with any options:

--shot -1 1 video/shot01_a.mp4
--shot 1 2 video/shot02_b.mp4
--shot 2 2.5 video/shot03_a.mp4
--shot 2.5 3 video/shot04_a.mp4
--twos 3 4
--start 2=0.4
exec("python", ["scripts/cut_to_bar_grid.py", "--beats", "analysis/beats.json",
     "--song", "analysis/song.wav", "--out", "cut/pass_a/cut_v1.mp4", "@cut/shots.args",
     "--check"], cwd="<job>", skill="python-cut-to-bar-grid")
  • --twos N…: shots (1-based, in file order) stepped on twos, every frame held twice, for one look or world animated at 12 fps.
  • --start N=SECONDS: skip shot N's idle opening (read the strip in ffmpeg-frame-exact-trim to find it).
  • --fps (24) and --size (1920x1080; clips are scaled to fill and centre-cropped).
  • Paths in the args file can't contain spaces.

What you get

  • The cut: H.264 at --fps, the song from the first shot's start bar to the last shot's end bar, AAC 256k. Each shot is encoded at CRF 16 on its own and joined without re-encoding: a review and rough-cut file. Deliver from the master per guide-prepare-renders-for-delivery.
  • One line per shot whose clip is shorter than its slot: it holds the last frame.
  • With --check: cuts checked: 83 of 83, more than a frame off: none, or the shots that missed, with their frame and how far off.

Tips and traps

  • Render each shot at least as long as its slot and let the cut trim. H3 Max's minimum is 0.92 s, so render a half-bar shot at 24 frames, or its slot's frames when that is more (h3-max-image-to-video), and let the cut take what it needs. A clip shorter than its slot holds its last frame, which reads as a freeze.
  • Build the cut so changes are a re-run. Dropping a scene or trimming the intro means editing shots.args (fold the bars into a neighbour, or start the first shot later) and running again, never re-rendering.
  • A dropped shot leaves a gap and the script stops: shots must tile the bars.
  • Count frames, not seconds: each shot is round(end_time × fps) − round(start_time × fps), so the parts add up to the song exactly.
  • --check uses a 0.1 scene score. Two shots that look alike (the same set, a slow dissolve in the render) can score under it and show up as "off": look at that cut before believing it (ffmpeg-scene-cuts reads the scores).

Check it

  • --check on every cut. The worked job, a 3:22 song in 84 shots: 83 of 83 cuts within a frame of their bars.
  • The frame count printed equals the song's span at the frame rate.
  • Watch the cut with sound at a few downbeats: the picture changes on the "one".

Go make something cool.

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

Sticker HypernaturalSticker BannerSticker TVBoy