Nodes/ComfyUI-CustomNodePacks/Video Frame Player
ComfyUI Node

Video Frame Player

The video scrubber that crops, trims, and resizes in the graph

By Code2Collapse·Created 6 months ago·Updated a day ago· 52
Video Frame Player
  • frames
  • frame
  • frame_index
  • frame_count
  • processed
  • out_width
  • out_height
  • crop_x_px
  • crop_y_px
  • crop_w_px
  • crop_h_px
  • trimmed_count
  • playback_fps
  • frames_trimmed
  • trim_start_idx
  • trim_end_idx
  • width
  • height
  • duration
  • video_info
frame_index0
output_modecurrent_frame
frame_start0
frame_end-1
frame_stride1
playback_fps24.0
loop_modeloop
crop_enabledfalse
crop_lockedfalse
aspect_ratiofree
custom_aspect_w16.0
custom_aspect_h9.0
crop_x0.000
crop_y0.000
crop_w1.000
crop_h1.000
resize_methodnone
target_width0
target_height0
upscale_factor1.00
preview_width480
preview_formatpng
preview_quality95

Every video workflow in ComfyUI has the same bottleneck: you can't look at your frames without chaining Load → Preview and you can't choose a frame without guessing at an index. VideoFramePlayerMEC is the in-graph answer - a scrubber with a timeline you can drag, an interactive drag-crop overlay with eight handles, trim markers, frame stride, and integrated resize, all in one node. It plays inside the node itself, and it emits the processed batch ready to feed a sampler or a video saver.

The pitch from the author is "one node so you don't have to chain Load → Trim → Crop → Resize → Preview," and that's exactly the workflow it replaces. It's from the ComfyUI-CustomNodePacks pack, an output node, and one of the more polished pieces of the whole suite.

How it works

Feed it frames (the batch), and you get a player: drag the timeline to scrub, hit space to play, set loop mode (once / loop / ping-pong), and mark trim in/out by dragging the green and red markers on the timeline. The frame_index widget tracks your scrub position. Turn on crop_enabled and the preview grows a draggable rectangle - aspect-lockable (1:1, 16:9, 9:16, original, custom, etc.) - with rule-of-thirds guides and a live W×H readout. Then resize_method + target_width/target_height/upscale_factor produce the final output.

The critical design decision is output_mode:

  • current_frame (default) - emit only the selected frame. For single-frame work (grab a hero frame, test a prompt on one frame).
  • all_frames - apply trim + stride + crop + resize to every frame, producing the processed batch. This is the mode that turns the player into a real preprocessing stage.

The inputs and outputs that matter

  • frames (IMAGE) - the batch. frame_start/frame_end/frame_stride - the trim range and sampling step (stride applies in all_frames mode).
  • crop_enabled, aspect_ratio, crop_x/y/w/h - the crop, set by dragging on the preview.
  • resize_method, target_width, target_height, upscale_factor - the resize stage. lanczos is the quality pick.
  • playback_fps, loop_mode - playback controls.

The outputs are where this node earns its keep - it's a control room, not just a preview. The ones you'll actually wire:

  • frame (IMAGE) - the full-res frame at the scrubber position (pre-crop/pre-resize, full source precision).
  • processed (IMAGE) - the crop+resize result, or the full trimmed/strided batch in all_frames mode.
  • frames_trimmed (IMAGE) - the trimmed source batch without crop/resize. This is the one to feed a video saver when you don't want to lose source resolution.
  • trimmed_count, out_width, out_height, duration, playback_fps - numbers for downstream automation.
  • video_info (STRING) - a JSON blob with all the metadata (width, height, fps, duration, trim/crop values). Wire it to a Show Text node or your own automation.

That's eighteen outputs total, but you'll realistically use frame, processed, frames_trimmed, and video_info. Don't let the long list intimidate you.

Installing it

Standard pack install:

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git

restart ComfyUI or use Manager → "CustomNodePacks". No heavy dependencies - the preview is browser-side; the crop/resize is standard tensor work.

Where people get burned

The most common mistake is leaving output_mode on current_frame and wondering why the "whole video" came out as one frame. If you're processing the clip, switch to all_frames. The second is forgetting that processed applies crop and resize - if you want the clip at source resolution with only a trim, wire frames_trimmed to your saver instead. And the preview_width/preview_format knobs only affect what the browser shows - the IMAGE outputs are always full source precision, so don't fear the JPEG setting.

