Cut to the beat
Read a music track as a beat grid, check each cut of a page against it, and move the cuts that are off.
At the end of this page you have a table that says which cutsA cut is the change from one world to the next. of a page land on a beat of your music, and the second to move each of the others to. An agent cannot hear a track. bin/vawe sound reads the track as numbers instead.
vawe does not make music and does not move cuts for you. It measures the track, compares the cuts of the page with it, and prints the fix. You edit the numbers in the page.
What you need
- A music file that you have the right to use (
mp3,m4a,wav, or an mp4 with audio). - A page with one
data-worldelement for each beat of the story. The element start times are the cut times. See Worlds. - The track in the page as a looped
<audio>tag. See Audio.
A track with no clear pulse has no grid. The verb says so and checks nothing. It does not invent a grid (core/beats/detect.js).
Steps
Read the track alone
bin/vawe sound assets/music.mp3The verb prints the tempo, the time of the first beat, the strongest hits and a beat grid. The grid lists each beat with its half and quarter beats, in seconds and in frames at 30 and 60 fps. Put a cut or a cue on the attack of a hit, where the sound starts.
For a click track at 120 BPM the verb printed:
Tempo 120 BPM, confidence 183.5 (strong); one beat is 0.50 s = 15.0 frames at 30 fps, 30.0 at 60 fps.
Beat phase: the first beat is at 0.50 s (frame 15 at 30 fps, 30 at 60 fps); bars of 4 beats, bar 1 starts at 0.50 s.Compare the cuts of the page
bin/vawe sound assets/music.mp3 --cuts films/my-film/page.htmlThe verb reads the worlds from the DOM and prints one row per cut. The test film colour-sting against the same click track gave:
| cut | at s | frame | nearest hit s | nearest line | offset ms | offset f | verdict |
| 1 | 0.03 | 1 | 0.50 (-466 ms) | beat 1.1 0.50 (-466 ms) | -466 | -14 | off |
| 2 | 0.73 | 22 | 0.50 (+234 ms) | half beat 0.75 (-16 ms) | -16 | -0.5 | on beat |
| 3 | 1.03 | 31 | 1.00 (+34 ms) | beat 1.2 1.00 (+34 ms) | +34 | +1 | near |
...A cut is on beat within 1 frame of a hit, a beat line or a half-beat line. It is near within 3 frames, and off beyond that. The verdict uses 30 fps. The table ends with advice that names the second to move each off cut to, for example “move it to 0.50 s (frame 15 at 30 fps)”.
Move the cuts
Each beat start is a literalA literal is a tunable number that you write in the page: a [[f, v]] table row, a keyframe stop or a :root custom property. in the page: a keyframe stop, a [[f, v]] table or a :root custom property. Change that number to the second in the advice. Name each beat once, for example --beat-3: 5.42s, and read it in every delay of that beat, so one edit moves the beat.
Draft and read the table again
bin/vawe dev films/my-film/page.htmlThe draft reads the same table. It prints a cut-off-beat line with the count of cuts within one frame of a hit or beat line, and names the verb for the fix. bin/vawe check page-check <page> also warns when a cut is early or late against the grid, and says how many frames.
The beat-synced template
For a film that is built around a song, start from the template:
bin/vawe new my-music-film --from prompts/music-video-beat-synced.mdThe template asks you to measure the song first and write films/<name>/beats.md: the BPM, the offset of the first downbeat, the energy per bar and the time of the drop. It sets the drop as the one spectacleThe spectacle is the second of the one big moment in a film, set by <meta name="spectacle" content="6.2">. of the film. It computes the beat index in window.seek(t) as floor((t - offset) * BPM / 60), so the page stays deterministic. It places each cue 30 ms early, by its measured peak. A lyric-video variant sets one line per bar.
Limits
- The grid is a measurement of one track. A track with a tempo change or a swing feel can give a grid that fits some bars and not others. Look at the hits table, not only the grid.
- A cut on the beat can still feel flat. Read Transitions for what carries the eye across it.
check page-checkand the draft line advise. They never stop a render.
Audio
Loudness and the mix
Transitions
From the blogCut video to beat: sync cuts to music with code