動画のサムネイル画像は、FFmpegで動画のフレームを静止画として書き出せば作れます。
基本:特定タイムスタンプから1フレーム抽出
-ss で取り出す位置を指定し、-vframes 1 で1フレームだけ書き出します。
ffmpeg -i input.mp4 -ss 00:00:01 -vframes 1 thumbnail.jpg
-ss 00:00:01:開始から1秒の位置にシーク(移動)する-vframes 1:書き出すフレームを1枚にする(-frames:v 1と同じ)- 画像の形式は、出力ファイルの拡張子で決まる(ここでは JPEG)
-ssの位置について:-iの前に置くと、直前のキーフレーム(単独で表示できるフレーム)まで一気に移動してから、指定した位置までをデコードします。速いうえに、取り出されるフレームは-iの後ろに置いた場合と同じです。-iの後ろに置くと、先頭から順にデコードするので、動画が長いほど時間がかかります。長い動画では-iの前に置いてください。
PNG で保存する場合:
ffmpeg -i input.mp4 -ss 00:00:01 -vframes 1 thumbnail.png
PNG は可逆圧縮(画質が落ちない圧縮)なので高画質ですが、JPEG よりファイルサイズが大きくなります。
複数フレームを一定間隔で抽出
-vf fps=1 を使うと、1秒ごとに1フレームずつ、連番のファイルとして書き出せます。
ffmpeg -i input.mp4 -vf fps=1 frame%03d.jpg
%03d の部分には連番が入ります。
間隔を変える例:
# 5秒ごとに1フレーム
ffmpeg -i input.mp4 -vf fps=1/5 frame%03d.jpg
# 10秒ごとに1フレーム
ffmpeg -i input.mp4 -vf fps=1/10 frame%03d.jpg
別のフォルダーに書き出す場合は、frames/frame%03d.jpg のようにパスを付けます。フォルダーは先に作っておく必要があります。
thumbnailフィルタ:代表フレームを自動選択
thumbnail フィルタは、指定した範囲のフレームから「代表的なフレーム」を自動で選びます。選ぶ基準は、ヒストグラム(明るさや色の分布)が、そのグループ全体の平均にいちばん近いことです。
ffmpeg -i input.mp4 -vf thumbnail -vframes 1 thumbnail.jpg
初期設定では、100フレームを1グループとして調べ、その中で最も代表的なフレームを選びます。-vframes 1 を付けると最初のグループで止まるので、選ばれるのは冒頭の100フレーム(30fpsなら約3.3秒)の中の1枚です。グループの大きさを変えるには、数値を付けます:
ffmpeg -i input.mp4 -vf thumbnail=300 -vframes 1 thumbnail.jpg
数値を大きくすると広い範囲から選びますが、そのぶん処理に時間がかかります。
解像度指定付きサムネイル抽出
-vf scale=幅:高さ を加えると、サイズを変えて書き出せます。
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 -vf scale=320:180 thumb.jpg
縦横比(アスペクト比)を保ったまま幅だけ指定する場合は、-1 を使います:
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 -vf scale=320:-1 thumb.jpg
-1 は「アスペクト比を保つように自動で計算する」という意味です。JPEG や PNG は 320×181 のような奇数のサイズでも書き出せるので、画像なら -1 で問題ありません。偶数に丸める -2 が必要になるのは、H.264 などの動画に書き出すときです。
thumbnail フィルタと scale を一緒に使う場合は、カンマでつなぎます:
ffmpeg -i input.mp4 -vf "thumbnail,scale=320:180" -vframes 1 thumb.jpg
JPEGとPNGの選び方
| 形式 | 圧縮 | ファイルサイズ | 用途 |
|---|---|---|---|
| JPEG | 非可逆 | 小さい | Web表示、SNSサムネイル |
| PNG | 可逆 | 大きい | 高品質保存、透過画像 |
JPEG の画質は -q:v で指定できます。値は2〜31で、小さいほど高画質です:
ffmpeg -i input.mp4 -ss 00:00:01 -vframes 1 -q:v 2 thumbnail.jpg
よくある問題
抽出したフレームが真っ暗になる
その時刻のフレームそのものが暗い(フェードインや暗転の途中)ことが多いです。少し後ろの時刻を指定してください。
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 thumbnail.jpg
thumbnailフィルタが遅い
初期設定の100フレーム単位の解析が重い場合は、thumbnail=30 のように値を小さくしてください。
まとめ
| 目的 | コマンド例 |
|---|---|
| 特定秒から1枚 | -ss HH:MM:SS -vframes 1 |
| 定期間隔で複数枚 | -vf fps=1/N frame%03d.jpg |
| 自動で代表フレーム | -vf thumbnail -vframes 1 |
| リサイズしながら抽出 | -vf scale=W:H -vframes 1 |
関連記事:
よくある質問
指定秒のサムネイルを取るには?
ffmpeg -ss 00:00:05 -i in.mp4 -vframes 1 -q:v 2 thumb.jpg を実行します。長いファイルでは、-ss を -i の前に置くと高速にシークできます。
サムネイルが真っ黒になる
その時刻のフレームそのものが黒い(フェードインや暗転の途中)ことが多いです。少し後ろの時刻を試してください。ファイルの長さより後ろの時刻を指定した場合は、黒い画像ではなく、画像が1枚も書き出されません。
N フレームごとに静止画を出すには?
-vf "select=not(mod(n\,30))" -fps_mode vfr を使うと、30 フレームごとに連番の静止画を書き出せます。スプライトシート(複数のコマを1枚に並べた画像)や、シークバーのプレビュー用サムネイルに使えます。
JPEG と PNG どっちで保存する?
写真のようなフレームなら JPEG(-q:v は 2 か 3)が向いています。ファイルが小さく、見た目の劣化もありません。スクリーンショットや、透過が必要な場合は PNG を使います。
サムネイルグリッド(スプライト)を作りたい
tile フィルタを使います。-vf "fps=1/10,scale=160:-1,tile=5x5" とすると、10 秒ごとに取り出したフレームを 5×5 に並べた画像ができます。