Nodes/MKRShift_Nodes/Freeze Frame Detector
ComfyUI Node

Freeze Frame Detector

Find the dead frames in your footage so you're not hunting them by eye

By criskb·Created 7 months ago·Updated 5 months ago· 0
Freeze Frame Detector
  • video
  • freeze_ranges_json
  • range_count
  • summary
diff_threshold0.0015
min_run_frames4
fallback_fps24.0

AI-generated video has a signature problem: a frozen frame. Whether it's the model losing temporal coherence for a stretch, or a shot that just sits there, dead frames make footage feel broken in a way that's hard to put your finger on. MKRFreezeFrameDetector is the node that finds them for you, instead of you scrubbing a 4,000-frame clip hoping to spot the freeze.

It's the analysis counterpart to the pack's MKRFreezeFrame - that one makes stills, this one finds them. It sits in the pack's media-analysis lane and does exactly one thing: report every range where the video stops moving.

How it works

The mechanism is dead simple, and that's a feature. It decodes the clip to frames and computes, for every adjacent pair, the mean absolute difference of the pixels (divided by 255 to normalize). If that difference is at or below diff_threshold (default 0.0015), the frame boundary counts as "still." Then it groups consecutive still boundaries into runs - with the default threshold and a clean digital source, a genuine freeze is near-zero difference, so it stands out from the background noise of normal motion easily.

Two knobs matter:

  • diff_threshold - how strict "still" is. Crank it up and you'll also flag very slow, near-static shots (someone standing almost still at a distance). Keep it low and only true freezes get caught. The default is calibrated for clean digital video; compressed or noisy footage may need a bump.
  • min_run_frames (default 4) - the minimum length of a still run before it counts. This is your false-positive filter: a two-frame glitch, or a single stuttering frame, won't register as a freeze. Set it higher if you only care about long dead stretches.

fallback_fps is the "source didn't tell me its rate" number, used for converting run lengths into seconds in the output.

Outputs: freeze_ranges_json (array of ranges with start/end frames and seconds), range_count (INT - quickly check if the clip has any freezes at all), and summary (JSON string with frame count, transitions flagged, and warnings).

Where it fits

This is the kind of node that earns its place in a QA step. Run it as part of a batch review after generating a sequence, wire freeze_ranges_json into anything that takes scene ranges, and you'll catch dead footage before it ships - which beats spotting it after a client's review. It's also handy for finding the clean, stable frame in a clip to use as a keyframe: the start of a freeze range is exactly where the camera stopped moving.

Installing and caveats

Standard pack install - ComfyUI Manager search "MKRShift_Nodes", or:

cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes

Then restart. No extra Python deps; it's numpy and Pillow on top of the ComfyUI stack. ffmpeg is only needed if your source format requires it for decoding (MP4 and friends).

One real limitation: it needs at least two frames, and it detects pixel stillness, not content stillness. A slow push-in on a static scene will read as motion (because pixels change), and a talking-head shot where the subject holds perfectly still but the lips twitch will read as not-frozen. It's a freeze detector, not a "is this interesting" detector - pair it with judgment on anything borderline.

CategoryMKRShift Nodes/Media/Analysis

Inputs (4)

NameTypeDefaultDescription
video*
diff_thresholdFLOAT0.00150–1
min_run_framesINT42–100000
fallback_fpsFLOAT24.01–240

Outputs (3)

NameTypeDescription
freeze_ranges_jsonSTRING
range_countINT
summarySTRING