Video Trimmer (Buff)
Cut the junk out of your generated clips without leaving ComfyUI
- video
- images
- audio
- images
- audio
- fps
- frame_count
- trim_info
Every video workflow hits the same wall eventually: you generate a clip, and half of it is junk. Warm-up frames where the motion hasn't settled, two seconds of dead air at the start, a tail that drifts into mush. The usual fix is to leave ComfyUI and open an editor, which is a pain mid-graph. Video Trimmer - the one node in the tiny ComfyUI_VideoCutter pack - plugs that hole directly in the graph: Load Video -> Video Trimmer -> Save Video. It takes a native ComfyUI VIDEO object, cuts it by time or by frame number, and hands you back another VIDEO that your existing save/encode node will happily eat.
This matters more than it sounds, because ComfyUI is the only local tool where chaining video models, conditioning, and post-processing in one graph is even practical. If you've ever had to drop a clip to an external cutter, cut it, and re-import just to shave off filler frames, you know the friction. This node removes that round-trip.
How it actually works
The key detail is that it trims in memory, not by re-encoding. It grabs the decoded components of the incoming VIDEO (frames tensor, audio, metadata, frame rate), converts your time or frame inputs into a frame slice, cuts the tensor, and rebuilds a fresh VIDEO object. Audio is sliced to match - it converts the frame range to audio samples using the frame rate and sample rate so the soundtrack stays in sync. No file-system round-trips, no ffmpeg dependency, no model downloads. It's about as lightweight as a node gets.
That simplicity has one real requirement, though: the node imports comfy_api.latest from ComfyUI core to access the native VIDEO API. If your ComfyUI is old enough to lack that, the node fails at load with a clear import error. Keep ComfyUI updated and you're fine.
The inputs that matter
You'll set two things in practice: trim_mode (a toggle, time or frames) and the matching start/end pair.
trim_mode-"time"is the default and the friendly one. Switch toframeswhen you want surgical precision.start_time/end_time- seconds as floats. Setend_timeto0to cut fromstart_timeto the very end.start_frame/end_frame- integers, same deal:end_frame = 0means "everything to the end."
One trap: the end values are exclusive, which matches Python slicing. end_frame = 192 with start_frame = 48 keeps frames 48 through 191, not 192. Don't be the person who wonders why their last frame vanished.
Outputs
The star is trimmed_video (VIDEO), which wires straight into your Save Video node. The rest are metadata you mostly don't need but are nice for validation: duration_seconds, frame_count, and the resolved_start_frame / resolved_end_frame - the actual frames used after clamping. If you're chaining automated workflows, those resolved values are how you confirm the cut landed where you thought.
Installing it
Via ComfyUI Manager, search for ComfyUI_VideoCutter and install. Or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/benjamin-bertram/ComfyUI_VideoCutter
Then restart ComfyUI and look for Video Trimmer under the Video Editing category. There are no dependencies, no requirements.txt, no models to fetch. One stale README detail: it tells you to put the folder in as ComfyUI_VideoCutter_CodexAPP, which is an artifact of the author's dev machine - the clone lands as ComfyUI_VideoCutter and works fine.
Troubleshooting
- Node shows up red / won't import: your ComfyUI predates the native
VIDEOAPI. Update ComfyUI core. - Errors about empty videos, missing frame rate, or malformed tensors: the input isn't a proper decoded
VIDEO. It has to come from a node that outputs the native type - typicallyLoad Video. - "Invalid trim range": your start is past your end, or off the end of the clip. Fix the numbers.
- No audio after trimming: only happens if the source
VIDEOhad no audio track to begin with; the node preserves it when present, not when absent.
It's a small, niche node from a one-custom-node pack - don't expect a big community around it. But for the specific job of cutting generated footage down to the good part without breaking your graph, it's exactly the tool you reach for. The name isn't a lie: it trims video. That's all it does, and that's enough.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| trim_mode | COMBO | last_n | Trimming mode: • all: Keep entire video (useful for pure framerate conversion/resampling) • start_duration: Trim starting at 'start_value' for duration 'duration_or_count' • start_end: Trim between 'start_value' and 'end_value' • first_n: Extract first N units (frames/seconds) • last_n: Extract last N units (frames/seconds) • center_n: Extract center N units around the midpoint • cut_inside: Remove segment between start_value and end_value, splicing remaining parts |
| trim_units | COMBO | source_frames | Units for trim parameters: • seconds: Real-world time in seconds • source_frames: Frame count / indices based on source framerate • output_frames: Frame count based on target output framerate • percentage: 0% to 100% (or 0.0 to 1.0) of the video duration |
| start_value | FLOAT | 0.00-100000–100000 | Start position (can be negative to index from the end, e.g., -2.0s or -48 frames). |
| duration_or_count | FLOAT | 24.000–100000 | Length/count to extract (0 = until the end of video in start_duration mode). |
| end_value | FLOAT | 0.00-100000–100000 | End position for start_end / cut_inside modes (0 = end of video; negative = offset from end). |
| source_fps | FLOAT | 24.000.01–1000 | Source video framerate. Auto-detected when native 'video' input is connected unless overridden. |
| framerate_mode | COMBO | keep_source | Framerate / resampling mode: • keep_source: Preserve source framerate • custom_fps: Resample frames to target_fps while preserving real-world playback speed and audio sync • multiplier: Multiply source framerate by fps_multiplier • target_frame_count: Produce exact target_frame_count output frames (auto-calculates output fps) |
| target_fps | FLOAT | 24.000.01–1000 | Target framerate used when framerate_mode is 'custom_fps'. |
| fps_multiplier | FLOAT | 1.000.01–100 | Framerate scaling factor used when framerate_mode is 'multiplier' (e.g., 0.5 = half fps, 2.0 = double fps). |
| target_frame_count | INT | 241–100000 | Exact number of output frames when framerate_mode is 'target_frame_count'. |
| interpolation | COMBO | nearest | Frame interpolation method: • nearest: Frame skipping/duplication (crisp, zero motion blur/ghosting) • linear: Linear blend between adjacent frames • cubic: Smooth cubic interpolation |
| loop_mode | COMBO | clamp | How to handle boundary frames (clamp to edge, repeat, or mirror). |
| videoopt | VIDEO | Optional native ComfyUI Video object (e.g. from LoadVideo or CreateVideo). | |
| imagesopt | IMAGE | Optional batch of images [B, H, W, C]. | |
| audioopt | AUDIO,VHS_AUDIO | Optional audio track (ComfyUI AUDIO dict or VHS_AUDIO). |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| audio | AUDIO | — |
| fps | FLOAT | — |
| frame_count | INT | — |
| trim_info | STRING | — |