MVEx Frame Range Mask
Solid Masks for the Frames You Actually Want to Inpaint
- masks
Sometimes the mask you need isn't a subject at all - it's "these frames, this whole rectangle, nothing else." Say you want to inpaint a stretch of a clip where something ugly passes through, or regenerate a temporal range in a latent without touching the rest of the timeline. MVEx Frame Range Mask builds exactly that: a batch of solid masks, fully masked (1) on the frames you list and empty (0) everywhere else, at whatever resolution you ask for.
This is the pack's "make a mask by hand, in time" utility. The README frames it as useful for masking a stretch of a clip for inpainting, or for feeding a temporal mask straight into Mask To Latent Space - it's the manual-temporal counterpart to Mask Cleanup's automatic-temporal filtering.
The inputs
Four widgets, all dead simple:
- width / height (default 832×480) - mask resolution in pixels.
- frames (default 81) - how many masks in the batch.
- ranges (default
0:24) - the interesting one. It speaks Python slice syntax, which takes a beat to get used to and then feels right:0:24masks frames 0 through 23 - the stop is excluded, so an 81-frame clip needs0:81, not0:80-by-accident.5:or5:endruns to the end;:3starts at the beginning.-1is the last frame,5:-1stops one short of the end.- A bare number masks a single frame:
40. - An optional third field steps:
0::2is every other frame. - Comma-separate to combine:
0:24, 40, 100:end.
Output is masks - one mask per frame, torch tensors you can wire straight into an inpaint conditioning, a composite, or Mask To Latent Space. An empty ranges gives you an all-empty batch, which is occasionally exactly what you want as a starting point.
Where it fits
The obvious use is "inpaint frames 30–60 of this clip" without hunting through other nodes. The sneaky-good use is chaining it into MVEx Mask To Latent Space: a temporal mask that's solid across a stretch of frames, reduced to latent resolution with the correct VAE geometry, becomes a clean regenerate-this-stretch signal for Set Latent Noise Mask. That's a genuinely handy pattern for targeted temporal edits.
Install
It's in MaskVidExperiments, so it rides along with the rest of the pack. ComfyUI Manager (search "MaskVidExperiments") or:
cd ComfyUI/custom_nodes
git clone https://github.com/drozbay/MaskVidExperiments
then restart. No model files, no dependencies beyond ComfyUI's own, needs ComfyUI v0.15.0+.
The one thing that trips people is off-by-one on the slice stop. frames: 81 with a range of 0:81 is a full clip; 0:80 silently leaves the last frame unmasked. The node will throw if you reference a frame number outside the batch (a bare 120 on an 81-frame clip errors, as list indexing would), but a slice stop beyond the end just clamps, Python-style - so double-check long ranges against your actual frames value. Small node, small surface, but it's the difference between a clean temporal mask and staring at a frame you forgot to mask.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 8321–16384 | Mask width in pixels. |
| height | INT | 4801–16384 | Mask height in pixels. |
| frames | INT | 811–16384 | Frames in the batch. |
| ranges | STRING | 0:24 | Frames to mask, comma-separated. Ranges are Python slices written start:stop, with the stop frame excluded, so 0:24 masks frames 0 to 23. Leave a side out to run to the start or the end (5:, :3), or write 5:end for the same thing. Negative numbers count back from the end, so -1 is the last frame and 5:-1 stops one short of it. A bare number masks a single frame, an optional third field steps (0::2 is every other frame), frame numbers start at 0, and an empty list gives an empty mask. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| masks | MASK | One mask per frame. |