Difforum · Schedule
The keyframe brain behind Difforum's Deforum-style animation
- params
- audio
- schedule
- values
If you ever used Deforum in Automatic1111, you remember the syntax: 0:(0), 60:(0.5*sin(2*pi*t/30)), 120:(1.0). That string was the heart of the whole genre - every zoom pulse, camera wobble and strength swell came from keyframes holding little math expressions. Difforum Schedule is that exact thing, rebuilt for modern ComfyUI. It parses a Deforum-style keyframe string into a dense per-frame curve that every other Difforum node can consume.
The name is a bit misleading: it's not a "schedule" you set, it's the engine that makes scheduling possible. Wire one of these into a camera node, a warp, the VJ Look's intensity_schedule, or a Feedback Sampler's strength - anywhere Difforum accepts a DIFFORUM_SCHEDULE - and you get animation that's driven by math instead of by hand-keyframing a hundred frames.
How it works
The curve gets built over params["max_frames"] (which comes from Difforum · Anim Setup), one value per frame. Between keyframes, the node eases - linear, ease_in, ease_out, ease_in_out, or step (hold the left keyframe). A nice detail: both endpoints are evaluated at the current frame, so an oscillator like 0:(sin(t/10)) keeps oscillating across the whole range instead of freezing between keyframes, while a constant like 0:(0), 60:(1) just ramps linearly.
The important part for safety: expressions are parsed with Python's ast module and run through a whitelist walker. No eval() of arbitrary code. You get sin, cos, tan, sqrt, pow, clamp, lerp, smoothstep, ternaries, and the variables t/f (frame), s (seconds), fps, max_f, pi, e, tau. Connect an audio input and the curve names from the Audio Analyzer - amp, low, mid, high, beat, onset - become available in expressions, so 0:(1.0 + 0.6*low) gives you a bass-pumping zoom.
The inputs that matter
Only three, and one of them is where you'll spend your time:
schedule- the multiline keyframe string.0:(0.5), 30:(1.0), 60:(0.2 + 0.3*sin(t/6))style. Unbalanced parens throw a clear error.easing- interpolation between keyframes.ease_in_outis usually the friendliest;stepis for hard cuts.audio(optional) - aDIFFORUM_AUDIOobject from the Audio Analyzer, which unlocks the audio variable names above.
Outputs are schedule (the DIFFORUM_SCHEDULE object - hand this downstream) and values (the same data as a list of floats, if you want to tap individual frames elsewhere). There's no preview here; that's what Schedule Plot and Schedule Info are for.
Install and gotchas
Everything in Difforum installs the same way, so this applies to every node in the pack. ComfyUI Manager works (search "Difforum"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/chillithebillis/Difforum.git difforum
Restart ComfyUI and watch for [Difforum] loaded N nodes in the console. Dependencies are deliberately minimal - just numpy, which ComfyUI already ships. The whole pack was built to run on Python 3.12+, which is exactly what trips up the original Deforum library. One real-world gotcha that isn't Difforum's fault: on some SD1.5 fp16 builds you get all-black frames (NaN in the UNet). Launch with --force-fp32 - it's a base-model precision issue, not the schedule.
One thing to internalize early: the curve length is fixed by Anim Setup's max_frames. Change that and every schedule downstream re-renders. That's the "everything is schedulable" model in action - and it's why you can plan an entire clip before a single diffusion step.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| params | DIFFORUM_PARAMS | — | |
| schedule | STRING | 0:(0), 60:(0.5*sin(2*pi*t/30)), 120:(1.0) | — |
| easing | COMBO | linear | 5 options: linear, ease_in, ease_out, ease_in_out, step |
| audioopt | DIFFORUM_AUDIO | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| schedule | DIFFORUM_SCHEDULE | — |
| values | FLOAT | — |