πΌοΈ Compare Frames
Actually seeing the difference between two video gens, without leaving the graph
- images_a
- images_b
You've just generated the same video twice - once with a tweaked prompt, once without - and now you're the proud owner of two batches of frames and a growing headache. ComfyUI's default preview hands you them as separate image streams, so spotting the one-frame difference means flipping between outputs or exporting and squinting in an external viewer. πΌοΈ Compare Frames is a small, sharp fix for exactly that: it plays two image sequences side by side, overlaid, or behind a wipe slider, right inside the node.
It's an output node in the preview category, and despite the fancy UI it's mechanically simple. The backend (compare_frames.py) is a thin subclass of ComfyUI's built-in PreviewImage - it saves whatever IMAGE batches it receives to your output/ directory with a temp.compare_frames. prefix and hands the frontend the file lists plus your fps. All the actual comparing happens in web/compare_frames.js, which renders a canvas player with a toolbar. No models, no pip dependencies, no API - the pyproject is bare. It's a personal utility from a single dev (the whole pack is one node), so set expectations accordingly: this is a tool you reach for, not a framework you build around.
The three ways to compare
The toolbar gives you three view modes, and they're each good for a different job:
- Slider - drag a wipe handle across the canvas to reveal A or B at full size. Best for spotting exactly where two frames diverge.
- Side by Side - both sequences split 50/50. Good for a general vibe check.
- Overlay - B blended over A with a draggable transparency slider. Handy when the difference is subtle and you want it to literally float on top.
Below that is a scrubber bar (with a current/total counter), prev/next step buttons, a play/pause toggle with loop, and a speed selector running 0.25Γ to 4Γ. Since this is ComfyUI, the whole thing also works as a single-sequence player if you only wire in images_a.
The inputs that matter
There are only six, and four of them do the interesting work:
compare_frame- the shared playhead for both sequences. Set it to N and both sides show frame N (before per-side offsets).skip_a/skip_b- per-sequence offsets. The frontend computesmax(0, base + skip), so a negative offset lets you align two clips that start at different times, like one sequence leading the other by a few frames.fps- playback speed, default 12.
The optional images_a / images_b are each an IMAGE batch - wire your video-model output (LTX-Video, AnimateDiff, HunyuanVideo, whatever's churning out frames) straight in. There are no outputs: this node terminates the branch, so it belongs at the end of each sequence's pipeline. One nice touch: frames are cached after the first run, so changing compare_frame or the skip values is instant - you don't re-queue the whole graph to peek at frame 40.
Installing it
The boring, reliable way:
cd ComfyUI/custom_nodes
git clone https://github.com/sidmehraajm/ssd_frame_compare
Then restart ComfyUI - it lands under the preview category as πΌοΈ Compare Frames. If you use ComfyUI Manager, search Compare Frames in Install Custom Nodes. That's it: no model downloads, no extra pip installs, nothing but a restart.
Where people get burned
- Node missing after install - you restarted, right? ComfyUI won't pick up new custom nodes until it reloads.
- Empty canvas - both inputs are optional, but you need at least one IMAGE connected. If you expected to compare and see nothing, check the branch actually terminates here.
- Confusing the playhead -
compare_frameis shared; it is not a per-side index. To look at frame 30 of A and frame 24 of B, setcompare_frameto 24 andskip_ato 6. That's the whole point of the skip fields. - Output clutter - because it subclasses
PreviewImage, every run writestemp.compare_frames_*.pngfiles intooutput/. Harmless, just know the temp prefix is why those are there. - Length mismatch - the player's total is
max(len(A), len(B)), so a shorter sequence just hits its last frame early and holds it. That's expected, not a bug.
For its size it's remarkably pleasant to use - the wipe slider alone beats exporting frames to a third-party A/B tool for a mid-workflow check. Just don't expect updates or a big community behind it; it's a small node that does one thing well.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| compare_frame | INT | 00β99999 | β |
| skip_a | INT | 0-99999β99999 | β |
| skip_b | INT | 0-99999β99999 | β |
| fps | FLOAT | 12.00.1β60 | β |
| images_aopt | IMAGE | β | |
| images_bopt | IMAGE | β |
Outputs (0)
No outputs