CategoryC2C/Preview

Inputs (24)

NameTypeDefaultDescription
framesIMAGEFrame batch (B,H,W,C). B=number of frames.
frame_indexINT00–99999Current frame to emit on the IMAGE output. Drag the timeline to scrub.
output_modeCOMBOcurrent_framecurrent_frame: emit only the selected frame. all_frames: apply trim+stride+crop+resize to every frame.
frame_startINT00–99999First frame of the trim range. Drag the green marker on the timeline.
frame_endINT-1-1–99999Last frame of the trim range (inclusive). -1 = last frame. Drag the red marker on the timeline.
frame_strideINT11–64In 'all_frames' mode, output every Nth frame within the trim range.
playback_fpsFLOAT24.00.1–240Preview playback speed (frames per second).
loop_modeCOMBOloopPreview playback at end of trim range: once / loop / ping-pong.
crop_enabledBOOLEANfalseEnable the drag-crop rectangle on the preview.
crop_lockedBOOLEANfalseLock the crop rect to prevent accidental drags. Press R on the canvas to reset.
aspect_ratioCOMBOfreeAspect lock. 'original' = source W:H. 'custom' = custom_aspect_w:custom_aspect_h.
custom_aspect_wFLOAT16.00–999Custom aspect width (used when aspect_ratio = custom).
custom_aspect_hFLOAT9.00–999Custom aspect height (used when aspect_ratio = custom).
crop_xFLOAT0.0000–1Crop left edge as fraction of source width [0..1]. Set by dragging the rectangle on the preview.
crop_yFLOAT0.0000–1Crop top edge as fraction of source height [0..1].
crop_wFLOAT1.0000.001–1Crop width as fraction of source width (0..1].
crop_hFLOAT1.0000.001–1Crop height as fraction of source height (0..1].
resize_methodCOMBOnonePost-crop resize. 'lanczos' = high-quality.
target_widthINT00–8192Target width after crop (0 = keep crop width).
target_heightINT00–8192Target height after crop (0 = keep crop height).
upscale_factorFLOAT1.000.1–8Multiplier applied AFTER target_width/target_height (1.0 = no upscale).
preview_widthINT48096–1920Width (px) of preview frames sent to the browser. Lower = lighter UI; full-resolution IMAGE outputs are unaffected.
preview_formatCOMBOpngpng = lossless, exact colors (recommended). jpeg = smaller payload, slight chroma loss. The IMAGE outputs are always the full-precision source tensor regardless of this setting.
preview_qualityINT9530–100JPEG quality (ignored when preview_format=png).

Outputs (19)

NameTypeDescription
frameIMAGESingle full-resolution frame at the slider position (1,H,W,C) - pre-crop, pre-resize. Full source precision (no JPEG re-encode).
frame_indexINTEcho of the selected frame_index (clamped to trim range).
frame_countINTTotal number of frames in the input batch.
processedIMAGEProcessed output: the selected frame OR the trimmed/strided batch (per output_mode), with crop + resize + upscale applied. Full source precision.
out_widthINTWidth (px) of the processed output.
out_heightINTHeight (px) of the processed output.
crop_x_pxINTCrop left edge in source pixels.
crop_y_pxINTCrop top edge in source pixels.
crop_w_pxINTCrop width in source pixels.
crop_h_pxINTCrop height in source pixels.
trimmed_countINTNumber of frames emitted on 'processed' after trim+stride (1 in current_frame mode).
playback_fpsFLOATEcho of playback_fps (handy as input to video savers).
frames_trimmedIMAGETrimmed source batch (frame_start..frame_end inclusive, with stride). NO crop/resize applied. Use this to feed downstream video savers without losing source resolution.
trim_start_idxINTResolved trim start frame index.
trim_end_idxINTResolved trim end frame index (inclusive).
widthINTSource width in pixels.
heightINTSource height in pixels.
durationFLOATTotal duration of the trimmed range in seconds (trimmed_count / playback_fps).
video_infoSTRINGJSON string with all video metadata: width, height, fps, duration, frame_count, trim_*, crop_*, etc. Wire to a Show Text node or any downstream automation.