GIF stores a waiting time for each frame
The GIF89a Graphic Control Extension stores nonzero delays in hundredths of a second: one unit is 10 ms. Moyoutil sends 1000/FPS ms per frame to its bundled gifenc 1.0.3 encoder, which divides by 10 and rounds. At 15 FPS, approximately 66.667 ms becomes 7 units, or 70 ms. The selected FPS controls frame sampling; it is not an FPS number stored unchanged in the GIF.
Reproduce the stored total for a one-second selection
We generated synthetic 1×1 px frames with the same GIF worker code and encoder, then read their delay fields. One second at 5 FPS produced 5 frames × 200 ms = 1000 ms; 10 FPS produced 10 × 100 ms = 1000 ms; 15 FPS produced 15 × 70 ms = 1050 ms. These are stored values in the generated test GIFs. This experiment did not convert an actual video or measure a player’s playback time. The calculation below reproduces the same numbers.
for (const fps of [5, 10, 15]) {
const frames = Math.ceil(1 * fps);
const delayMs = Math.round(1000 / fps / 10) * 10;
console.log(fps, frames, delayMs, frames * delayMs);
}
// 5 5 200 1000
// 10 10 100 1000
// 15 15 70 1050Frame count is ceil(length × FPS). A 0.1-second selection at 15 FPS therefore produces 2 frames with a stored delay total of 140 ms. The current GIF interface offers 5, 10 and 15 FPS, with limits of 10 seconds and 150 frames. For timing-sensitive work, check the output file in the player you plan to use. This calculation cannot predict every player’s playback time or how long conversion takes.
Frequently Asked Questions
Does choosing 15 FPS always make one second play for 1.05 seconds?
No. The 1050 ms total is the sum of stored delays for this one-second, 15-frame example. Actual display timing needs separate verification; this article does not measure playback time across players.