ffmpeg で使える評価式

どこでこの書式を使うかというと座標やフレーム数、音声の周波数を指定するときの値やタイムライン編集で使う。全てを記載していないのですべての使い方は公式ドキュメントを参照。

公式ドキュメント : FFmpeg Utilities Documentation :: Expression Evaluation
使えるフィルタ一覧 : FFmpeg Filters Documentation
計算例:(ffmpeg-utils)3. Expression Evaluation — ffmpeg examples

ffmpeg でテキストを動的に表示する
特定の区間だけフィルタを当てるタイムライン編集について
Expression_Evaluation | タグ検索

n は 0 から始まるフレーム数(整数)
t は 0 からはじまるタイムスタンプ(秒時間)
expr は評価式指定でもできるし、そうでなくてもよい
0 または 1 を返す変数は、変数の頭に置いてその変数の有効無効に使う
三角関数で使われる sin などは角度指定ではなく、ラジアン単位指定である
この書式を使ってエラーが出る場合はその区間を一重引用符'で挟む、半角スペースを削除するか、エスケープする

値を調べるには print() を使う

  • sinh(x) ハイパボリックサイン(双曲線関数)
  • cosh(x) ハイパボリックコサイン
  • tanh(x) ハイパボリックタンジェント
  • sin(x) サイン(三角関数)
    sin((PI*n)/180) 360フレームで1回転する
    sin((PI*(360/5)*t)/180) 5秒で1回転する
    sin((PI*(180/5)*t)/180) 5秒で半回転する
  • cos(x) コサイン
  • tan(x) タンジェント
  • asin(x) アークサイン(逆関数)
  • acos(x) アークコサイン
  • atan(x) アークタンジェント
  • exp(x) 自然対数の底 e の x 乗。exp(0) = 1
  • log(x) 自然対数の底 e の x。log(E) = 1
  • abs(x) x の絶対値を返す
  • isnan(x) x が数字でなければ 1 を返す、そうでなければ 0 を返す
  • mod(x,y) x を y で割り、その余りを返す
    mod(n,100) 0から99までそれを返し、100は0を返し、101は1を返し、以下ループ

  • max(x,y) x≦y は y を返し、x>y は x を返す
  • min(x,y) x≦y は x を返し、x>y は y を返す
  • between(x,min,max) x が min 以上または max 以下ならば 1、そうでなければ 0 を返す。between() を併用する場合は2回目以降の両端が重複するので、最初に between() を使い、後は gt()*lte() を併用する
  • clip(x,min,max) x が min から max の間だけ返す。min以下は min を返し、max 以上は max を返す
    clip(x,0,255) でマイナスは 0 に、 256 以上は255に、その間はそのままを返す
  • bitand(x,y) ビットアンドの x, y
  • bitor(x,y) ビットオアの x, y
  • eq(x,y) x=y のときに 1 を返し、そうでなければ 0 を返す
  • gcd(x, y) x, y の共通の最大公約数を返す。x, y の両方が 0 だと 0 を返し、x, y の片方が 0 または マイナスだと undefined を返す
  • gt(x,y) x>y ならば 1 を返し、そうでなければ 0 を返す
    gt(n,100) n が100より大きければ 1 を返し、100以下ならば 0 を返す
  • gte(x,y) x≧y ならば 1 を返し、そうでなければ 0 を返す
    gte(n,100) n が100以上ならば 1 を返し、100より小さければ 0 を返す
    gte(n,0) n が0以上ならば 1 を返し、マイナスならば 0 を返す
  • lt(x,y) x<y ならば 1 を返し、そうでなければ 0 を返す
    lt(n,100) n が100より小さければ 1 を返し、100以上ならば 0 を返す
  • lte(x,y) x≦y ならば 1 を返し、そうでなければ 0 を返す
    lte(n,100) n が100以下ならば 1 を返し、100より大きければ 0 を返す
    lte(n,0) n が0以下ならば 1 を返し、0より大きければ 0 を返す
  • lerp(x,y,z) x から y の間を z の 0 から 1 までとした線形補間で返す。z が負の時は xy 間に負をかけて、1より大きな時は xy 間の先の値になる
  • sgn(x) 符号関数。xが正の値は 1、負の値は -1、0 は 0 を返す

  • st(var,expr) var には数値を、expr は計算式が使える。一度値を代入すると再代入しない限り同じ値を持ち続ける
  • ld(var) st() で使った変数を再利用する。st()を宣言する前は0になる。同じフィルタのオプション(::)内でしか使えない
    つまり同じフィルタ内にあると st(n,mod(n,100)) と ld(n) は同じ計算になる
    例:x='st(0, 100);ld(0)' x には 100 が代入される
    例:x='st(0, 100);st(1, 100);ld(0)+ld(1)' x には 200 が代入される

    Windowsは引用符で囲まないとうまく実行できない。
    ffplay -f lavfi -i testsrc2 -vf "crop=iw/2:ih:'st(0\,100);ld(0)'"
    ffplay -f lavfi -i testsrc2 -vf crop=iw/2:ih:'st(0\,100);ld(0)'

    以下はエラーになる。
    ffplay -f lavfi -i testsrc2 -vf "crop=iw/2:ih:st(0\,100);ld(0)"
    ffplay -f lavfi -i testsrc2 -vf crop=iw/2:ih:'st(0\,100)';ld(0)

    ld()は一度st()を読み込まないとld()の中身を読み込めず0を返す。例えばif(x,y,z)xに条件を指定し、0以外ならy、0ならzになる。xが0なのでld(1)を読み込むが、st(1,10)を読み込んでないので0を返す。

    if(0,st(1,10),ld(1))

    xの条件はst(1,10)-10で0になり、ld(1)を読み込み10を返す。

    if(st(1,10)-10,2,ld(1))

    How to cut / delete 2 seconds of video after each 10 seconds with ffmpeg ? : ffmpegより。

    'if(gte(t,ld(1)+10),st(1,t)*0,if(ld(1),gt(t,ld(1)+2),1))'

    これは10秒前まで1、10秒から12秒前まで0、12秒から20秒前まで1、20秒から22秒前まで0。と以下同様の処理になる。

    処理をわかりやすくインデントを加えたもの。


    まず、if(x,y,z)の形になり、xの条件式にst()ではなく、ld()を使っているのがポイントである。一度もst()を読み込んでないとld()は0を返す。xの条件のgte()はtとld(1)+10を比較して真ならyのst(1,t)*0を返し、偽なら2番目のif()に移動する。tが10秒未満では2番目のifに移動し、10秒になるとst(1,t)*0を返しld(1)に10を代入する。するとxの条件のld(1)+10は20になり、次の20まで偽を返す。以下同様に10の倍数のときだけld(1)に10の倍数が代入される。

    2番目のif()は、10秒前まではld(1)は0のままなので1を返す。10秒になるとld(1)に10が代入されtとld(1)+2の12秒を比較し12秒未満は0、12秒以上は1を返す。20秒になるとld(1)に20が代入され以下同様になる。

    他の利用例
    python - I want a ffmpeg command that will zoom video every 4 second with transition effects - Stack Overflow

  • ceil(expr) 小数点以下を繰り上げ
    ceil(1.5) は 2.0 になる
  • floor(expr) 小数点以下を繰り下げ
    floor(-1.5) は -2.0 になる
  • trunc(expr) 小数点以下を切り捨て
    trunc(-1.5) は -1.0 になる
  • gauss(x)
    ガウス関数に x を代入して返す

  • sqrt(expr) 評価式の平方根を返す
  • hypot(x,y)
    C 言語の hypot と同じ。sqrt(x*x + y*y) を返す。直角三角形の斜辺の長さを求める
  • squish(x) 1/(1+exp(4*x)) を返す
  • random(x) 0 から 1 までの小数点を含む値をランダム数を返す x は他の値と区別する
  • if(x,y) x が 0 であれば 0 を返す、そうでなければ y を返す
  • if(x,y,z) x が 0 であれば z を返す、そうでなければ y を返す
    if(x,0,1) で 0 と 1 を逆に返す
  • ifnot(x,y) x が 0 であれば y を返す、そうでなければ 0 を返す
  • ifnot(x,y,z) x が 0 であれば y を返す、そうでなければ z を返す
  • not(expr) 評価式が 0 ならば 1 を返し、そうでなければ 0 を返す
  • time(0) 現在の時間を Unixtime で返す
  • pow(x,y) (x)^(y) つまり x の y 乗。立方根などのn乗根は y に分数を指定する
  • print(t), print(t,1) t(タイムスタンプ)のログをコンソールに表示。引数をつけることでログレベルを指定できる。t の部分を変えることでいろいろな変数の値を調べられる

  • PI 円周率 約3.14
  • E 自然対数の底 約2.718
  • PHI 黄金比 約1.618

2013/07/13、2016/12/02、2016/12/22、2017/02/04、2017/02/1:
比較の書式を直した。
2017/03/15:gt, gte, lt, lte の説明が間違っていたのを直した。
2020/10/13:st(),ld()の利用例を追加した。
2022/05/14:lerp()を追加した。
2022/05/16:sgn()を追加した。
関連記事

コメント

非公開コメント

プロフィール

ロベルト

お問い合わせはこちらまで
robelt2525[at]gmail.com

中の人 @nico_lab

広告リンク
Amazon
楽天市場

ブログ更新用 @blo_nico_lab

詳しいプロフィールはこちら

当ブログは、Amazonアソシエイトに参加しています。