Camera Shake (Video File)
Add handheld motion without a plugin
- output_path
Perfectly stable AI video looks, well, perfectly stable - which is often exactly the problem. A touch of handheld wobble is what sells a shot as real footage, and for action scenes a deliberate shake does the heavy lifting of "impact." This node adds procedural camera shake to an existing video file: circular or random motion patterns, adjustable radius, easing, and optional seamless looping - then writes out a new file with the original audio intact.
It's the file-based sibling of the in-graph camera shake in this pack, and the pattern will be familiar if you've used the other "Video File" nodes: ffprobe the input, extract frames, apply the effect, re-encode, copy audio. It does all the decode/encode work itself, so you just hand it a path.
How it works
The node extracts all frames at the video's original FPS, applies the shake pattern, and re-encodes as H.264 with the audio copied across losslessly. The two mode options behave quite differently:
- Circular Shake - a smooth sinusoidal orbit around the center. Reads as a gentle handheld or "floating" motion; good for subtle life on a locked-off shot.
- Random Shake - constant-magnitude random directional steps (per the README, ±1 pixel steps), which reads as chaotic and buzzy - your punchy action look.
pixels_per_frame is the shake radius relative to the smaller canvas dimension (default 5.0) - bigger is more violent. ease shapes an envelope over the clip's duration (Ease_In starts gentle and builds; Ease_Out is the reverse), and loop forces circular shake with a constant radius so the loop point is seamless - turn it on if you're making a loopable clip.
Safe cropping keeps the shake from revealing black edges: the node crops within the canvas rather than letting the viewport slide off the frame.
Inputs and output
video_path- the file to shake.mode-Circular Shake(default) orRandom Shake.pixels_per_frame- shake radius, default 5.0.ease- Linear / Ease_In / Ease_Out / Ease_In_Out.loop- seamless-loop mode, default off.prefix- output filename prefix, defaultcamera_shake.
Output is output_path, the shaken video file.
Installing it
One of ~25 nodes in the Simple Video Effects pack:
cd ComfyUI/custom_nodes
git clone https://github.com/scofano/ComfyUI-Simple-video-effects
cd ComfyUI-Simple-video-effects
pip install -r requirements.txt
Restart ComfyUI, or install via ComfyUI Manager (search "Simple Video Effects"). No models. ffmpeg/ffprobe must be on your PATH.
Common issues
The classic mistake is radius. A pixels_per_frame of 5 sounds small, but on a 512×512 source that's ~1% of the frame per step of random shake, and random mode compounds it into visible jerk. Start at 2–3 for realism and work up - subtle reads as footage, violent reads as a mistake. If you want a loop, remember loop only matters in the sense that it switches to circular with constant radius; with random mode and loop off, your loop point will visibly jump. And since this is a re-encode, you're taking a small quality hit - apply shake last in your chain, not first.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| video_path | STRING | — | |
| mode | COMBO | Circular Shake | 2 options: Circular Shake, Random Shake |
| pixels_per_frame | FLOAT | 5.0 | — |
| ease | COMBO | Linear | 4 options: Linear, Ease_In, Ease_Out, Ease_In_Out |
| loop | BOOLEAN | false | — |
| prefix | STRING | camera_shake | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| output_path | STRING | — |