π RIFE VFI FPS Resample
The one node for hitting an exact FPS, not 'close enough'
- frames
- IMAGE
Video generated locally almost never comes out at the frame rate you actually want. A Wan or Hunyuan render at 24fps, a clip you grabbed at 30fps, and now you're trying to drop both into a 60fps timeline. The usual fix is either frame duplication (smooth but smeary motion blur on the fake frames) or just living with the mismatch. RIFE VFI FPS Resample is the tool that says "no" to both. Feed it any clip, tell it your current FPS and your target FPS, and it converts to exactly that rate - synthesizing in-betweens when it needs to add frames, and dropping them cleanly when it needs to remove.
It's from the WhiteRabbit pack, which is built around the RIFE (Real-Time Intermediate Flow Estimation) IFNet architecture - the same engine that powers most of the frame-interpolation nodes floating around ComfyUI. What makes this node different is that it does arbitrary frame-rate conversion, not just "double it." 24β60, 30β23.976, whatever. And there's a genuinely thoughtful detail in how it handles the downscales: when the conversion is an exact integer drop (say 30β15), it just decimates - throws away frames - instead of wasting GPU time pretending to interpolate. That's the kind of call that tells you the author actually runs this stuff.
How it works
The node converts your clip using exact rational arithmetic under the hood, which matters more than it sounds like it should. FPS conversion implemented with naive floating-point math accumulates a little drift per frame, and by frame 300 your output is off by a frame. WhiteRabbit avoids the whole class of bug by working with exact fractions, so the timeline stays honest no matter how long the clip is. Non-integer conversions compute, for each output frame, the exact position between two input frames and ask RIFE to synthesize an in-between at that spot.
There's also a shared model cache across the pack - if your workflow uses several WhiteRabbit RIFE nodes, the checkpoint loads once instead of once per node.
The inputs that matter
Most of these are set-and-forget:
- frames - your clip, one image per frame.
- fps_in / fps_out - the two numbers you actually care about. Both are floats, so 23.976 is fair game.
- ckpt_name - defaults to
rife47.pth; the pack offers the classic RIFE 4.7/4.9 pair (and supports the newer 4.25/4.26 checkpoints). Missing models auto-download into ComfyUI'smodels/frame_interpolation/on first use, SHA-256 verified. - scale_factor - the quality/speed dial. 1.0 is recommended; 0.5 is faster and softer, 2 is sharper and slower. Leave it at 1 until you're on a deadline.
- ensemble - blends forward and backward predictions to kill artifacts at the cost of speed. Keep it on.
Then there's the stabilizer block: linearize, lf_guardrail, source_pair_match, and edge_band_lock. These exist because RIFE interpolation of AI-generated video has a tendency to shimmer or flicker in flat regions. If your output flickers, turn on lf_guardrail (it pins overall brightness and gradients close to the source frames) and optionally source_pair_match. edge_band_lock protects sharp edges from smearing by mixing in more of the nearest real frame near strong edges. For a first pass, leave them all off - they cost speed and you may not need them.
Installing it
It's a WhiteRabbit pack node, so install once for all of them:
cd ComfyUI/custom_nodes
git clone https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit
cd comfyui-WhiteRabbit
# use your ComfyUI python env:
python -m pip install -r requirements.txt
or just search "WhiteRabbit" in ComfyUI Manager and hit install. The only pip dependency the pack adds is torchlanc (the gamma-correct Lanczos kernel used by the resize nodes); everything else it leans on packages ComfyUI already ships. Note the pack is written against ComfyUI's v3 node API, so keep your ComfyUI reasonably current.
Where people get burned
- The model download on first run. The first execution can sit there for a while pulling
rife47.pth. It's not hung, it's downloading. - Integer downscales are decimation. If you drop 30β15fps and it looks steppy, that's by design - no interpolation happened. If you want it smooth, that's what the up-res direction is for.
- Flicker on synthetic video. AI video has unstable flat regions; that's literally what the stabilizer toggles are for. Enable them before blaming the node.
Wire the output IMAGE straight into a VHS_VideoCombine (or whatever you use to save frames) and you're done. It's the node I'd reach for every time I need a clip to land on a specific rate.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| ckpt_name | COMBO | rife47.pth | Choose RIFE 4.7, 4.9, 4.25, or 4.26 (for interpolation). Missing catalog models download automatically into ComfyUI's frame_interpolation model folder. |
| frames | IMAGE | Your input clip: one image per frame. | |
| fps_in | FLOAT | 24.000.000001β1000 | Current frame rate of your clip (frames per second). |
| fps_out | FLOAT | 60.000.000001β2000 | Target frame rate you want (frames per second). |
| scale_factor | FLOAT | 1.000.25β4 | Quality vs speed. 1.0 recommended. Lower = faster/softer; higher = sharper/slower. |
| ensemble | BOOLEAN | true | Blend forward & backward predictions to reduce artifacts (slower). |
| linearize | BOOLEAN | false | Work in linear light for more accurate brightness and gradients (slower). |
| lf_guardrail | BOOLEAN | false | Keep overall brightness and gradients close to the originals to reduce flicker. |
| lf_sigma | FLOAT | 13.00β64 | How strong the low-frequency smoothing is. Higher = smoother changes. |
| source_pair_match | BOOLEAN | false | Match exposure and contrast to the source pair to reduce flicker. |
| match_a_cap | FLOAT | 0.0200β0.2 | Maximum change allowed for exposure scale. |
| match_b_cap | FLOAT | 0.00780β0.1 | Maximum change allowed for brightness offset. |
| edge_band_lock | BOOLEAN | false | Protect sharp edges: near edges, mix in more of the nearest real frame to avoid smearing. |
| tau_low | FLOAT | 0.00590β0.25 | Edge sensitivity: lower threshold (smaller finds more edges). |
| tau_high | FLOAT | 0.02350β0.5 | Edge sensitivity: higher threshold (larger finds only strong edges). |
| band_radius | INT | 40β64 | Width of the edge protection band (pixels). |
| band_soft_sigma | FLOAT | 2.00β16 | Soften the edge band. Higher = smoother. |
| clear_cache_after_n_frames | INT | 100β1000 | Free up GPU memory every N output frames (advanced). Set 0 to never. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | β |