Video Stabilizer Shake Generator
Add fake handheld shake to static AI video (deterministically)
- frames_context
- Motion Meta
Static AI-generated footage has a lifelessness that's hard to name until you've seen it next to real handheld video. This node is the fix: it generates realistic camera shake and hands it to the pack's Motion Apply node, which actually moves the pixels. On its own, Video Stabilizer Shake Generator doesn't touch a single pixel - the node's own tooltip is refreshingly honest about it: "This node outputs motion metadata only; connect it to Video Stabilizer Motion Apply to move pixels."
It's part of the ComfyUI-Video-Stabilizer pack, which is a two-sided operation: the stabilizer nodes remove real shake and record it as motion_meta, and this node manufactures fake shake in the same format. Same wire, opposite intent. The motion_meta it produces is deterministic - the same seed always produces the same shake - which is genuinely useful: you can lock in a "handheld look" and reuse it across clips, or bump the seed per clip to keep each one different.
How it works
The node models shake as layered noise. There's a low-frequency drift (the sway you fight while holding a phone), a higher-frequency tremor layered on top, and, in some presets, sudden jitter events and a walking bounce. Each of those is generated from the seed, converted into per-frame pan/tilt/roll/zoom values, and baked into the same per-frame 3×3 matrix format the stabilizers emit. Since it never reads frame content, you feed it frames_context - any image batch or video - purely so it can read the frame count and resolution. Wire your actual video in; it won't be processed.
The inputs that matter
style- the character of the shake:tripod(nearly static),handheld(natural handheld),walking(up-and-down bounce from footsteps),action(intense),vibration(mechanical vibration, think inside a vehicle).amount- overall shake strength (0–3, default1).speed- overall shake speed (0.1–3, default1).lock_horizon- removes roll rotation while keeping the selected pan/tilt/zoom motion. This is your "handheld X/Y without a tilted horizon" switch, and it's the one you'll actually flip if you plan to feed the result into anything that hates roll.seed- the reproducibility knob.frame_rate- only a fallback if your input doesn't carry fps metadata.
The output is a single socket: Motion Meta (JSON). Wire it into Motion Apply's motion_meta input.
Install and gotchas
Install is the pack standard - ComfyUI Manager → "ComfyUI-Video-Stabilizer", or:
cd ComfyUI/custom_nodes
git clone https://github.com/nomadoor/ComfyUI-Video-Stabilizer
Restart. No model downloads, and the only dependency is opencv-python-headless (auto-installed). It does need a recent ComfyUI, since the pack uses the newer V3 node API.
Where people get burned: mostly by expecting the node to change the video on its own. Nothing happens until you connect Motion Apply, and if you forget lock_horizon you'll get roll that reads as a tilted horizon on a tripod shot. Also remember the deterministic thing cuts both ways - same seed, same shake, every time. If a clip feels off, change the seed or nudge amount, not the whole workflow.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| frames_context | IMAGE | The input frames are used only to read frame count and resolution. This node outputs motion metadata only; connect it to Video Stabilizer Motion Apply to move pixels. | |
| frame_rate | FLOAT | 16.0 | Fallback frame rate when the input does not carry fps metadata. |
| style | COMBO | handheld | 5 options: tripod, handheld, walking, action, vibration |
| amount | FLOAT | 1.000–3 | — |
| speed | FLOAT | 1.000.1–3 | — |
| lock_horizon | BOOLEAN | false | Remove roll rotation while keeping the selected pan, tilt, and zoom motion. |
| seed | INT | 00–18446744073709550000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| Motion Meta | JSON | — |