Nodes/TrentNodes/Enhanced Animation Timing Processor
ComfyUI Node

Enhanced Animation Timing Processor

The trick to making 2D animation hold still in video models

By TrentHunter82·Created 9 months ago·Updated 4 days ago· 36
Enhanced Animation Timing Processor
  • images
  • processed_frames
  • duplicate_mask
  • timing_report
  • removal_indices
similarity_methodhybrid
similarity_threshold0.85
motion_tolerance0.05
gray_styledesaturated
gray_intensity0.5
preserve_firsttrue
preserve_lasttrue
preserve_global_firsttrue
preserve_global_lasttrue
skip_secondfalse
skip_second_to_lastfalse
min_sequence_length2
min_gray_frames4
insert_paddingtrue
align_keyframestrue
alignment_multiple4
debug_infofalse

Traditional 2D animation is mostly holds: a drawing sits on screen for three, six, twelve frames with nothing changing. Feed that into a video model and it does what video models do - it makes the held frames drift, breathe, morph, shimmer. The Enhanced Animation Timing Processor exists for this exact problem. It detects the duplicate frames that make an animation a hold, turns them into neutral gray frames so the video model has nothing to invent, and then - this is the clever part - pads and aligns everything so keyframes land on clean multiples of 4 for glitch-free generation.

Here's the workflow it's built for: you generate a video from an animation sequence, the video model renders only the "real" keyframes cleanly, and the gray holds become placeholders that come back out. Wire this node's removal_indices output into the companion Animation Frame Remover and you strip the padding after generation, returning to the original frame count with your generated content preserved. The two nodes are a matched pair; the processor is the one that does the thinking.

How the detection works

similarity_method picks between hybrid (default), ssim, histogram, and perceptual. SSIM is the structural-similarity comparison you'd expect, histogram compares color distributions, perceptual runs edge-based Sobel filtering to compare structure, and hybrid blends them. similarity_threshold (default 0.85) decides how similar two frames must be to count as a duplicate run, with motion_tolerance absorbing tiny movements so a held pose with a millimeter of jitter still registers as a hold. Then the gray replacement frames get rendered in one of three styles - solid_gray, desaturated, or dimmed - at gray_intensity.

The defaults are tuned to be safe rather than aggressive: preserve_first and preserve_last keep the first and last frame of each duplicate sequence untouched, preserve_global_first/preserve_global_last protect the batch endpoints, and min_sequence_length (default 2) stops a single pair of frames from being treated as a hold. When holds are too short for clean padding, insert_padding inserts extra gray frames automatically.

Keyframe alignment - the knob that matters

align_keyframes (on by default) with alignment_multiple (default 4) is the part that makes or breaks a render. It inserts padding frames so keyframes land on multiples of 4 - frames 0, 4, 8, 12 - because that's the frame grid several video models (Wan included, which wants 4x+1) actually generate cleanly on. If you see glitching or interframe wobble at keyframes, this is the first thing to check: make sure align_keyframes is on and the multiple matches what your model wants.

Inputs, outputs, gotchas

You feed it images (an IMAGE batch) and read processed_frames out for generation. The three diagnostic outputs matter more than they look: duplicate_mask flags which frames are holds, timing_report gives you the readable analysis, and removal_indices is the comma-separated string you feed to Animation Frame Remover. Turn on debug_info if you want the full sequence-by-sequence breakdown in the console.

The main trap is threshold tuning. Set similarity_threshold too low and genuine animation frames get grayed out; too high and holds with any motion pass through undetected. Start at the 0.85 default, check timing_report on a short test clip, and adjust by a hundredth at a time.

Installs as part of TrentNodes - ComfyUI Manager, search "Trent Nodes", or git clone https://github.com/TrentHunter82/TrentNodes into custom_nodes/. No model downloads; this is pure analysis. Pair it with Animation Frame Remover in the same pack and the whole pad → generate → strip loop stays inside the graph.

CategoryTrent/Animation

Inputs (18)

NameTypeDefaultDescription
imagesIMAGE
similarity_methodCOMBOhybridMethod for calculating frame similarity
similarity_thresholdFLOAT0.850–1How similar frames need to be to count as duplicates
motion_toleranceFLOAT0.050–0.3Tolerance for small movements/changes
gray_styleCOMBOdesaturatedHow to render the gray replacement frames
gray_intensityFLOAT0.50–1Intensity of gray effect
preserve_firstBOOLEANtrueKeep the first frame of each duplicate sequence unchanged
preserve_lastBOOLEANtrueKeep the last frame of each duplicate sequence unchanged
preserve_global_firstBOOLEANtrueKeep the very first frame of the entire batch unchanged
preserve_global_lastBOOLEANtrueKeep the very last frame of the entire batch unchanged
skip_secondBOOLEANfalseSkip the 2nd preserved frame from the list of all preserved frames
skip_second_to_lastBOOLEANfalseSkip the 2nd-to-last preserved frame from the list of all preserved frames
min_sequence_lengthINT21–10Minimum frames in a sequence to consider as duplicates
min_gray_framesINT40–20Minimum gray frames needed between preserved frames (will insert extra if needed)
insert_paddingBOOLEANtrueAutomatically insert extra gray frames when sequences are too short
align_keyframesBOOLEANtrueAlign keyframes to multiples of alignment_multiple for better video generation quality
alignment_multipleINT41–16Keyframes will be aligned to multiples of this value (e.g., 4 means frames 0, 4, 8, 12...)
debug_infooptBOOLEANfalsePrint detailed analysis of duplicate sequences found

Outputs (4)

NameTypeDescription
processed_framesIMAGE
duplicate_maskMASK
timing_reportSTRING
removal_indicesSTRING