ffmpeg ネタ2つ:Cuda エンコードに失敗した時は・フレームレート変換

ffmpeg のネタを2つ。ffmpeg はオプションがホントに豊富だし、高機能で次から次に情報が出てくる。

Cuda を使った GPU エンコードに失敗する時は…

↑ コチラのように、Windows10 + Git SDK 環境で ffmpeg を用意していて、NVIDIA GTX1080 を使った GPU エンコードが出来ている。

# スケールを「高さ 720px」に圧縮しようと思い -vf オプションを書いている
$ ffmpeg -hide_banner -loglevel error -stats \
    -hwaccel cuda \
    -i './example-input.mp4' \
    -c:v h264_nvenc \
    -vf scale=-1:720 \
    './example-output.mp4'

こんな感じでいつものように GPU エンコードをしようと思ったら、今回取り込んだ example-input.mp4 だけ、エラーが出てしまい上手く変換できなかった。それまで他のファイルは上手く変換できていたのに…。

そんで調べてみると、-pix_fmt yuv420p オプションを付け加えれば回避できるという。

$ ffmpeg -hide_banner -loglevel error -stats \
    -hwaccel cuda \
    -i './example-input.mp4' \
    -pix_fmt yuv420p \
    -c:v h264_nvenc \
    -vf scale=-1:720 \
    './example-output.mp4'

コレで無事変換できた。

フレームレートを変換する

60fps の動画ファイルを 30fps にしたいとか、59.94フレームの動画を29.97フレームにしたいとか、そういう風にコマ数を半分に間引いて動画を圧縮しようと思った時。

結論からいうと -r オプションで指定できるのだが、-i オプションよりも後ろに書かないといけないことだけ注意。-i オプションの手前に書いた -r オプションは入力ソースの情報を示す別の意味になってしまうようだ。

# 元は 59.94fps のような動画を、29.97fps に間引いて書き出す。-r オプションの位置に注意
$ ffmpeg -hide_banner -loglevel error -stats \
    -hwaccel cuda \
    -i './example-input.mp4' \
    -c:v h264_nvenc \
    -vf scale=-1:720 \
    -r 29.97 \
    './example-output.mp4'

「29.97」のような中途半端なフレームレートは 30000/1001 と書くこともあるようだが、自分は 29.97 と直接書いて上手く行った。59.94 も 60000/1001 と書いたりするようだ。

コレでフレームレートを間引けた。音ズレもなく問題なし。