Load Video [BETA]
Drag a video into ComfyUI and get frames, audio, fps — without ffmpeg gymnastics
- frames
- audio
- fps
- frame_count
Video work in ComfyUI has a classic annoyance: getting the video into the graph. The stock Load Image won't touch it, most video loaders want files pre-split into frames, and nobody wants to babysit ffmpeg before every test. LoadVideoNode (display name Load Video [BETA]) skips all that - drag a file onto it, or hit the upload button, and it decodes the video server-side into a batch of frames with audio, fps, and frame count riding along. It's from DemonAlone-JS_Addon-ComfyUI, the JS companion pack to the author's main DemonAlone-nodes repo.
How it works
Two pieces talk to each other. The backend adds three HTTP endpoints: /uploadvideo for drag-and-drop, /get_video_metadata for instant fps/frame-count reads, and /inputvideo for the built-in preview player that sits right on the node. The decoding itself is PyAV (import av) - not ffmpeg calls you run by hand, a proper Python binding - pulling frames through frame.to_image(), normalizing them to float tensors, and stacking them into an IMAGE batch. Audio, when present, is decoded into a waveform tensor plus its sample rate.
The preview player is the underrated part: it's a real <video> element on the node, so you can scrub the source before you even run anything.
The inputs
video- a dropdown of video files in ComfyUI's input folder (root input, same place your images go). MP4, AVI, MOV, MKV, and WebM are supported. The upload button and drag-and-drop both drop files there.max_frames- caps how many frames get decoded.0means all of them. This is your memory lever.
The outputs
Four, which is generous for a loader:
frames- the decoded video as anIMAGEtensor, shape[N, H, W, C].audio- anAUDIOdict withwaveformandsample_rate, orNoneif the file has no audio track. Wire it into VideoMakerNode or anything that consumes audio.fps- the video's frames-per-second as a float, so downstream nodes can time things correctly.frame_count- the actual number of frames loaded aftermax_framescropping, not the source's total. If you crop, this reflects reality.
Installing it - and the PyAV gotcha
cd ComfyUI/custom_nodes
git clone https://github.com/DemonAlone/DemonAlone-JS_Addon-ComfyUI
Restart, or grab "DemonAlone-JS_Addon-ComfyUI" from ComfyUI Manager. Now the catch: this node imports av (PyAV), but the pack ships no requirements.txt. A fresh install that has everything else working can still hit ModuleNotFoundError: No module named 'av' the moment it loads. The fix is one line:
pip install av
(Use the same Python environment as your ComfyUI install.) The other video nodes in this pack don't need it - they encode in the browser - so this is the only one with a real external dependency hiding in it.
Where people get burned
The memory one is the big one. Decoding happens eagerly: every frame is a float tensor in RAM, so a long 1080p clip can eat several gigabytes before you've done anything with it. If a video run OOMs, max_frames is your first dial - you usually don't need all 3,000 frames to test a pipeline. The loader will happily take a 60fps file too, so check the fps output if your frame-based math looks off.
Also note audio isn't resampled or remuxed - you get the source's native sample rate, so a 48kHz file hands you 48kHz and downstream audio nodes need to cope. And while it decodes most common containers, exotic codecs will fail loudly with a "No video stream found" style error. For the everyday MP4/MOV/WebM pipeline though, it's the smoothest way in - one drag, and you're sampling frames or feeding a video-to-video model without touching a terminal.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| video | COMBO | 1 options: No video files found | |
| max_frames | INT | 00–1000000 | 0 = all |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| frames | IMAGE | Batch of video frames as images (torch.Tensor) [N, H, W, C] |
| audio | AUDIO | Dictionary with 'waveform' and 'sample_rate', or None if no audio |
| fps | FLOAT | Frames per second of the video (float) |
| frame_count | INT | Actual number of frames loaded, respecting the 'max_frames' limit |