Nodes/NKD Preview Tools/😺NKD Timeline
ComfyUI Node

😺NKD Timeline

An actual video editor inside ComfyUI

By Nekodificador·Created 5 months ago·Updated 4 days ago· 41
😺NKD Timeline
  • media
  • images
  • mask
  • coverage
  • generate
  • audio
  • audio_mask
  • audio_ranges
  • width
  • height
  • fps
  • frame_count
  • duration
  • current_frame
  • current_image
  • markers
  • raw_images
timeline
import_modestack
aspect_ratioCustom
width0
height0
megapixels1.00
size_multiple16
fitcontain
fps24.00
modelfree
quantize_n8
start_frame0
frame_count0
clip_audiotrue
clip_markersfalse

You've been hand-counting frames

Video workflows in ComfyUI are doable, but the "edit" part is where the graph falls apart. You compute trim ranges by hand, feed frame_count = 97 into an empty latent, and pray three clips line up. NKD Timeline is the antidote: a real multi-track timeline inside a node, where you drag clips, trim, slip, blade and layer them, and get the numbers back as sockets the rest of the graph actually consumes. It ships in NKD Preview Tools by Nekodificador, a ComfyUI author with a real reputation for "the editor should just work" tooling - his NKD VFX and Klein Tools packs pull hundreds of upvotes on r/comfyui, and people describe using his nodes daily.

What actually happens under the hood

The node is split-brain. A frontend editor (scrub, trim, Alt-slip, blend modes, markers) serializes your cut into a hidden timeline widget, and a Python backend parses that JSON and does the real work: decoding each source in windows, compositing frames in track order with blend modes, mixing the audio lanes through PyAV, and handing back one tidy image batch plus a set of masks. The media input is an autogrow socket - connect a video, an image sequence, a mask or audio to media_0 and another slot appears. The editor figures out which lane each thing belongs on.

The inputs that matter

  • model - the gotcha beginners miss. Pick the model this timeline feeds and the frame count snaps to the grid that model requires: Wan and Hunyuan want 4n+1, LTX and Cosmos 8n+1, Mochi 6n+1, MiniMax H3 17n+5. If a clip's rate doesn't match the timeline fps, the editor flags it rather than resampling it silently.
  • import_mode - stack layers each source on its own track from frame 0 (higher track wins; set blend modes via right-click); append assembles a sequence on one track.
  • width / height - 0 means "take the first clip's resolution." Or pick an aspect ratio and a megapixels budget and let it compute, rounded to size_multiple.
  • fps, start_frame, frame_count - the classic trio. frame_count 0 runs to the end of the last clip.

Wire the outputs

images feeds your VAE encode and sampler. The mask outputs are where this node gets clever: coverage is WHITE where the timeline is empty - the stretches the editor labels "generate" - and generate is the mask lane UNION those gaps. Feed generate straight into a temporal inpainting mask and the model fills exactly the holes you left, no manual inversion. Then width, height, fps and frame_count drive your empty latent so the render matches the cut. current_image hands back the composited frame under the playhead, and markers feeds NKD Freeze Frames, its sibling in this pack.

Install and run

No model downloads, no dependency hell - the pack declares zero Python deps, and encoding rides on PyAV, which is already a hard dependency of core ComfyUI. Install via Manager (search "NKD Preview Tools") or:

cd ComfyUI/custom_nodes
git clone https://github.com/Nekodificador/ComfyUI-NKD-Preview-Tools

Restart, drop the node in under 😺NKD Nodes/Preview, connect a Load Video, hit conform to take fps and resolution from the first clip, and scrub the ruler. Space plays, J/K/L shuttles, I/O set the in and out points, Ctrl+wheel zooms, M drops a marker, Q and E bring a clip's edges to the playhead.

Where people trip

Run it with nothing connected and you get "the timeline is empty" - wire a source. If a workflow saved before mid-2026 comes up miswired, the author deliberately rebuilt the widget and output order once (a one-time break for a small audience), so the node may need re-adding. And check clip_audio: your videos' own sound only rides along if that's on.

Category😺NKD Nodes/Preview

Inputs (16)

NameTypeDefaultDescription
mediaCOMFY_AUTOGROW_V3Connect a video, an image sequence, a mask or audio - the same socket takes any of them and the timeline puts it on the right lane. More slots appear as you connect.
timelineSTRING
import_modeCOMBOstackWhere a newly connected source is placed. 'stack' gives each one its own track from frame 0, so they layer like any other timeline - the higher track is the one you see. 'append' puts it after the previous one on the same track, to assemble a sequence.
aspect_ratioCOMBOCustom'Custom' uses width/height below, which is what this node always did. Any other ratio computes them from the megapixel budget, and the monitor follows immediately - no run needed.
widthINT00–163840 = take the width of the first clip.
heightINT00–163840 = take the height of the first clip.
megapixelsFLOAT1.000.05–16Pixel budget for the chosen ratio. Ignored when aspect_ratio is 'Custom'.
size_multipleINT161–64Round the computed size to a multiple of this. Match the model's canvas grid (MiniMax H3 uses 32) or it resizes every frame again on its way in.
fitCOMBOcontainHow a clip is fitted when its aspect ratio does not match the output. The preview shows this live.
fpsFLOAT24.001–240Timeline frame rate. Sources at a different rate are resampled.
modelCOMBOfreeThe model this timeline feeds. Its frame count is snapped to the grid that model requires: Wan, Hunyuan Video, Kandinsky, Cosmos Predict and SCAIL use 4n+1; LTX and Cosmos 1 use 8n+1; Mochi uses 6n+1; MiniMax H3 uses 17n+5.
quantize_nINT81–256Only used by 'custom (multiple of N)'.
start_frameINT00–1000000
frame_countINT00–10000000 = up to the end of the last clip.
clip_audioBOOLEANtrueInclude the videos' own audio in the mix.
clip_markersBOOLEANfalseAlso emit the first and last frame of every picture clip on the 'markers' output, AHEAD of the hand-placed markers: clip 1 in, clip 1 out, clip 2 in… NKD Freeze Frames then freezes each cut's boundary frames without marking them by hand.

Outputs (16)

NameTypeDescription
imagesIMAGE
maskMASKThe mask lane, and nothing else.
coverageMASKWhite where there is NO material, i.e. the stretches the editor labels 'generate'. Feed it straight to a temporal inpainting mask. For the gaps PLUS the mask lane, use 'generate'.
generateMASKEverything the model should generate: the mask lane UNION the gaps. A gap is a region to generate, so it belongs in the conditioning mask - 'mask' alone leaves it black and nothing is generated there. This is the socket for temporal inpainting.
audioAUDIO
audio_maskMASKWHITE where the rendered soundtrack is silent: frames covered by a MUTED clip, and frames no clip gives sound to at all — silence is a region to generate, like a picture gap in coverage. One value per frame: feeds the audio mask of 😺NKD AV Latent / 😺NKD Audio Mask directly. For MVEx Audio Mask To Latent use audio_ranges instead.
audio_rangesSTRINGThe same silent stretches as in,out second pairs (e.g. 0.292,0.833), relative to the rendered range — the exact syntax MVEx Audio Mask To Latent's time_ranges input parses.
widthINT
heightINT
fpsFLOAT
frame_countINT
durationFLOATLength of the output range in seconds.
current_frameINT
current_imageIMAGE
markersSTRINGComma-separated indices of the freeze-frame markers (press M on a clip), counted INTO the 'images' batch. Feed it to NKD Freeze Frames.
raw_imagesIMAGEThe timeline cut as-is: every clip contributes its picture, including audio-only clips. Gaps with no material are black. Use as reference for models that need the original video.