Search code examples
videotimeffmpegcommand-line-interfaceblend

How to use the blend / tblend filter with the t variable and between statement in FFMPEG


I want to use the blend or tblend filters in conjunction with the t variable's between statement. I'm open to other solutions that will achieve the same effect.

I know an image can be transposed over a video, e.g. between 00:00:01.000 to 00:00:02.000:

ffmpeg -i input.mkv -i input.jpg -filter_complex \ "[0:v][1:v] overlay=10:10:enable='between(t,1,2)'" output.mkv

Blurring a video at the same time can be done with smartblur:

ffmpeg -i input.mkv -vf "smartblur=enable='between(t,1,2)'" output.mkv

Changing the hue angle, e.g. by 90 degrees, can also be done:

ffmpeg -i input.mkv -vf "hue=h=-90:enable='between(t,1,2)'" output.mkv

Nothing from my searches or in the official documentation, however, explains how to compose a command using the blend or tblend filters in conjunction with the t variable's between statement. I've tried a number of formulations, but they all lead to errors. Is this simply not possible? Or is there another way to structure the command?


Solution

  • According to the examples in the documentation, we may multiply the frame by the evaluated condition.

    Example (the input is from here):

    ffmpeg -y -i in.mp4 -i in.gif -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0][v1]blend=all_expr='A*if(between(T, 2, 6), 0.3, 1)+B*if(between(T, 2, 6), 0.7, 0)'" -vcodec libx264 -pix_fmt yuv444p -crf 17 -acodec copy out.mp4
    
    • A applies the frame from the first video stream - [v0].
    • B applies the frame from the second video stream - [v1].
    • if(between(T, 2, 6), 0.3, 1) is evaluated to 0.3 when time is between 2 and 6 seconds, and evaluated to 1 otherwise.
    • if(between(T, 2, 6), 0.7, 0) is evaluated to 0.7 when time is between 2 and 6 seconds, and evaluated to 0 otherwise.
    • The entire expression is evaluated to 0.3*A + 0.7*B between 2 and 6 and 1*A + 0*B otherwise.

    Sample output (between 2 and 6 seconds):
    enter image description here

    Note:
    I think there is a bug regarding the exact time, but it could be related to my input.


    We may also chain two blend filters if required.
    The first blend applies some blending effect, and the second blend selects when to use the effect and when to use the original video stream.
    Example:

    ffmpeg -y -i in.mp4 -i in.gif -filter_complex "[1:v][0:v]scale2ref[v1][v0];[v0][v1]blend=all_mode=grainextract[b];[0:v][b]blend=all_expr='A*if(between(T, 2, 6), 0, 1)+B*if(between(T, 2, 6), 1, 0)'" -vcodec libx264 -pix_fmt yuv444p -crf 17 -acodec copy out.mp4
    

    Another option is to chain blend with overlay filter.