動画から静止画を取り出すのはFFmpegの最も便利な使い方の一つです。コンタクトシートの作成、サムネイル用のきれいな1枚の取得、別ツールに渡すためのフレーム書き出しなど。FFmpegならフレームをPNGやJPGとして書き出すことができ、全フレーム、1秒ごとなど一定間隔、あるいは正確なタイムスタンプでの1枚、と自由に選べます。本記事ではそれぞれの方法と、重要な画質設定を解説します。所要時間:7分。
動作確認: FFmpeg 8.1
この記事でわかること
- タイムスタンプ指定で1枚キャプチャする方法(実行可能)
fpsで1秒ごとに1フレーム抽出する方法- 全フレームを画像シーケンスとして書き出す方法
- PNGとJPGの使い分けと画質の制御
- 抽出と同時にリサイズする方法
- トラブルシューティングと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=1 | 1秒あたり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.png、output_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=1 | 1枚/秒 |
| 5秒ごと | -vf fps=1/5 | 1枚/5秒 |
| 毎秒2枚 | -vf fps=2 | 2枚/秒 |
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