TS Video Loader
A video loader with a timeline, so a two-second cut doesn't cost an hour
- images
- audio
- video_info
- video
Most video loaders in ComfyUI are a file picker and a prayer: load the whole thing, then trim with numbers. TS Video Loader is the version you'd build if you had time - it reads a video into frames, audio and a compact metadata bundle, and lets you pick the piece visually, on a timeline that lives inside the node.
The node's body holds a player and a timeline with a filmstrip. Drag the handles to set in and out, zoom into a single second of an hour-long take (Ctrl/Cmd + wheel), loop the selection while you judge it, type an exact timecode when the mouse isn't precise enough. If the file has audio, the waveform is drawn under the filmstrip - a beat or a spoken word is far easier to hit by the wave than by the picture. And the player follows whichever handle you're dragging, so the exact frame that becomes the first or the last is on screen while you're still choosing it.
Fast on purpose
This is where the loader separates from the pack. All resizing, rotation and colour conversion happen inside the decoder's own filter graph, and reading stops at the end of your selection. The README's numbers: a two-second cut from an hour-long 4K take costs a seek plus two seconds, not an hour. Measured at 0.43 seconds where the naive path - decode the whole thing at full resolution, then resize - takes 5.9 seconds and 6.4 GB of memory. The frame_rate resampling works by real timestamps, so a variable-frame-rate source comes out evenly spaced instead of drifting.
The inputs that matter
source_path- the file. Drag and drop from the file manager or another node's preview, paste, or type a path anywhere on the ComfyUI machine.start_seconds/end_seconds- the selection.end_secondsof -1 means "until the end of the file."frame_rate- output rate; 0 keeps the source rate. Fractional rates like 23.976 work.longer_side/shorter_side- sizing. Set one, the other derives from it (0 means "derive me"), so one graph fits landscape and portrait footage alike.divisible_byrounds down to what video models want (8, 16, 32).max_frames- hard cap on loaded frames, 0 means no cap; the memory guard.resize_filter-area(default) suits strong downscaling,lanczoskeeps edges sharp,neighboris for pixel art.when_too_large- what to do when the frames won't fit in RAM (the ceiling is 60% of the machine's memory, at least 8 GB):stoprefuses with a message naming the size, oruse diskputs frames in a memory-mapped file in the temp folder so the allocation can't fail - at the price of disk traffic (measured: 31.9 GB took 92 s on disk against 51 s in RAM).
Outputs
images- the decoded frames, float32 in 0..1.audio- the same time range's audio, or nothing at all when the file has no track (silence would quietly overwrite a real track downstream).video_info- the metadata bundle; feed it toTS Video Infoto get the numbers.video- the trimmed source file itself, no resizing or rate change, as a cheapVIDEOreference for nodes that take video.
Installing it
Part of comfyui-timesaver: ComfyUI Manager → search Timesaver, or
cd ComfyUI/custom_nodes
git clone https://github.com/AlexYez/comfyui-timesaver
cd comfyui-timesaver
python -m pip install -r requirements.txt
then restart ComfyUI. No system ffmpeg needed - the pack ships imageio-ffmpeg's static binary.
Gotchas
One security note worth reading: on a localhost ComfyUI (127.0.0.1), this node and its preview can read any path you give it - that's the point, nothing gets copied into input. But if you run ComfyUI open to a network (--listen 0.0.0.0), the preview is served over HTTP to whoever can reach that port, so the loader then stays inside your home folder and ComfyUI's own directories. Owners of the machine can widen that with TS_MEDIA_EXTRA_ROOTS or lift it with TS_MEDIA_ALLOW_ANY_PATH=1 - set on the machine, not in a workflow, since workflows can arrive from anyone.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| source_path | STRING | Video file. Pick or drop one in the node's own interface; a path to a file on the ComfyUI machine works too. | |
| start_seconds | FLOAT | 0.0000–1000000 | Start of the clip. Drag the left handle on the timeline. |
| end_seconds | FLOAT | -1.000-1–1000000 | End of the clip. -1 means "until the end of the file". Drag the right handle on the timeline. |
| frame_rate | FLOAT | 0.0000–240 | Output frame rate. 0 keeps the source rate. Fractional rates such as 23.976 are allowed. |
| max_frames | INT | 00–1000000 | Hard cap on the number of loaded frames. 0 means no cap. It trims the tail of whatever the timeline selected, after the frame rate and the frame step have been applied — the node's status line always shows how many frames actually come out. |
| longer_side | INT | 00–16384 | Length of the longer side of the frame. 0 derives it from the shorter side, keeping the aspect ratio. Works the same on landscape and portrait footage. Resizing happens inside the decoder, not afterwards. |
| shorter_side | INT | 00–16384 | Length of the shorter side. 0 derives it from the longer one. |
| divisible_by | INT | 11–64 | Round the output size down to a multiple of this value. Video models usually want 8, 16 or 32. |
| frame_step | INT | 11–1000 | Keep every Nth frame after the frame-rate stage. 1 keeps them all. |
| resize_filter | COMBO | area | Scaling filter. area suits strong downscaling, lanczos keeps edges sharp, neighbor is for pixel art. |
| when_too_largeopt | COMBO | stop | What to do when the frames will not fit in RAM. The ceiling is 60% of the machine's memory (at least 8 GB), or whatever TS_VIDEO_MAX_BYTES says. • stop (default) — refuse with a message naming the size, so nothing quietly starts paging. • use disk — put the frames in a memory-mapped file in the ComfyUI temp folder. What comes out is an ordinary IMAGE tensor, and the allocation cannot fail outright however big the clip is. Be honest about the cost: decoding writes every frame once, so memory still climbs towards the full size while it runs (measured: a 31.9 GB clip took 92 s on disk against 51 s in RAM). What you gain is that those pages are backed by a real file, so the system can drop them instead of failing, and downstream only the frames a node touches are read back. Make sure the temp drive has room; the file goes away when the run releases the tensor, and leftovers are swept on the next decode. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | Decoded frames [B,H,W,C], float32 in 0..1. |
| audio | AUDIO | Audio for the same time range. Nothing at all when the file has no audio track — silence would quietly overwrite a real track further down the graph. |
| video_info | TS_VIDEO_INFO | Metadata bundle. Feed it into TS Video Info to get the numbers. |
| video | VIDEO | The trimmed source file itself, without resizing or frame-rate change. A cheap reference for nodes that take VIDEO. |