🎬
ffmpegで複数の指定フレーム(飛び飛び)を一度に画像書き出しする方法
機械学習などで、動画から指定のフレームだけ(複数かつ飛び飛び)を画像にしたい場合、以下のコマンドが便利。
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など、パラメータの指定をミスすると他のフレームも書き出されたりうまくいかなかったりして、だいぶ苦戦した。
ちなみに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