Featured image of post FFmpegで動画のダウンサンプリング・リサイズと同時に再生速度を倍速にする方法

FFmpegで動画のダウンサンプリング・リサイズと同時に再生速度を倍速にする方法

FFmpegを用いて動画のファイルサイズを削減したりプレビュー用の軽量な動画を作成したりする際、フレームレートの引き下げ(ダウンサンプリング)と解像度の縮小(スケールダウン)を組み合わせる手法がよく用いられます。たとえば、入力動画 input.mov を10fpsに間引きつつ横幅を800ピクセルに縮小し、音声を除去して output.mp4 へ出力する場合、以下のようなコマンドがベースとなります。

ffmpeg -i input.mov -vf "fps=10,scale=800:-2" -c:v libx264 -crf 26 -preset slow -an output.mp4

この一連の変換処理に加えて、映像の再生速度を2倍速などに変更したい場合、既存のビデオフィルタ(-vf)にタイムスタンプを制御するフィルタを追加することで、1回のエンコード処理で速度変更まで完結させることが可能です。

再生速度の変更を追加したFFmpegコマンド

元の変換処理に2倍速の処理を組み込むには、ビデオフィルタの先頭に setpts フィルタを追加します。具体的なコマンドは以下の通りです。

ffmpeg -i input.mov -vf "setpts=0.5*PTS,fps=10,scale=800:-2" -c:v libx264 -crf 26 -preset slow -an output.mp4

各オプションの役割は以下の通りです。

  • -vf "setpts=0.5*PTS,fps=10,scale=800:-2" : 映像を2倍速にし、フレームレートを10fpsに変換したうえで、アスペクト比を維持しながら横幅800ピクセル(高さは2の倍数に自動調整)へ縮小します。
  • -c:v libx264 -crf 26 -preset slow : H.264コーデックを使用し、品質基準(CRF値26)と圧縮効率(slow)を指定してエンコードします。
  • -an : 音声トラックを出力から除外します。

setptsフィルタによるタイムスタンプ制御の仕組み

FFmpegにおける setpts は、映像の各フレームが持つPTS(Presentation Timestamp:表示タイムスタンプ)を書き換えるフィルタです。動画プレイヤーは各フレームに記録されたPTSを参照して表示タイミングを決定するため、各フレームのタイムスタンプの間隔を縮めることで再生速度を速めることができます。

元の映像を $N$ 倍速にする場合、新しいタイムスタンプ $\text{PTS}_{\text{new}}$ を求める計算式は以下のようになります。

$$\text{PTS}_{\text{new}} = \frac{1}{N} \times \text{PTS}$$

2倍速($N = 2$)にする場合は $\frac{1}{2} = 0.5$ となるため setpts=0.5*PTS と記述します。同様に、3倍速($N = 3$)にしたい場合は setpts=(1/3)*PTS、4倍速($N = 4$)にしたい場合は setpts=0.25*PTS と指定することで、任意の再生速度へ変更できます。反対に $0.5$ 倍速のスロー再生にしたい場合は $N = 0.5$ を代入し、タイムスタンプを2倍に引き伸ばす setpts=2.0*PTS を指定します。

ビデオフィルタの適用順序と音声トラックの扱い

複数のビデオフィルタをカンマ区切りで繋げた場合、FFmpegは記述された左から順番にフィルタ処理を適用するという仕様を持っています。今回のコマンドにおいて setpts=0.5*PTS を fps=10 の前に配置しているのは、倍速化によって時間軸が圧縮された後の映像に対してフレームレートの間引きを行うためです。

先に setpts=0.5*PTS で元の映像を2倍速に圧縮し、その直後に fps=10 を適用することで、出力される2倍速の動画は正確に秒間10フレームへ調整されます。仮に順序を逆にして fps=10,setpts=0.5*PTS と記述した場合、先に秒間10フレームへ間引かれた映像のタイムスタンプが後から半分に圧縮されるため、結果として秒間20フレームの映像が出力されてしまいます。意図したフレームレートとファイルサイズを得るためには、時間軸の操作をフレームレート変換の前に置くことが重要です。

また、通常FFmpegで動画の再生速度を変更する際は、映像用の setpts とは別に、音声用の atempo フィルタを用いて音声の再生速度も同期させる必要があります。しかし、今回のコマンドでは -an オプションによって音声トラック自体が削除されているため、音声フィルタの追加や映像とのズレを考慮する必要はなく、ビデオフィルタの記述変更のみで処理が成立します。

AIによる技術記事 備忘録.
Hugo で構築されています。
テーマ Stack は Jimmy によって設計されています。