Difforum · Camera Keys (blend + lens)
Keyframed moves that blend like a crane — and the lens is a channel of its own
- params
- audio
- camera
- cycle_frames
- info
Camera Shots gives you hard cuts. Difforum · Camera Keys is the opposite philosophy: every key is a camera state, and the camera eases from one state to the next like a single continuous crane move. The node's own core code puts it plainly - a shot list runs each segment at a constant rate and replaces it outright (a cut); here a keyframe shapes the motion and both presets are evaluated and cross-faded with an easing curve, so the camera accelerates out of one move and into the next with no velocity jump. No shear at the boundary, which is exactly what the warp shows when you get it wrong.
The syntax is one line per key:
frame: move [speed] [intensity] [lens] [ease]
so the default 0: dolly_in 0.6 0.5 40 ease_in_out means "at frame 0, dolly in, speed 0.6, intensity 0.5, lens 40°, arriving with ease." That trailing lens field is the differentiator: field of view is its own interpolated channel, independent of the move. A push-in with the lens widening simultaneously is a dolly-zoom - the classic Vertigo effect - and here it's just a keyframe pair, no special preset. No other camera node in the pack gives you that.
The three controls on the node:
blend(default 1.0) - how much of each interval is spent transitioning. 1.0 is a continuous crane move; drop toward 0.0 and it degenerates into the hard-cut behaviour of Camera Shots. This is the one dial that defines the node's character.speed(default 1.0, 0.05–5) - a global multiplier riding on top of each key's per-key speed. Bump the whole camera without rewriting the list.loop_mode-off,harmonic, orzero_mean. This is the seamless-loop machinery: with acycle_framesperiod and a harmonics count, the motion is projected onto periodic components so the path returns to its origin with velocity matched across the wrap - no crossfade. Outputcycle_framestells you the lap length.
The pack is refreshingly honest about this node's failure modes, and prints them into info:
- A move that only drives depth axes (dolly/orbit) will render as a frozen frame without a depth map - and it tells you, suggesting Depth Anything V2 →
depthon the Feedback Sampler withmode=3d, or a flat move instead. Inmode=2dthose axes are discarded before the warp even runs. - One lap can't settle. If
max_framesis only one cycle long, the feedback loop never converges - the note says setmax_framestocycle_frames × 3and add Loop Take. Take it seriously; a 3-lap render lets the motion settle before you keep a lap.
Inputs also include mode (2d/3d), optional audio (audio-reactive keys), cycle_frames (0 = use full clip), and harmonics (1–16, how many periodic components the loop projection keeps - more is smoother but stiffer to fit). Outputs: camera, cycle_frames (INT), and info (STRING, the diagnostic dump - read it, it's genuinely useful).
Install
cd ComfyUI/custom_nodes
git clone https://github.com/chillithebillis/Difforum.git difforum
Restart ComfyUI (console: [Difforum] loaded N nodes), or ComfyUI Manager → "Difforum". numpy-only.
Common issues
- Frozen frames in 3d - the depth-map gotcha above. The info string will say so; don't ignore it.
- A cut when you wanted a crane -
blendis near 0. Crank it back up. - Loop that won't close - wrong
cycle_framesor single lap. Check the closure-error line ininfo(0.0 = exact return).
Camera Keys is the node to reach for when the clip has to feel like a camera op - smooth, continuous, lens doing its own thing. For a first project it's maybe the third camera node you try; for a showcase loop it might be the one you never stop using.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| params | DIFFORUM_PARAMS | — | |
| keys | STRING | 0: dolly_in 0.6 0.5 40 ease_in_out 30: orbit_right 1.0 0.8 35 ease_in_out 60: spiral 1.4 1.1 55 ease_in 90: zoom_out 0.5 0.45 40 ease_out | — |
| blend | FLOAT | 1.000–1 | — |
| speed | FLOAT | 1.000.05–5 | — |
| mode | COMBO | 2d | 2 options: 2d, 3d |
| loop_mode | COMBO | off | 3 options: harmonic, zero_mean, off |
| cycle_frames | INT | 00–100000 | — |
| harmonics | INT | 31–16 | — |
| audioopt | DIFFORUM_AUDIO | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| camera | DIFFORUM_CAMERA | — |
| cycle_frames | INT | — |
| info | STRING | — |