🎬

ffmpegで複数の指定フレーム(飛び飛び)を一度に画像書き出しする方法

2023/06/08に公開

機械学習などで、動画から指定のフレームだけ(複数かつ飛び飛び)を画像にしたい場合、以下のコマンドが便利。

bash
$ ffmpeg -i in.mp4 -vf "select=eq(n\,1417)+eq(n\,2040)+eq(n\,3700)" \
-frame_pts 1 \
-vsync 0 \
-c:v mjpeg \
out/%d.jpg

eqの2個目の引数がフレーム番号。

参照したのは以下の記事。vsyncやframe_ptsなど、パラメータの指定をミスすると他のフレームも書き出されたりうまくいかなかったりして、だいぶ苦戦した。

https://stackoverflow.com/questions/38253406/extract-list-of-specific-frames-using-ffmpeg

ちなみにeq()+eq()+eq()はフィルタの重ね合わせなので、順不同でOK。いくつも指定できるので、Pythonなどで以下のように自動生成させると便利。

python
select_filter = '+'.join([f"eq(n\\,{frame_id})" for frame_id in frame_id_list])
subprocess.run(['ffmpeg', '-i', video_path, '-vf', f"select={select_filter}", '-frame_pts', '1', '-vsync', '0', '-c:v', 'mjpeg', os.path.join(out_dir, '%d.jpg')])

また、mjpegのデフォルトの画質 (ビットレート、-b:v) は20Kらしいので、画質を変えたい場合は指定したほうが良い。

Discussion