Nodes/SDXL Auto Prompter/APNext H3 Sync Check (does the picture hit the beat?)
ComfyUI Node

APNext H3 Sync Check (does the picture hit the beat?)

Did the picture actually hit the beat? APNext H3 Sync Check

By dagthomas·Created 3 years ago·Updated about 23 hours ago· 289
APNext H3 Sync Check (does the picture hit the beat?)
  • images
  • audio
  • report
  • hit_rate
  • chance
  • lift
fps25.00
tolerance_frames2.0
min_strength0.50
sound_events

Timestamps in a prompt are a request, not a guarantee. You can write "the light hits on the drop at 0:42" and the video model will nod along while the frames do their own thing. If you've ever watched a render that felt synced and wondered whether it really was - or, worse, one that obviously wasn't - this node gives you the only honest answer: it measures the render.

H3SyncCheck takes the clip's frames and its audio, finds the hits in the audio, finds the moments the picture changes, and counts how often a hit has a picture change within a couple of frames - against the same count for the same hits shifted to random times. That's the key move: it compares what you got to chance. A lift over chance is real in-clip sync. No lift means whatever sync you're feeling is coming from the cuts between clips, not from inside them.

It's a dagthomas/comfyui_dagthomas node, and it grew out of the pack's own measurements: across 18 H3 clips of one video, 58% of hits had a picture change within ±80 ms - against a 49% chance baseline. That modest gap is exactly why the pack's Cut Plan puts the hits on the cuts rather than trusting the model to land them inside a shot.

How it works

The frames get squashed to a tiny 54×96 greyscale copy and the node computes per-frame mean absolute difference - a picture-change curve. Peaks in that curve are where the image actually changes. Meanwhile it detects hits in the audio using the same detectors as the APNext H3 Sound Events node (or you connect its events list directly). It then measures the offset from each hit to the nearest picture change and scores how many land within tolerance_frames (default 2). For the chance baseline, it shifts the same hits to 300 random times and averages the hit rate - so you get a real number for "how often this would happen by accident."

It also reports the onset-envelope / picture-change correlation and its best lag, and lists every hit with its offset, so you can see which hits are being missed.

The inputs that matter

  • images - the rendered frames: the decoded clip, or a joined video.
  • audio - the audio those frames were rendered to: the clip's own piece, or the whole song for a joined video. This pairing matters - the hits have to match what the picture was actually generated against.
  • fps - the frame rate of images (default 25; set it right or the frame-to-time math lies).
  • tolerance_frames - how close a picture change must be to a hit to count. 2 frames at 24–25 fps is ±80 ms, the "tight" band.
  • min_strength - when no events are connected, only hits at least this strong are checked.
  • sound_events - optional: the Sound Events list for this audio, timed from its start. If you already ran the music through H3 Sound Events, feeding it here makes the measurement use your hand-tuned event list instead of a fresh detection.

Outputs: report (the human summary), hit_rate (how often hits landed a picture change), chance (how often they'd land at random), and lift (the difference - the number you actually care about).

Install

Same pack as the rest of the H3 family:

cd ComfyUI/custom_nodes
git clone https://github.com/dagthomas/comfyui_dagthomas
cd comfyui_dagthomas
pip install -r requirements.txt

Then restart ComfyUI (Manager search "comfyui_dagthomas" works too). Pure numpy/torch, no models, no heavy deps - this is a measurement node, not a generator.

Troubleshooting

The classic beginner mistake is feeding mismatched pairs - a clip's frames with the whole song, or a joined video with one scene's audio piece. The node can't tell you you've done this; it just reports a nonsense number. Match images to its own audio and the output stops being noise. And don't read a small lift as failure: for a music video cut on the beat, sync should live at the cuts, and a near-chance in-clip score with a strong hit rate is the workflow working as designed. The tool is there to tell you which of the two you're actually getting.

Categorycomfyui_dagthomas/H3

Inputs (6)

NameTypeDefaultDescription
imagesIMAGEThe rendered frames (decoded clip, or a joined video).
audioAUDIOThe audio those frames were rendered to - the clip's own piece, or the whole song for a joined video.
fpsFLOAT25.001–120Frame rate of `images`.
tolerance_framesFLOAT2.00.5–8How close (in frames) a picture change must be to a hit to count.
min_strengthFLOAT0.500–1When no events are connected: only hits at least this strong are checked.
sound_eventsoptSTRINGOptional: the Sound Events list for THIS audio (timed from its start). Otherwise hits are detected here.

Outputs (4)

NameTypeDescription
reportSTRING
hit_rateFLOAT
chanceFLOAT
liftFLOAT