Nodes/Compare Frames/πŸ–ΌοΈ Compare Frames
ComfyUI Node

πŸ–ΌοΈ Compare Frames

Actually seeing the difference between two video gens, without leaving the graph

By sidmehraajmΒ·Created 5 months agoΒ·Updated 5 months agoΒ· 4
πŸ–ΌοΈ Compare Frames
  • images_a
  • images_b
    β—„compare_frame0β–Ί
    β—„skip_a0β–Ί
    β—„skip_b0β–Ί
    β—„fps12.0β–Ί

    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 computes max(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_frame is shared; it is not a per-side index. To look at frame 30 of A and frame 24 of B, set compare_frame to 24 and skip_a to 6. That's the whole point of the skip fields.
    • Output clutter - because it subclasses PreviewImage, every run writes temp.compare_frames_*.png files into output/. 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.

    Categorypreview

    Inputs (6)

    NameTypeDefaultDescription
    compare_frameINT00–99999β€”
    skip_aINT0-99999–99999β€”
    skip_bINT0-99999–99999β€”
    fpsFLOAT12.00.1–60β€”
    images_aoptIMAGEβ€”
    images_boptIMAGEβ€”

    Outputs (0)

    No outputs