はじめに
前回の記事を書いた後で、force_key_frames を設定する方法を知ったので、それについて書きます。 ちなみに、前回の記事はこちらです。
確認した環境
- ffmpeg 4.2
本題
force_key_frames
によるキーフレームの設定では式(expression)を使って詳細に指定することができます。
例えば、5秒間隔でキーフレームを挿入するコマンドは以下の通りです。
ffmpeg -i input.mp4 -vcodec h264 -force_key_frames expr:gte(t,n_forced*5) out.mp4
また、150フレームに1回キーフレームを入れるコマンドは以下の通りです。
ffmpeg -i input.mp4 -vcodec h264 -force_key_frames expr:gte(n,n_forced*150) out.mp4
expr:
以下について
expr:
以下に式を書くことで、式によるキーフレームの指定ができます。
この式は最初のフレームからフレーム単位で順番に評価され、その式が0以外を返すときそのフレームはキーフレームになります。
そしてforce_key_frames
のexpr:
で指定する式には、数字以外に使用できる値があります。
今回のgte(t,n_forced*5)
ではt
とn_forced
を使用しています。
t
は評価されるフレームの時間を表します。単位は秒です。
n_forced
はそれまでに評価されたフレームのキーフレームの数を表します。
例としてgte(t,n_forced*5)
を詳しく見ていきます。
まずgte(t,n_forced*5)
のgte(x,y)
はx >= y
のとき1を返し、それ以外のときは0を返す関数です。
gte(t,n_forced*5)
は、0フレーム目のときt = 0, n_forced*5 = 0*5 = 0
となるので1を返しキーフレームになります。
次の1フレームはt = 0.033…, n_forced*5 = 1*5 = 5
となるので、gte(t,n_forced*5)
は0を返しキーフレームになりません(t
はフレームレートが30fpsのときの値)。
よって次にgte(t,n_forced*5)
が1を返すのはt >= 5
となる最初のフレームなので、5秒のところにキーフレームがきます。
それから次フレームからはn_forced*5 = 2*5 = 10
となるので、次のキーフレームは10秒のところとなって……、
というのを繰り返すので、キーフレームが5秒間隔で設定されることになります。
利用できる関数は他にもあります。
例えば、ifnot(x,y)
はx == 0
のときy
を返し、それ以外のときは0を返す関数です。
また使用できる値は他にもあります。
例えば、n
は評価されるフレームのフレーム数を表します。0オリジンです。
よって以下のコマンドでも150フレームに1回キーフレームを入れることができます。
ffmpeg -i input.mp4 -vcodec h264 -force_key_frames expr:ifnot(mod(n,150),1) out.mp4
詳しくは、参考に載せる公式ドキュメントをご確認ください。
参考
公式ドキュメントでforce_key_frames
に関する説明があります。
https://ffmpeg.org/ffmpeg.html#Advanced-Video-options
同じく公式ドキュメントで`FFmpegで使用できる関数の一覧があります。
https://ffmpeg.org/ffmpeg-utils.html#Expression-Evaluation
expr:
以下の式の評価のされ方に関しては以下のページの説明が分かりやすかったです。