GIFはフレームごとに待ち時間を保存します
GIF89aのGraphic Control Extensionは、0以外の遅延を1/100秒単位で保存します。1単位は10msです。Moyoutilは各フレームの1000/FPS msを同梱のgifenc 1.0.3へ渡し、エンコーダーは10で割って丸めます。15FPSの約66.667msは7単位、70msになります。選択したFPSはフレーム抽出の設定であり、そのままGIFに保存されるFPS値ではありません。
1秒を選択したときの保存合計を再現する
同じGIFワーカーコードとエンコーダーで1×1pxの仮想フレームを生成し、遅延フィールドを読みました。1秒・5FPSは5フレーム×200ms=1000ms、10FPSは10×100ms=1000ms、15FPSは15×70ms=1050msでした。これはテストGIFの保存値です。実際の動画変換やプレーヤーの再生時間測定ではありません。以下の計算コードは同じ数値を再現します。
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 1050フレーム数はceil(長さ×FPS)です。0.1秒・15FPSは2フレームとなり、保存遅延の合計は140msです。現在のGIF画面は5・10・15FPSを提供し、最大10秒・150フレームです。タイミングが重要なら、出力ファイルを使用予定のプレーヤーで確認してください。この計算だけで全プレーヤーの再生時間や変換処理時間は予測できません。
よくある質問
15FPSを選ぶと1秒は必ず1.05秒で再生されますか?
いいえ。1050msはこの1秒・15フレームの例の保存遅延合計です。実際の表示タイミングは別途検証が必要で、この記事ではプレーヤー別の再生時間を測定していません。