Create overlay text with ffmpeg moving in and out
Add static overlay text
I could make appear and disappear easily text for my videos with a box around :
ffmpeg -stats -loglevel error -i in.mp4 -vf "drawtext=text='add overlay where you want': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: x=w*0.05: y=h*0.05: enable='between(t,1,4)'" -vcodec libx264 -x264-params keyint=24:scenecut=0 -c:a copy -y normal.mp4
Here an example with a white background:
w
is the width of the video,x=w*%xpos%
isx=w*0.05
so the position will be at pixel 96 ifw
is 1920 (1920/5=96)h
is the height of the video (same calculation here)between(t,1,4)
means between second 1 to 4- you can also use to add what is in a textfile, which is easier with multiples lines (unfortunately difficult to center really), replace
text='add overlay where you want'
withtextfile=yourtext.txt
The position of the text with be taken on the top left corner of the text.
Meaning that you can place it anywhere you wish since you can also know the width and height of your text with tw
and th
.
For example you can place this text in:
- top left corner:
x =w*0.05: y=h*0.05
- top center:
x=((w-tw)/2): y=h*0.05
- top right corner:
x=w*0.95-tw: y=h*0.05
- center left:
x=w*0.05: y=h*0.5
- center:
x=((w-tw)/2): y=h*0.5
- center right:
x=w*0.95-tw: y=h*0.5
- bottom left corner:
x=w*0.05: y=h*0.90
- bottom center:
x=((w-tw)/2): y=h*0.90
- bottom right corner:
x=w*0.95-tw: y=h*0.90
Add moving overlay text
You can however add moving text. Using t
(time in second) and the function if
, gte
(greater) or lt
(less).
Here an example:
set time1=2
set time2=7
set timeuser=2,10
set posstay=3
set xpos=0.05
set ypos=0.05
ffmpeg -stats -loglevel error -i input.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-w/10*(t-%time1%-%posstay%)\,if(gte(-w*0.2-tw+w/10*t\,w*%xpos%)\, w*%xpos%\, -w*0.2-tw+w/10*t)): y=h*%ypos%: enable='between(t,%timeuser%)'" -y test.mp4
Some explanations for the easiest corner, the top left corner:
x=if( gte( t, 2+3 ), w * 0.05 - w / 10 * (t - 2 - 3 ), if( gte( -w * 0.2 - tw + w / 10 * t, w * 0.05), w * 0.05, -w * 0.2 - tw + w / 10 * t ) ) : y=h*0.05
- You may need 1
\
to escape a,
in the code - here y does not change, only x change so
y=h*0.05
gte( t, 2+3 )
means ift
(in second) is more than 5, (2 is actually the start of the overlaybetween(t,2,7)
), 3 is that I decided that the overlay will not move during 3 seconds- if yes
w * 0.05 - w / 10 * (t - 2 - 3 )
w * 0.05
5% if the width so pixel 96, the start position of the movement (the end position below)- ` - w / 10 * (t - 2 - 3 )
minus 10% of the width pixel (192) per second (this is when the overlay returns out of the frame) that's why we use
* (t - 2 - 3 )`
- if no
gte( -w * 0.2 - tw + w / 10 * t, w * 0.05), w * 0.05, -w * 0.2 - tw + w / 10 * t ) )
w * 0.05
this is the end position-w * 0.2 - tw + w / 10 * t
this is the first movement- so if the overlay did not reach the end position, do the movement
- and the movement is the same as before but we start outside the frame meaning minus something here minus 20% of the width minus the width of the text
-w * 0.2 - tw
- if yes
You can test of all this with the code below AND you can find a batch file that will ask you the path of your video, the time wanted, the position and the fontsize, making you all in 1 shot what you need —> HERE
The documentation for drawtext
from ffmpeg is really good, you can find it here
Batch code to test it
@echo off
ffmpeg -stats -loglevel error -f lavfi -i color=c=white:s=1920x1080:d=8 -video_track_timescale 24000 -y input.mp4
ffmpeg -stats -loglevel error -i input.mp4 -vf "drawtext=text='add overlay where you want': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: x=w*0.05:y=h*0.05:enable='between(t,1,4)'" -vcodec libx264 -x264-params keyint=24:scenecut=0 -c:a copy -y normal.mp4
set time1=2
set time2=7
set timeuser=2,10
set posstay=3
:: - top left corner:
set xpos=0.05
set ypos=0.05
ffmpeg -stats -loglevel error -i input.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-w/10*(t-%time1%-%posstay%)\,if(gte(-w*0.2-tw+w/10*t\,w*%xpos%)\, w*%xpos%\, -w*0.2-tw+w/10*t)): y=h*%ypos%: enable='between(t,%timeuser%)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - top center:
set xpos=0.5
set ypos=0.05
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: y=if(gte(t\,%time1%+%posstay%)\, h*%ypos%-h/10*(t-%time1%-%posstay%)\,if(gte(-h*0.2-th+h/10*t\,h*%ypos%)\, h*%ypos%\, -h*0.2-th+h/10*t)): x=w*%xpos%: enable='between(t,%timeuser%)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - top right corner:
set xpos=0.95
set ypos=0.05
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=5: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-tw+w/10*(t-%time1%-%posstay%)\,if(lt(w+w*0.2-w/10*t\,w*%xpos%-tw)\, w*%xpos%-tw\, w+w*0.2-w/10*t)): y=h*%ypos%: enable='between(t,2,20)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - center left:
set xpos=0.05
set ypos=0.5
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-w/10*(t-%time1%-%posstay%)\,if(gte(-w*0.2-tw+w/10*t\,w*%xpos%)\, w*%xpos%\, -w*0.2-tw+w/10*t)): y=h*%ypos%: enable='between(t,%timeuser%)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - center right:
set xpos=0.5
set ypos=0.5
set xpos=0.95
set ypos=0.5
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=5: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-tw+w/10*(t-%time1%-%posstay%)\,if(lt(w+w*0.2-w/10*t\,w*%xpos%-tw)\, w*%xpos%-tw\, w+w*0.2-w/10*t)): y=h*%ypos%: enable='between(t,2,20)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - bottom left corner:
set xpos=0.05
set ypos=0.90
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-w/10*(t-%time1%-%posstay%)\,if(gte(-w*0.2-tw+w/10*t\,w*%xpos%)\, w*%xpos%\, -w*0.2-tw+w/10*t)): y=h*%ypos%: enable='between(t,%timeuser%)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - bottom center:
set xpos=0.5
set ypos=0.9
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=10: y=if(gte(t\,%time1%+%posstay%)\, h*%ypos%+h/10*(t-%time1%-%posstay%)\,if(lt(h+h*0.2-h/10*t\,h*%ypos%)\, h*%ypos%\, h+h*0.2-h/10*t)): x=w*%xpos%: enable='between(t,%timeuser%)'" -y test.mp4
del test1.mp4
rename test.mp4 test1.mp4
:: - bottom right corner:
set xpos=0.95
set ypos=0.90
ffmpeg -stats -loglevel error -i test1.mp4 -vf "drawtext=text='youhou': fontcolor=white: fontfile='Arial': fontsize=50: box=1: boxcolor=Black@0.5:boxborderw=5: x=if(gte(t\,%time1%+%posstay%)\, w*%xpos%-tw+w/10*(t-%time1%-%posstay%)\,if(lt(w+w*0.2-w/10*t\,w*%xpos%-tw)\, w*%xpos%-tw\, w+w*0.2-w/10*t)): y=h*%ypos%: enable='between(t,2,20)'" -y test.mp4
del test1.mp4