SCAIL Beat-Driven Dance
A physics-based dance engine that hits your beats
- base_pose
- beat_info
- audio_features
- pose_sequence
This is the heart of the pack - the node the README calls "the Choreographer." SCAILBeatDrivenPose takes a base skeleton, a beat structure and audio features, and generates a full physics-based dance sequence with 80+ poses across styles like hip hop, rock and disco. Where the AIST/CMU nodes replay real motion capture, this one synthesizes dance in real time, which means it's fully audio-reactive: bass drives the bounce, treble drives the arms, and moves snap onto the beat with adjustable anticipation. It's also the only node in the pack that does real multi-character coordination out of the box.
How it works
The movement is driven by a custom physics engine rather than a lookup table. A few design choices make it worth understanding:
- Sticky feet. Ankles get zero drag and double stiffness in the engine's
MotionDynamicsmodel, forcing them to snap to the floor unless a specific move lifts them. That's the difference between a grounded dancer and a floating puppet - the classic failure of procedural animation. - Neutral structure init (auto-rigging). If your reference pose has the character mid-stride or on one leg, the engine computes a neutral standing skeleton from their bone lengths and interpolates Reference → Neutral → Dance move. Without this, a character whose reference image has one foot up stays stuck with one foot up all dance.
- Scale-aware movement. Amplitudes are normalized to torso length, so a background character moves with appropriately smaller absolute motion and won't collide with the foreground dancer.
The inputs are many but they divide into two buckets. Structure: base_pose, beat_info, audio_features (all wired in - from SCAILBasePoseGenerator or SCAILPoseFromDWPose, SCAILBeatDetector, and SCAILAudioFeatureExtractor). Feel: the knobs that actually change the output:
dance_style(22 options,autopicks by energy) andenergy_style(auto/low/medium/high)interaction_mode-unison(everyone identical),mirror(left/right swapped around the leader),random(independent moves). This is where 2–5 characters get interesting.motion_smoothness(lower = snappier, higher = floatier),anticipation(frames the move starts before the beat),groove_amount(continuous hip sway),bass_intensity(vertical bounce),treble_intensity(arm/hand jitter)phrase_bars(4/8/16 - when choreography changes),staging_mode(off/subtle/dynamic),hit_easing(linear/ease_out/bounce/elastic/punch),pose_blend,loop_mode(force a seamless loop),seed
Output
One output, pose_sequence, into SCAILPoseRenderer, then the rendered frames feed your Wan pose-control nodes. The pack's example workflows run exactly this chain with the SCAIL-preview Wan model.
Installing and common gotchas
Standard pack install: clone ckinpdx/ComfyUI-SCAIL-AudioReactive into ComfyUI/custom_nodes, pip install -r requirements.txt, restart (ComfyUI Manager works too). No downloads for this node itself.
The gotchas are the frame-count mismatch (beat_info and audio_features must come from matching frame_count/fps), and the initial-pose trap - if your reference image has the character in a weird stance, the neutral-structure init handles it, but you'll still get better results starting from active_idle than from a mid-stride frame. And if the dance feels robotic, lower motion_smoothness before you blame the physics.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| base_pose | SCAIL_POSE | Base skeleton pose from DWPose or Generator | |
| beat_info | SCAIL_BEAT_INFO | Beat detection data from SCAILBeatDetector | |
| audio_features | SCAIL_AUDIO_FEATURES | Audio analysis from SCAILAudioFeatureExtractor | |
| dance_style | COMBO | auto | Dance style preset. 'auto' selects moves based on energy level. |
| interaction_mode | COMBO | mirror | Multi-character coordination: unison=same moves, mirror=left/right swapped, random=independent |
| energy_style | COMBO | auto | Override energy detection. 'auto' uses audio RMS. |
| motion_smoothness | FLOAT | 0.500.1–3 | Lower = snappier, higher = smoother/floaty |
| anticipation | INT | 30–10 | Frames to start moving BEFORE beat |
| groove_amount | FLOAT | 1.000–3 | Hip sway/bounce intensity synced to tempo |
| bass_intensity | FLOAT | 1.200–5 | How much bass drives motion snap |
| treble_intensity | FLOAT | 1.200–5 | How much treble drives arm movement |
| phrase_bars | COMBO | 8 | Bars per phrase. Choreography changes on phrase boundaries. |
| staging_mode | COMBO | subtle | Stage movement: off=stationary, subtle=small sway, dynamic=larger travel |
| hit_easing | COMBO | ease_out | Motion curve for pose transitions. Affects how moves hit the beat. |
| pose_blend | FLOAT | 0.300–1 | Blend between poses. 0=hard keyframes, 1=maximum smoothing between poses |
| loop_mode | BOOLEAN | false | Ensure first and last frames match for seamless looping |
| seed | INT | 00–99999 | Random seed for deterministic choreography |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pose_sequence | SCAIL_POSE_SEQUENCE | — |