Beat-Aligned Scene Durations
Turn a beat map into SRT scene timings that actually cut on the beat
- srt_text
- srt_path
A music video that ignores the beat feels wrong even if you can't say why. This node is VRGameDevGirl's answer: you hand it a beat map - JSON with a list of beat times - and it hands you back an SRT file of scene durations whose cuts land on or near those beats. It's the thing that keeps the visual edits synced to the track in her music-video workflow, and it's a surprisingly thoughtful little piece of logic.
The node is Node B in her pipeline. It assumes something upstream detected the beats (the pack's workflow does audio analysis and hands over beat_data as JSON with a beats array of time objects and a total duration). Your job is just the three dials and the seed.
How it works
Given the beat list and song length, the generator walks the track and picks scene boundaries as close to beats as it can while keeping each scene inside min_duration (default 2s) and max_duration (default 10s). bias (default 0.7) steers whether a cut lands early or late relative to the beat - higher bias means it'll hold closer to the impact. The duration_preset chooses the feel:
impact_weighted- durations vary, weighted toward impact beats.varied_no_repeat- varied lengths, no two adjacent scenes the same.clustered_no_repeat- clustered variety without repeats.
seed makes the whole thing reproducible, which matters a lot when you're tweaking one dial and want to compare like for like. There's also an intro guard built in: if the first beat isn't at time zero, it adds intro scene(s) capped at max_duration, and if the opening cut comes out under 1.5s it quietly merges it into scene 2 - a fix for the "first scene is two frames long" failure you'd otherwise chase manually.
The output is a valid SRT, and the node writes it to disk (output_filename becomes beats_output.srt) and returns the text. Each scene gets a SCENE n cue line - that cue line is load-bearing, because the pack's SRTLyricsMerger parses exactly that format to attach durations to lyrics.
Inputs and outputs
You set: beat_data (the JSON), min_duration, max_duration, bias, duration_preset, seed, output_filename. You get: srt_text and srt_path. Wire srt_text into SRTLyricsMerger or a subtitle-burn node; keep srt_path if you want the file for an external editor.
Install and gotchas
Same pack as everything else: ComfyUI Manager → search "vrgamedev", or git clone https://github.com/vrgamegirl19/comfyui-vrgamedevgirl into ComfyUI/custom_nodes, then restart. kornia, librosa, imageio from the README's requirements cover the audio side of this pack.
The one real trap: beat_data must be valid JSON with the expected shape (beats as a non-empty list), or the node raises. If you get an empty beat list, the error is upfront - check whatever node produced the beat map, not this one. And remember the output is scene durations, not burned subtitles: you still need something downstream to render them onto the video. If you want on-screen lyric sync rather than just cut timing, pair it with SRTLyricsMerger and a subtitle-burn node.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| beat_data | STRING | — | |
| min_duration | FLOAT | 2.0 | — |
| max_duration | FLOAT | 10.0 | — |
| bias | FLOAT | 0.700–1 | — |
| duration_preset | COMBO | impact_weighted | 3 options: impact_weighted, varied_no_repeat, clustered_no_repeat |
| seed | INT | 0 | — |
| output_filename | STRING | beats_output | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| srt_text | STRING | — |
| srt_path | STRING | — |