Load Video + Crop
A WYSIWYG crop box on the actual video, before you ever queue
- VIDEO
- FULL FRAME
- CROPPED FRAME
ComfyUI got serious about video, which means you spend a lot of time pointing it at footage that was never shot for whatever model you're feeding. Source clips need reframing to a target aspect ratio and trimming to the exact window you want to extend or edit. Do that outside the graph and you're babysitting ffmpeg command lines. Do it with frame-level image nodes and you're decoding the whole clip into RAM and cropping blind - no preview of what the workflow will actually see until it runs.
Load Video + Crop (class LoadVideoCrop, from the domg73/ComfyUI-LoadVideoCrop pack) is a drop-in replacement for the core Load Video node that kills the blind part. Same file picker, same drag-and-drop, same native <video> preview - but now with a real crop rectangle drawn on top of the playing footage. You frame it, you see the exact output dimensions printed on the frame, and what you frame is what executes.
How it works
Aspect ratio defaults to Original, and in that mode the node is a pure pass-through: literally the core Load Video output, uncropped, no box drawn. Pick any locked ratio - 1:1, 2:3, 3:2, 3:4, 4:3, 9:16, 16:9, 21:9 - and the rectangle appears. Drag to move it; hover and scroll to zoom, always around your cursor. The crop is static: every frame gets the same rectangle, which is exactly what reframing needs. The box lives in the workflow as normalized 0–1 floats on hidden crop_x / crop_y / crop_w / crop_h inputs, so an API script can set an arbitrary rectangle too - handy, because the UI only offers presets.
The neat part is what doesn't happen when you queue. The node decodes nothing up front: the cropped video is a lazy object that streams decode → crop → encode from the source file only when a downstream consumer asks for it, so peak memory stays around one frame no matter how long or high-res the clip. Tensor consumers (like core Get Video Components) materialize only the cropped region. Output dimensions are even-aligned for the x264/yuv420p encoder.
Trim, stills, and the outputs
Since v1.0.1 there's an editor-style trim timeline under the preview: a filmstrip of real frames, an audio waveform, and draggable mark-in/mark-out markers (keyboard I / O set them; playback loops inside the window). It's display-only - it edits the same hidden start_time / duration / strict_duration values with the core Trim Video semantics: negative start counts from the end, 0 duration means "to the end," and strict_duration: true makes the node fail instead of clamping a short clip.
Three outputs come off the node. VIDEO is the trimmed, cropped clip. FULL FRAME and CROPPED FRAME are plain IMAGEs of whatever frame the preview is showing (pinned by the hidden frame_time widget, so a paused player gives a stable still) - the same pixels the 💾 Frame button saves. Pause on the frame you want and wire CROPPED FRAME straight into your I2V conditioning. One gotcha: the Frame button saves PNGs as browser downloads, not into ComfyUI/output.
Installing it
ComfyUI Manager (search Load Video + Crop or the pack title), or the manual way:
cd ComfyUI/custom_nodes
git clone https://github.com/domg73/ComfyUI-LoadVideoCrop
Then restart ComfyUI. No extra dependencies and no model downloads - PyAV, numpy and torch all ship with ComfyUI's own video support. One real requirement: the pack registers through the newer comfy_api extension entry point (there's no NODE_CLASS_MAPPINGS in the repo), so you need a reasonably current ComfyUI - on an old build it simply won't show up. It was written to work in both the classic canvas and the Nodes 2.0 Vue frontend - a quiet achievement, given that same rewrite broke a lot of third-party packs.
Where people get burned
- Crop plus an exotic source errors out. The v1 streaming path handles 8-bit SDR only. Rotated phone footage (rotation metadata), 10-bit, and HDR sources raise a clear error at save time when you crop. Set aspect ratio to Original to use the untouched core path, or re-encode the source first.
- Output dims can be a pixel or two off your drawn box. That's the even alignment for the encoder, not a bug in your drag.
- No custom ratio in the UI. The list is fixed; arbitrary boxes only via the hidden crop floats from a script.
- The overlay tracks the DOM. It's positioned over the core preview and coupled to its markup, so a frontend update could knock it loose. Keep ComfyUI current; if the box stops tracking after an update, that's a bug report for the author, not a sign you broke your install.
Brand-new (v1.0.1 as of this week), thoughtful, and honest about its limits. If you feed video into generative workflows, this is the Load Video you'll probably want on the canvas.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| file | COMBO | 0 options: | |
| aspect_ratio | COMBO | Original | 9 options: Original, 1:1 (Square), 2:3 (Portrait Photo), 3:2 (Photo), 3:4 (Portrait Standard), 4:3 (Standard), +3 |
| crop_x | FLOAT | 0.00000–1 | — |
| crop_y | FLOAT | 0.00000–1 | — |
| crop_w | FLOAT | 1.00000–1 | — |
| crop_h | FLOAT | 1.00000–1 | — |
| start_time | FLOAT | 0.000-100000–100000 | Trim: start time in seconds (negative = from the end; 0 = no trim). |
| duration | FLOAT | 0.000 | Trim: duration in seconds, or 0 for unlimited duration. |
| strict_duration | BOOLEAN | false | If True, raise an error when the requested duration cannot be fully satisfied. |
| frame_time | FLOAT | 0.0000–100000 | Seconds in the file: the frame the preview is showing, output as the two images. Kept in sync by the frontend; set manually to export a specific moment. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| VIDEO | VIDEO | — |
| FULL FRAME | IMAGE | The frame the preview is showing, full resolution (stable while the player is paused). |
| CROPPED FRAME | IMAGE | The previewed frame cropped to the aspect-ratio box (identical to the full frame in Original mode). |