Search code examples
if-statementvideoffmpegcommand-lineblending

How to use multiple between statements with the blend filter in ffmpeg


The command below blends input2 into input1 using a binary of *if expressions featuring the between statement's t variable. As such, output = input1, but with input2 at 00:00:03- 00:00:05:

ffmpeg -y -i input1.mkv -i input2.mkv -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0][v1]blend=all_expr='A*if(between(T, 3, 5), 0, 1)+B*if(between(T, 3, 5), 1, 0)'" -vcodec libx264 -pix_fmt yuv444p -crf 18 -acodec copy output.mkv

My question is how these can be chained together in the case of a set of evaluated conditions. I've attempted the + operator, below, but input1 is no longer the same. It seems distorted by multiple layers of the video.

ffmpeg -y -i input1.mkv -i input2.mkv -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0][v1]blend=all_expr='A*if(between(T, 3, 5), 0, 1)+B*if(between(T, 3, 5), 1, 0)'+'A*if(between(T, 7, 9), 0, 1)+B*if(between(T, 7, 9), 1, 0)'" -vcodec libx264 -pix_fmt yuv444p -crf 18 -acodec copy output.mkv

How can these be chained together without producing visual artifacts?

This question is a follow-up to Rotem's solution to my earlier question.


Solution

  • In case you want only [v1] between [3, 5] and between [7, 9], and [v0] otherwise, make sure that B is multiplied by 1 between {[3, 5], [7, 9]} and A is multiplied by 0 between {[3, 5], [7, 9]}, and vice versa.

    We may use the following command:

    ffmpeg -y -i input1.mkv -i input2.mkv -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0][v1]blend=all_expr='A*not((between(T, 3, 5)+between(T, 7, 9)))+B*(between(T, 3, 5)+between(T, 7, 9))'" -vcodec libx264 -pix_fmt yuv444p -crf 18 -acodec copy output.mkv
    

    Since it's just 0 and 1, we don't have to use the if expression.

    According to Expression Evaluation documentation:

    between(x, min, max)
    Return 1 if x is greater than or equal to min and lesser than or equal to max, 0 otherwise.

    not(expr)
    Return 1.0 if expr is zero, 0.0 otherwise.

    • (between(T, 3, 5)+between(T, 7, 9)) is evaluated to 1 in range {[3, 5], [7, 9]}, and evaluated to 0 otherwise.
    • not(between(T, 3, 5)+between(T, 7, 9)) is evaluated to 0 in range {[3, 5], [7, 9]}, and evaluated to 1 otherwise.