UV Load Video
Get video frames into ComfyUI without a fight
- images
- metadata_json
- audio_ref
- width
- height
- fps
- frame_count
Every video workflow in ComfyUI bottoms out at the same place: you've got an .mp4 sitting on disk and you need it as a batch of frames the graph can chew on. UV_LoadVideo is that handoff. It decodes any file your ffmpeg build can read and hands you a proper IMAGE tensor plus a pile of metadata - no scripts, no separate frame-extraction step, no leaving the app.
The clever part is what it does not do. Most of the current video stack is latent-native: Wan, Hunyuan and LTX ship their own loaders that decode straight into latent space for one specific model (the KB's wan-video guide goes deep on that ecosystem). UV_LoadVideo works in plain pixel space, and that's both its limit and its point. Because it outputs ordinary images, the frames feed anything that eats images - img2img, AnimateDiff, IPAdapter, ControlNet preprocessing - and when you want to get back into a latent model you bridge with UV_ImageBatchToLatent. The README calls this "pixel video import" and calls it a deliberate V1 choice; model-native latent bridges are deferred to V2 nodes.
Mechanically it's simple and honest: ffprobe pulls stream info, imageio (backed by ffmpeg) decodes frame by frame, and everything lands as a float 0-1 tensor in [B,H,W,C] order. If your source has an alpha channel, it rides through as RGBA.
The inputs you'll actually touch:
path- absolute, or relative to wherever ComfyUI's working directory is (usually its install root, notoutput/).start_frame/frame_limit- skip ahead, then stop.frame_limitof 0 means "everything," which is what you want unless a clip is huge.fps_override- 0 means "trust the file." Set it when a source has a weird fps tag and you want a clean number downstream.resize_mode-none,fit,stretch. Fit letterboxes onto your target canvas; stretch ignores aspect ratio.
One trap before you get fancy: the resize is nearest-neighbor. It's fast and fine for downscaling or matching a model's native resolution, but it's not a quality scaler. Don't reach for it to upscale into a hi-res pass and expect detail back.
Outputs are where the node earns its keep: images (straight into a VAE encode, img2img, or a KSampler), metadata_json (a JSON string - drop it into a Show Text node to read fps, frame count, audio presence), audio_ref (the source path if the file has audio, empty string otherwise - wire it straight into UV_AudioMux or UV_SaveVideo's audio_path), plus plain width, height, fps and frame_count ints you can use for conditioning or logging.
audio_detect_only is a neat trick worth knowing: flip it on and the node only probes - you get an empty image plus the audio_present flag in metadata. It's the cheap way to check whether a source has sound before you commit to a full decode and plan a mux.
Install
This is the flagship node of the pack, and the pack installs like any custom node:
cd ComfyUI/custom_nodes
git clone https://github.com/GeekatplayStudio/ComfyUI-UniversalVideoIO
cd ComfyUI-UniversalVideoIO
pip install -r requirements.txt
Then restart ComfyUI. Dependencies are light - imageio, imageio-ffmpeg, numpy, torch - and torch is already present in any ComfyUI install. There are no model downloads; ffmpeg itself is resolved from your system PATH first and falls back to the imageio-ffmpeg bundled build.
Troubleshooting
The one real failure mode, and it's community-documented: "ffmpeg not found" after a ComfyUI update. The fix is the same as the general ComfyUI advice - make sure ffmpeg is on your PATH or let imageio-ffmpeg supply it (the pack does exactly this fallback). If a codec family is missing from your ffmpeg build (some Windows static builds skip libsvtav1 or prores_ks), the error shows up here as a decode failure - grab a fuller build. And remember: relative paths resolve against ComfyUI's working directory, so if a load "can't find" a file you're sure exists, check where you launched the process.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| path | STRING | — | |
| start_frame | INT | 00–1000000 | — |
| frame_limit | INT | 00–1000000 | — |
| fps_override | FLOAT | 0.000–1000 | — |
| resize_mode | COMBO | 3 options: none, fit, stretch | |
| resize_width | INT | 00–8192 | — |
| resize_height | INT | 00–8192 | — |
| keep_aspect_ratio | BOOLEAN | true | — |
| audio_detect_only | BOOLEAN | false | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| metadata_json | STRING | — |
| audio_ref | STRING | — |
| width | INT | — |
| height | INT | — |
| fps | FLOAT | — |
| frame_count | INT | — |