📜 ⬆️ ⬇️

Snowfall with FFmpeg filters

FFmpeg is powerful software with a wide range of features. In the article I will try to tell about a bit unusual application of ffmpeg filters and about what can be done using them exclusively. The video below is made using the 1 ffmpeg command (no image editor was hurt).


I will use the latest version of ffmpeg compiled from git . So, if you want my examples to work, I recommend to collect from the master branch. Building and installing is trivial and is described on the ffmpeg.org website, with ./configure, do not forget to specify "--enable-libfreetype".

First we need to create a background for our video and we will use the ffmpeg tools. The fact is that ffmpeg allows you to use not only real devices (for example, a video camera or sdi card) and files as an input source, but also can use its own virtual device called lavfi .

FFmpeg contains several pre-made filters that generate a video image. Among them:

The full list of filters can be viewed with the command
ffmpeg -filters

Here's what they look like:

')
Since I indicated that I would only use ffmpeg, I generated this image with the help of 1 ffmpeg command. Here she is:
 ffmpeg \ -f lavfi -i "testsrc=s=320x240" \ #   lavfi       320x240 -f lavfi -i "cellauto=s=320x240" \ -f lavfi -i "life=s=320x240" \ -f lavfi -i "mandelbrot=s=320x240" \ -f lavfi -i "rgbtestsrc=s=320x240" \ -f lavfi -i "smptebars=s=320x240" \ -filter_complex \ "[0:0]pad=iw*6:ih[a];\ #      pad [1:0]pad=iw:ih[b];\ [2:0]pad=iw*2:ih[c];\ [3:0]pad=iw*3:ih[d];\ [4:0]pad=iw*4:ih[e];\ [5:0]pad=iw*5:ih[f];\ [a][b]overlay=w[x];\ #      overlay [x][c]overlay=w[y];\ [y][d]overlay=w[z];\ [z][e]overlay=w[v];\ [v][f]overlay=w" -vframes 1 all_filters.jpg 

Although I made a picture, with the help of this command you can also combine 6 video in a row or make a “mosaic”, you just need to substitute video files as input sources and change the parameters for the pad and overlay filters. Run through the options:

And so, let's create a background for our video:
 ffmpeg2 -f lavfi -i "color=lightblue" -t 30 -y blue.ts 

It's all the same as in the example with pictures, except that here we create video and instead of filter generators, we use a simple color filter. In addition to the number of frames, you can specify the duration of the video through the key "-t". By default, ffmpeg will set the fps of the output stream to 25. Since I have specified the extension for the output .ts file, ffmpeg will use the MPEG2TS container, and the codec will be mpeg2video.

Now add a snowflake. For this we will use the filter drawtext. Yes, yes, we will draw a snowflake with the text, or rather with a special Unicode character "" (U + 2744).

The team that does this is:
 ffmpeg -f lavfi -i "color=lightblue" \ -vf "drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=50:text='':fontcolor=white:x=sin(n/10)*30+w/2:y=n" \ -t 5 -y snow.gif 

Drawtext filter options:


As you can see, the whole salt in coordinates. The fact is that ffmpeg allows you to change the parameters of some of its filters on the fly, for example, depending on the frame number or timestamp. In this example, in addition to the already familiar w and h, I used the next internal alias of ffmpeg "n" - the current frame number and the sine function to give the snowflake a motion from side to side. In ffmpeg filters, you can use trigonometric and arithmetic functions, such as trunc and random. A complete list of functions can be found here .

Now we just need to add more filters (we need more filters!) To create other snowflakes and change their size and movement.
Ffmpeg summary lineup
 ffmpeg -f lavfi -i "color=lightblue" \ -vf "drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=10:text='':fontcolor=white:x=sin(n/10)*30:y=3*n,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=16:text='':fontcolor=white:x=cos(n/9)*3+w/3:y=n/2-h/16,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=19:text='':fontcolor=white:x=sin(n/7)*10+w/9:y=n/3-h/20,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=15:text='':fontcolor=white:x=cos(n/25)*20+w/2:y=nh/9,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=20:text='':fontcolor=white:x=sin(n/19)*4+ww/3:y=nh/20,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=17:text='':fontcolor=white:x=cos(n/10)*9+w/7:y=n/2-h/18,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=16:text='':fontcolor=white:x=sin(n/20)*23+ww/7:y=2*nh/15,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=19:text='':fontcolor=white:x=cos(n/15)*15+w/5:y=nh/6,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=20:text='':fontcolor=white:x=sin(n/15)*50+ww/9:y=nh/10,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=12:text='':fontcolor=white:x=cos(n/30)+w/2:y=n*2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=16:text='':fontcolor=white:x=cos(n/9)*3+w/3:y=n/2-h/6,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=19:text='':fontcolor=white:x=sin(n/7)*10+w/9:y=n/4-h/2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=15:text='':fontcolor=white:x=cos(n/25)*20+w/2:y=n/5-h/2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=20:text='':fontcolor=white:x=sin(n/19)*4+ww/3:y=nh/2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=17:text='':fontcolor=white:x=cos(n/10)*9+w/7:y=n/2-h/2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=16:text='':fontcolor=white:x=sin(n/20)*23+ww/7:y=2*nh/3,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=19:text='':fontcolor=white:x=cos(n/15)*15+w/5:y=n/6-h/2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=20:text='':fontcolor=white:x=sin(n/15)*50+ww/9:y=2*nh/2,\ drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf:fontsize=12:text='':fontcolor=white:x=cos(n/22)+w/2:y=2+h"\ -qscale 1 -s 720x560 -t 12 -y snow.mp4 



The video above shows the result of executing this command. Unfortunately, I was not able to force the fontsize parameter to accept the result of the random function as a value, most likely this is not yet supported. Finally, I will point out another nuance with which I encountered - the text parameter also does not accept values ​​of the form text = n. In order to display the frame number, use the construction “text =% {expr \\: n}”. I have everything on it, I hope you have learned something new for yourself.

Source: https://habr.com/ru/post/203314/


All Articles