Video Effects
Camera shake, zoom, spin and wobble — video effects without leaving the graph
- image
- audio
- image
- audio
You generated a clip and it's static - no camera life, no push-in, no wobble. The classic fix is to drop it in After Effects or DaVinci and do a Ken Burns move there. This node is the version that never leaves the graph: feed it the frames, pick a movement, and it returns the same-length video with zoom, pan, spin, shake or wobble baked in. It's the flagship of the TKVideoZoom pack, and it's pure deterministic pixel work - no model, no seed lottery, no API key. It'll run in milliseconds where a re-gen takes minutes.
Why this fills a real gap. ComfyUI's post-processing layer is famously patchy - the community consensus is that camera moves and motion blur are exactly what people normally export to a compositor for (our KB calls it the standing "VFX handoff" gap in its post-processing essay). TKVideoZoom is one of the pieces pulling that work back inside the graph. It doesn't invent motion with a model; it transforms frames you already have.
How it works
Under the hood it's OpenCV-on-frames. Each frame gets resized up by a zoom factor, then a crop window of the original dimensions is cut from it - moving that window frame-to-frame is what produces the motion, and the up_dn / left_right inputs decide which corner or edge you zoom toward (top/bottom/center × left/right/center). The movement types:
- zoom in / zoom out / zoom both - the crop window grows or shrinks; "both" sways in then out.
- slide - pans sideways across a scaled-up frame.
- spin - continuous rotation composited over the original so corners don't tear.
- seesaw - rocks between roughly ±30°.
- wobble - a random sine-wave superposition of translations, so it looks handheld rather than mechanical.
- camera shake - a sine-wave
dx/dyshift whose frequency scales withmovement_speed; it even zoom-crops slightly to hide the edges, which is the part most DIY shake implementations forget. - materialize - fades the clip in over a checkerboard background.
The one I reach for constantly is camera shake, then wobble - they're the cheapest way to break the "too smooth" AI look, which is exactly what the grain-and-shake crowd talks about for realism.
Inputs and outputs that matter
The schema is all enums, so nothing to memorize: image and audio (required, both straight off VHS_LoadVideo), frame_count, movement_type, movement_speed, up_dn, left_right, and visual_effect (normal / grayscale / sepia / noise).
Three things actually matter to a beginner:
movement_type- the whole point of the node; start with "zoom in" or "camera shake".frame_count- required with no default. The demo wires it fromVHS_LoadVideo's frame_count output; it drives the progress bar and the wobble/shake waveform length. Wrong value just means a wonky progress bar, but wire it properly and the node feels finished.visual_effect- sepia is a proper color matrix; "noise" is Gaussian burst added on scattered frames (sparser at higher speeds), good for that found-footage feel.
Outputs are image (same resolution, same frame count) and audio, which is passed through untouched - you must supply audio or the required input refuses to run, but the node won't touch it. Wire output image into VHS_VideoCombine's images slot, and set its frame_rate from VHS_VideoInfo's loaded_fps.
Install
ComfyUI Manager → search "TKVideoZoom" → install. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/trashkollector/TKVideoZoom
Restart ComfyUI. No model files to download, ever - the repo ships only mask PNGs and demo workflows. It depends on OpenCV (cv2) at import time, which you almost certainly already have via VideoHelperSuite. Note the pack's requirements.txt is a mess - it pins torch and three different opencv packages with duplicate lines, and you should not let Manager apply those torch pins. Stock ComfyUI plus cv2 is all this needs.
Troubleshooting
If the TKVideoZoom nodes don't appear after install, check that cv2 imports in your ComfyUI environment (python -c "import cv2"). If you see ValueError: cannot reshape array or dimension errors mid-run, it usually means you fed it images of mismatched sizes - keep all frames the same resolution, which VHS_LoadVideo handles if you leave it to re-encode consistently. And remember the video never changes length here: if you want the duration to change, that's the sibling TKVideoSpeedZones node's job, not this one's.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| audio | AUDIO | — | |
| frame_count | INT | — | |
| movement_speed | COMBO | 5 options: very slow, slow, medium, fast, very fast | |
| movement_type | COMBO | 9 options: zoom in, zoom out, zoom both, camera shake, slide, spin, +3 | |
| up_dn | COMBO | 3 options: top, bottom, center | |
| left_right | COMBO | 3 options: left, right, center | |
| visual_effect | COMBO | 4 options: normal, grayscale, sepia, noise |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| audio | AUDIO | — |