動画から静止画を取り出すのはFFmpegの最も便利な使い方の一つです。コンタクトシートの作成、サムネイル用のきれいな1枚の取得、別ツールに渡すためのフレーム書き出しなど。FFmpegならフレームをPNGやJPGとして書き出すことができ、全フレーム、1秒ごとなど一定間隔、あるいは正確なタイムスタンプでの1枚、と自由に選べます。本記事ではそれぞれの方法と、重要な画質設定を解説します。所要時間:7分。

動作確認: FFmpeg 8.1


この記事でわかること

  1. タイムスタンプ指定で1枚キャプチャする方法(実行可能)
  2. fps で1秒ごとに1フレーム抽出する方法
  3. 全フレームを画像シーケンスとして書き出す方法
  4. PNGとJPGの使い分けと画質の制御
  5. 抽出と同時にリサイズする方法
  6. トラブルシューティングとFAQ

1. 1枚だけキャプチャする

最も多いニーズは、良い静止画を1枚得ることです。フィルタでフレームを選び、最初の1枚で停止します。

ffmpeg -i input.mp4 -vf fps=1 -frames:v 1 output.png
  • -vf fps=1 … 1秒あたり1フレームでサンプリング
  • -frames:v 1 … 最初に一致したフレームだけを書き出す
  • output.png … 1枚のPNG画像

特定の瞬間のフレームを取りたい場合は、入力の前にシークします。これは5秒地点のフレームを取り出します。

ffmpeg -ss 00:00:05 -i input.mp4 -frames:v 1 output.png
オプション意味
-ss 00:00:05読み込み前に5秒へシーク
-frames:v 1正確に1フレームだけ出力
-vf fps=11秒あたり1フレームをサンプリング

-iでのシークは高速で、最近のFFmpegではデコード/トランスコード時には正確でもあります。FFmpegはまず近くのキーフレームへジャンプし、そこからデコードして既定で目的のフレームちょうどに到達します。-i の後ろの出力側 -ss も同じフレームに届きますが、先頭からデコードするため遅くなります。そのため、フレーム抽出では入力側 -ss の方が一般に有利です。Seeking wiki を参照。


2. 1秒ごとに1フレーム抽出する

動画を一定間隔の静止画群にするには、fps でサンプリングして連番で書き出します。

ffmpeg -i input.mp4 -vf fps=1 output_%04d.png

これで output_0001.pngoutput_0002.png… と、動画の1秒ごとに1枚の画像が生成されます。

  • -vf fps=1 … 1秒あたり1フレーム(5秒ごとなら fps=1/5、毎秒2枚なら fps=2
  • output_%04d.png%04d がゼロ埋めの連番になる

%04d シーケンスをプレーンテキストで示しているのは、連番をそのまま打つのではなく実行時にFFmpegが埋めるためです。


3. 全フレームを書き出す

すべてのフレームを画像として書き出すには(コマ送り確認や別パイプラインへの入力用)、レート指定のフィルタを付けません。

ffmpeg -i input.mp4 output_%04d.png

これでフレームごとに1枚のPNGが書き出されます。30fpsのクリップなら動画1秒あたり30枚になり、すぐに膨れ上がるのでディスク容量に注意してください。

目的フィルタ結果
全フレーム(なし)全フレームを画像化
1秒ごと-vf fps=11枚/秒
5秒ごと-vf fps=1/51枚/5秒
毎秒2枚-vf fps=22枚/秒

4. PNGとJPGと画質

PNGは無劣化で、ピクセル完全なフレームが必要なときに最適です。JPGははるかに小さく、プレビューには十分です。JPGで1枚書き出して画質を制御するには:

ffmpeg -ss 00:00:05 -i input.mp4 -frames:v 1 -q:v 2 output.jpg
  • -q:v 2 … JPG画質(2は高画質。2〜31のスケールで、小さいほど高画質)
形式サイズ画質向いている用途
PNG無劣化編集・保存・透過
JPG非可逆プレビュー・コンタクトシート・Web

スマートなフレーム選択で仕上げる1枚のサムネイルはサムネイル抽出ガイドを参照してください。


5. 抽出と同時にリサイズする

scale をフレーム選択と組み合わせれば、小さい画像を直接書き出せます。これは5秒地点のフレームを取り、幅640pxにスケールします(高さは比率を保って自動)。

ffmpeg -ss 00:00:05 -i input.mp4 -vf scale=640:-1 -frames:v 1 output.png
  • scale=640:-1 … 幅を640に、-1 でFFmpegがアスペクト比を保つ高さを計算

フィルタは連結できます。例えば -vf "scale=640:-1,fps=1" でリサイズとサンプリングを同時に行えます。


6. トラブルシューティング

症状1: 複数欲しかったのに画像が1枚しか出ない

原因: 出力名に %04d パターンが無く、各フレームが同じファイルを上書きした。 解決策: シーケンスにするには出力名に %04d(または同様の連番)を含めます(第2章)。

症状2: 抽出したフレームが狙った瞬間から少しずれる

原因: フレーム抽出(デコードを伴う)では、最近のFFmpegの入力側 -ss は通常は正確で、目的のフレームちょうどまでデコードします。目立つズレが出るのは、たいてい古いFFmpegビルド、ストリームコピー経路、または破損したファイルの場合です。 解決策: FFmpegを更新する。あるいは代替として -ss-i の後ろに置きます(先頭からデコードするため遅い)。

ffmpeg -i input.mp4 -ss 00:00:05 -frames:v 1 output.png

症状3: PNGファイルが巨大

原因: PNGは無劣化で情報量が多い。 解決策: -q:v を付けてJPGで書き出すとはるかに小さくなります(第4章)。


よくある質問

Q1. フレーム抽出とサムネイル作成の違いは? A. フレーム抽出は選んだレートで生の静止画を得ます。サムネイル作成の手順は代表的な1枚のためのスマートな選択とサイズ調整を加えたものです。

Q2. N秒ごとに1フレーム取るには? A. -vf fps=1/N を使います。例えば fps=1/10 は10秒ごとに1フレームです。

Q3. PNGではなくJPGで抽出できますか? A. できます。出力名を .jpg にし、高画質なら -q:v 2 を使います(第4章)。

Q4. 画像シーケンスが上書きされてしまうのはなぜ? A. 出力ファイル名に連番が無いためです。%04d を追加して各フレームに一意の番号を付けてください。

Q5. フレーム抽出は元動画に影響しますか? A. しません。FFmpegは入力を読むだけで、元ファイルは一切変更されません。


関連記事


Tested with FFmpeg 8.1 — verified with our command-check script 一次ソース: ffmpeg.org/ffmpeg.html / trac.ffmpeg.org/wiki/Seeking