Load Video (Upload) (WepeNerd)
Wan wants 4n+1 frames — this loader hands them over without VHS
- images
- frame_count
- frame_rate
- audio
You have an mp4. You want an IMAGE batch. Between those two things sit two numbers that decide whether everything downstream works: how many frames you hand the model, and whether that count is legal for it. Wan Video wants 4n+1 (81 is the classic - about five seconds at 16fps), LTXV wants 8n+1, and feeding a video model 80 frames gets you either an error or silent padding. Neither is fun to debug at 3am.
Load Video (Upload) is the node that gets both right on the way in. It comes from WepeNerd's utility pack - the same author behind the LTX 2.3 Obscura Remova object-removal IC-LoRA - so it reads like something built for his own video work rather than a framework.
How it actually works
It decodes with PyAV, not VHS and not an external FFmpeg binary. That changes your install: ComfyUI already ships PyAV, so there's no "install ffmpeg and put it on your PATH" step.
Set frame_rate above zero and the node builds an FFmpeg filter graph (setpts + the fps filter, nearest rounding) to resample the timeline. That drops or duplicates frames - it never interpolates. Your clip stays exactly as fast as it was; you just get fewer samples of it.
The processing order is fixed, and the tooltips spell it out: frame rate → skip → every nth → cap → format trimming. The author's own example: rate 10, skip 2, nth 2, cap 3 gives resampled frames 2, 4 and 6, output rate 5fps. Set frame_rate to 0 and you keep every source frame untouched.
Then format does the useful part. Each preset carries a dimension multiple and a frame-count constraint, and the node rounds your dimensions to the nearest multiple and trims trailing frames to the largest valid count that doesn't exceed your cap.
| Preset | Dimension multiple | Frame count | |---|---|---| | None | 1 | any | | AnimateDiff | 8 | any | | Wan | 8 | 4n+1 | | LTXV | 32 | 8n+1 | | Hunyuan | 16 | 4n+1 | | Mochi | 16 | 6n+1 | | Cosmos | 16 | 8n+1 | | H3 | 32 | 17n+5 |
The catch: presets may trim your batch, and those two missing frames are the price of a legal length. The node tells you when the ask doesn't fit ("Too few selected frames for LTXV. Select more frames or use format None."). None preserves exactly what you selected.
The inputs worth touching
video is a dropdown plus an upload button, and it scans ComfyUI's input folder recursively for .mp4 .webm .mkv .mov .avi .m4v .gif. Drop a file in there and it appears.
frame_load_cap is the one that saves you. 1080p frames land in an IMAGE batch as float32 at roughly 24 MiB each, so an unglued 300-frame load is about 7GB of RAM before the sampler even starts. Cap it to your model's context - 81 for Wan - and use custom_width/custom_height to shrink further. Set only one of the two and the other follows to preserve aspect ratio, then rounds to the preset's multiple, so expect a pixel or two of aspect drift.
select_every_nth is a stride: the output frame_rate is your requested (or source) rate divided by it, which is why the node hands frame_rate back as an output at all.
Outputs and where they go
images is one RGB float32 batch - wire it into VAE Encode or a video model's image conditioning. frame_count is the actual count after trimming, for anything that has to agree with the batch length. audio is ComfyUI's standard AUDIO format (source channels and sample rate preserved, starting at your selected interval) - connect it to a video-combine/save node when you want sound, or flip load_audio off to skip decoding entirely.
And frame_rate: wire it to the frame-rate input of whatever saves your video. Skip this and a stride-2 load plays back at double speed. Every time.
Install
Through ComfyUI Manager, search the pack title ComfyUI-WepeNerd, or:
cd ComfyUI/custom_nodes
git clone https://github.com/WepeNerd/ComfyUI-WepeNerd.git
python -m pip install -r ComfyUI-WepeNerd/requirements.txt
That requirements file is small and honest: Pillow, numpy, av>=17.0.0. No models, no GPU wheels, no external runtimes. Restart ComfyUI and refresh the browser.
Where people get burned
The preview lies to you, by design. It autoplays the original file, muted and looping - not your sampled batch - and whether it plays inline depends on your browser's codec support. It's a "did the file upload?" indicator, not a render check.
Other real ones, straight from the node's own error strings: Video has no frame timestamps; use frame_rate = 0. (variable-rate or oddly muxed files), No frames selected. Reduce skip_first_frames or choose another video., and Video contains a corrupt frame. The file also has to be inside ComfyUI's input folder - the node refuses paths outside it, so a video on your desktop only works after it's uploaded.
And if you're migrating from VHS, the sampled frames won't always match: this node goes through FFmpeg's fps filter with nearest timestamp rounding, and VHS's OpenCV loader picks differently. Same clip, same settings, occasionally a different frame. Not a bug, just a different opinion.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| video | COMBO | 0 options: | |
| frame_rate | FLOAT | 0.000–240 | 0 keeps every source frame. Otherwise sample at this FPS, duplicating or dropping frames as needed. |
| frame_load_cap | INT | 00–2147483647 | Maximum selected frames to load. 0 loads all; large batches need more RAM. |
| skip_first_frames | INT | 00–2147483647 | Skip this many frames AFTER frame-rate conversion, before selecting every nth frame. |
| select_every_nth | INT | 11–2147483647 | Keep every nth remaining frame. The output frame rate is divided by this value. |
| format | COMBO | None | VHS dimension/frame-count constraints. May trim trailing frames. None preserves the selected count and dimensions. |
| custom_width | INT | 00–16384 | 0 uses source width, or preserves aspect ratio if only height is set. |
| custom_height | INT | 00–16384 | 0 uses source height, or preserves aspect ratio if only width is set. |
| load_audioopt | BOOLEAN | true | Output audio for the selected clip. Disable to skip audio decoding. Returns no audio if the file has no audio track. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| frame_count | INT | — |
| frame_rate | FLOAT | — |
| audio | AUDIO | — |