Nougan Duration → Frames ⏱️
Why your 5-second clip is 107 frames — duration to frames, without the math node
- frames
- seconds
- fps
Video models don't take seconds. They take frame counts. So every video workflow grows the same ugly tendril: a Float node holding a duration, a Math Expression node doing round(a*24), and a mental note that changing one breaks the other.
Nougan Duration → Frames ⏱️ collapses that into one node, with a twist that matters: some models don't accept arbitrary frame counts.
The 17n+5 thing
MiniMax H3 only takes lengths of 17n + 5 frames - 5, 22, 39, 56 and so on. Ask it for a clean 120 frames at 24 FPS and you get an error or a silently rounded clip, depending on your luck and your wrapper. The preset for it runs:
max(5, round(a * 24)) + (5 - (max(5, round(a * 24)) % 17)) % 17
Which is the polite way of saying "round up to the next 17n+5". That expression is why this node exists. Type 5 seconds, get 124 frames and change - not 120. It's not a rounding bug, it's the model's constraint expressed as arithmetic.
For everything else there are plain 24 FPS and 30 FPS presets (max(1, round(a * fps))), and a Custom mode.
What you set
duration - seconds, 0 to 3600, in tenths. That's the number you actually think in.
preset - the four choices above. Presets always run their own expression regardless of what's in the text box; only Custom reads your text.
expression - locked by default. Unlock it in the node's UI to edit, and the moment you do, the preset flips to Custom. Variables available: a for the duration, fps for the fps field. Functions: max min round abs ceil floor int float sqrt, plus the usual arithmetic and comparisons and a ternary. It runs through a sandboxed AST evaluator with a 300-character limit and a node budget, so it's arithmetic, not a Python shell - which is the right call for something people paste off the internet.
fps - 24 by default, used by Custom only, exposed to the expression as fps.
Outputs
frames(INT) - into your video sampler or the frame-count input of an image-batch node.seconds(FLOAT) - the round-tripped duration, useful for slapping on a comment node or naming a file.fps(INT) - the fps the expression used. Wire it into Nougan Save Video 🎬 or Nougan GIF Maker 🎞️ and the video can't disagree with the frame count about how long it is.
That last output is the quiet quality-of-life win. Mismatched fps between the generator and the saver is how a 5-second clip becomes a 3-second one that looks like everyone is sprinting.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Winnougan/Nougan_Nodes
# restart ComfyUI
Or ComfyUI Manager → search "Nougan". Nothing else to install, no models. The node's live preview and lock button come from its JS file, so hard-refresh (Ctrl+F5) after restarting, or you'll get the plain widget and wonder where the buttons went.
Where people get burned
"Custom" behaves oddly. Editing the expression switches the preset to Custom for you - that's the intent, and it's why the box is locked to begin with. If a tutorial's expression seems to be ignored, check the preset isn't still on a named one.
Feed H3 a number that isn't 17n+5. The sampler complains, or worse, silently trims. Use the preset and stop doing frame math by hand.
Rounding drift. round() on the duration means 4.9 and 5.0 seconds can land on the same frame count. If you care about exact per-frame timing, remember the model's constraint is coarser than a tenth of a second - you're choosing a length the architecture accepts, not the length you typed.
One node, one frame count. If you need three different segment lengths for a multi-shot clip, you'll want three of these - or just set the durations as inputs and let the formula do its job.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| duration | FLOAT | 6.00–3600 | Length in seconds. Available to the expression as 'a'. |
| preset | COMBO | MiniMax H3 (24 FPS) | Presets always run their own expression. Pick Custom to use your own. |
| expression | STRING | max(5, round(a * 24)) + (5 - (max(5, round(a * 24)) % 17)) % 17 | Locked by default. Unlock it in the node to edit; editing switches the preset to Custom. |
| fps | INT | 241–240 | Only used by Custom (available to the expression as 'fps'). Presets set their own. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| frames | INT | — |
| seconds | FLOAT | — |
| fps | INT | — |