Video Stabilize
Fix the wobble, keep the move
- video
- motion
- mask
- video
- zoom
Two node packs on this shelf do opposite jobs and people reach for the wrong one constantly. Video Camera Shake adds shake; Video Stabilize removes it. This is the removal one: it fits the camera's own movement from the motion between frames, smooths it (or locks it), and moves each frame to follow the steady path, with each scene steadied on its own so a cut does not get dragged into the previous shot's correction.
Where it earns its keep is on generated video. Diffusion samplers drift - a slow shot can breathe, wobble, or creep sideways over ten seconds in a way nobody asked for - and on footage you shot yourself, which is where the shake came from in the first place.
Inputs
video is the clip, at least two frames. mode is the big decision: smooth keeps the camera's intended move and removes the shake, lock holds the first frame's framing for the whole scene - as if it were on a tripod. lock is the stronger, weirder-looking option; smooth is what you want 90% of the time, because a stabilised shot that has been locked usually reads as dead.
smoothing is seconds of camera movement averaged, and it is where the craft lives: 0.25 removes jitter only and keeps almost everything the camera did, 1.0 is the default, 3.0 gives a slow floating move that has more in common with a gimbal than a hand. Lower is safer. Push it up and you are effectively re-authoring the camera move, which is fine if you meant to.
motion_model is the fit: similarity covers sliding, rolling and zooming - the full set - while translation only handles sliding, for a clip whose rotation is intentional and should be left alone. Start with similarity.
borders is what fills the edge a moved frame leaves bare: zoom enlarges until none shows, up to max_zoom; edge, mirror or black fill it other ways. max_zoom (default 1.25) is the ceiling on that enlargement. This is the setting that bites - stabilising a shaky clip requires moving frames, moving frames exposes edges, and hiding edges means cropping in. A heavy shake and a tight framing are in direct conflict.
motion is optional and takes a shared measurement from Video Motion of this same clip. mask is the one people miss: give it a per-frame subject mask (white on the subject) and the subject is left out when the camera's motion is read, so a large moving subject cannot drag the frame along with it. That is a real failure mode - a person walking across a steady shot can dominate the flow estimate and make the stabiliser follow them.
Outputs
video is the steadied clip: same size, length, frame rate and audio. zoom is a FLOAT with the enlargement actually applied, 1.0 for none - useful for spotting when the node had to work hard, and worth checking before you blame something else for a shot that suddenly got tighter.
Install
ComfyUI Manager → search WAS Node Suite v3 → install → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui.git
ComfyUI 0.14.0+ and Python 3.10+. Nothing is pip-installed by the pack - requirements.txt is a comment and pip never runs - which is exactly how this node exists at all: the v2 suite's OpenCV dependency is gone, and the whole family now runs on torch on ComfyUI's own device. No model weights unless you opt into a learned flow network in ComfyUI/models/optical_flow.
Honest limits
It cannot fix rolling shutter. Wobble and jelly distortion are not a rigid transform, and neither a similarity nor a translation fit can undo them. If that is your problem, you need a warping stabiliser, not this.
It cannot fix a shot that is genuinely ruined. A clip where the camera swung wildly needs more than retiming a path; you are better off regenerating it. Stabilisation is for small, persistent error.
Lock + moving subject = fighting yourself. In lock mode with someone walking through frame, the whole background will drift to hold the frame still. Use the mask input or switch to smooth.
Do not stabilise before per-frame effects. Steady first, then blur or trail, so the effects are working on final framing rather than having to be re-done.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| video | VIDEO | The clip to steady, at least two frames. | |
| mode | COMBO | smooth | 'smooth' keeps the camera's intended move and removes the shake; 'lock' holds the first frame's framing for the whole scene. |
| smoothing | FLOAT | 1.000–30 | Seconds of camera movement averaged in 'smooth': 0.25 = removes jitter only; 1.0 = default; 3.0 = a slow, floating move. |
| motion_model | COMBO | similarity | 'similarity' steadies sliding, rolling and zooming; 'translation' only sliding, for a clip whose rotation is meant. |
| borders | COMBO | zoom | What fills the edge a moved frame leaves bare: 'zoom' enlarges until none shows, up to max_zoom; 'edge' stretches the last pixels; 'mirror' reflects; 'black' leaves it black. |
| max_zoom | FLOAT | 1.251–3 | Most enlargement 'zoom' may use: 1.0 = none; 1.25 = default; 1.5 = heavy shake. |
| motionopt | WAS_MOTION | Motion from Video Motion, measured from this same clip at any size. Left empty, it is measured here at 768 px on the long side. | |
| maskopt | MASK | Subject mask per frame, white on the subject, such as from SAM 3. The subject is left out when the camera's motion is read, so a large moving subject cannot pull the frame along with it. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | The steadied clip: same size, length, frame rate and audio. |
| zoom | FLOAT | The enlargement applied to hide the edges, 1.0 for none. |