I was trying to create two effects by using FFmpeg: "curtain" ("barn doors") and "circle wipe" but had no success. The basic idea is to start from black screen (100% of black padding) and during 1 second (or more) display the entire video (the black padding on the top and on the bottom should get less and less).
How can I do this?
Answer
Generally, there are two methods to achieve such effects.
#1
Create a grayscale animated mask and attach that as the alpha channel to the video. Perform an overlay of the video over a black canvas.
Pros: one-time op to generate the mask. Much faster than method 2.
Cons: Animation parameters like size, speed, duration are fixed. These can be tweaked within ffmpeg but results may not be smooth. Mask file needs to be kept and accessible.
#2
Use the blend filter with a blank canvas as bottom layer and set expressions to carry out the effect.
Pros: customizable. May need some trial and error to achieve exact effect.
Cons: much slower than method 1. At smaller resolutions, result is coarser than a properly anti-aliased mask. If you don't remember expressions or how they work, expressions have to be saved as well and tweaking may be hard.
That said, here are the two effects using the blend filter. Both effects start at 2 seconds and happen over 3 seconds.
Curtains, unveiled vertically
ffmpeg -i in.mp4 -filter_complex \
"[0]format=yuv444p,split=2[bg][v];[bg]drawbox=t=fill[bg]; \
[v][bg]blend=all_expr='if(lte(2*abs(Y-H/2)/H,(T-2)/3),A,B)',\
format=yuv420p" \
out.mp4
A faster method can be adapted from first command here. That command does it horizontally.
Circle Wipe, expanding
ffmpeg -i in.mp4 -filter_complex \
"[0]format=yuv444p,split=2[bg][v];[bg]drawbox=t=fill[bg]; \
[v][bg]blend=all_expr='if(lte(sqrt(pow(X-W/2,2)+pow(Y-H/2,2))/sqrt(pow(W,2)+pow(H,2)),(T-2)/3)/2,A,B)',\
format=yuv420p" \
out.mp4
No comments:
Post a Comment