Text on video ffmpeg
Solution 1
Use the drawtext filter for simple text on video. If you need more complex timing, formatting, or dynamic text see the subtitles filter. This answer focuses on the drawtext filter.
Example
Print Stack Overflow
in white text onto center of video, with black background box of 50% opacity:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2" -codec:a copy output.mp4
- The audio is stream copied in this example (like a copy and paste).
-
@0.5
controls background box opacity. 0.5 is 50%. Remove@0.5
if you do not want any transparency. - See the drawtext filter documentation for a complete list and explanations of options.
Preview
You can use ffplay
to preview your text without having to wait for a file to encode:
ffplay -vf "drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2" input.mp4
Alternatively you can use mpv
but the syntax is slightly different:
mpv --vf="lavfi=[drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2]" input.mp4
Multiple texts
You can chain multiple drawtext filters:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2,drawtext=fontfile=/path/to/font.ttf:text='Bottom right text':fontcolor=black:fontsize=14:x=w-tw-10:y=h-th-10" -codec:a copy output.mp4
Position
x
and y
determine text position:
Position |
x :y
|
With 10 px padding |
---|---|---|
Top left | x=0:y=0 |
x=10:y=10 |
Top center | x=(w-text_w)/2:y=0 |
x=(w-text_w)/2:y=10 |
Top right | x=w-tw:y=0 |
x=w-tw-10:y=10 |
Centered | x=(w-text_w)/2:y=(h-text_h)/2 |
|
Bottom left | x=0:y=h-th |
x=10:y=h-th-10 |
Bottom center | x=(w-text_w)/2:y=h-th |
x=(w-text_w)/2:y=h-th-10 |
Bottom right | x=w-tw:y=h-th |
x=w-tw-10:y=h-th-10 |
Random | See this answer |
Repositioning text on demand
You can reposition the text with the sendcmd and zmq filters:
- sendcmd if you have predetermined positions and timing. See Sendcmd in ffmpeg and FFmpeg drawtext filter - is it possible to use variables with live data for x,y coordinates?
- zmq for live, on-the-fly positioning. See ffmpeg cli filter that require user input.
Moving / animated / looping / scrolling text
See:
- ffmpeg moving text drawtext
- Loop text that wipes left to right using FFMPEG drawtext filter
- Scrolling from RIGHT to LEFT in ffmpeg / drawtext
Timing
Use the enable
option to control when the text appears.
Show text between 5-10 seconds:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2:enable='between(t,5,10)'" -codec:a copy output.mp4
Show text after 3 seconds:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2:enable='gte(t,3)'" -codec:a copy output.mp4
Blinking text. For every 10 seconds show text for 5 seconds:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:text='Stack Overflow':fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2:enable='lt(mod(t,10),5)'" -codec:a copy output.mp4
Random position every 30 seconds:
See ffmpeg - Dynamic letters and random position watermark to video?
Changing / updating text
Add the textfile
and reload
options for drawtext:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:textfile=text.txt:reload=1:fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2" -codec:a copy output.mp4
- Update
text.txt
every time you want the text to change. -
Important: You must update the text file atomically or it may fail. You can do this with the
mv
command on Linux or macOS. - If you have many text changes, such as making subtitles, it is easier to make a subtitle file (such as an
.ass
file via Aegisub) and using the subtitles filter.
Font family instead of font file
You can declare the font family, such as Times New Roman, instead of having to point to a font file. See How to include font in FFMPEG command without using the fontfile option?
Requirements
The drawtext filter requires ffmpeg
to be compiled with --enable-libfreetype
. If you get No such filter: 'drawtext'
it is missing --enable-libfreetype
. Most of the ffmpeg
static builds available support this: see the FFmpeg Download page for links.
Solution 2
On macOS with enable='between(t,0,10)'
On macOS the syntax of enable='between(t,start_second, end_seconds)' is different. Input should be in seconds, not in hh:mm:ss.
My ffmpeg version 4.3.1
ffmpeg -i input.mp4 -vf "drawtext=text='My Text':enable='between(t,20,120)': x=(w-text_h)/2: y=(h-text_h)/2: fontsize=32: fontcolor=white: box=1: [email protected]: boxborderw=5:" -c:a copy output.mp4
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on July 08, 2022Comments
-
Admin almost 2 years
How can I add text overlay on my video in ffmpeg?
i.e. given a video "video1.flv", how can I add "StackOverflow" text during the whole video, positioned in the middle of the screen, with white text and a border?
-
Noah Ternullo about 10 yearsThank you. This produces text that is static. Other than date/time features, is there a way to produce an overlay of text that changes (such as a ticker tape at the bottom of the screen) or input from a text stream?
-
rogerdpack about 9 years@NoahTernullo there's also strftime options and "pts" variable you can use. In terms of making it ticker along the bottom, you can probably use some function for x variable value changes based on pts or frame number.
-
Janki Gadhiya about 8 yearsUnable to find suitable output format for 'text='Stack'. Getting this error please help me..!!
-
llogan about 8 years@jankigadhiya I can't help without seeing your actual command and the complete console output.
-
Janki Gadhiya about 8 years@LordNeckbeard see my question here :stackoverflow.com/q/37404476/6127411. And please help me if you can.
-
Chinmay235 almost 8 yearsThanks for answering. But I have faced some problem. How to add special character in my watermark text? Here I posted question. Please answer me - stackoverflow.com/questions/38266469/…
-
llogan almost 8 years@chovy Your
ffmpeg
needs to be built with--enable-libfreetype
. -
chovy almost 8 yearsfyi, for those installing with brew, you can pass that flag
--with-libefreetype
to the install command. -
Ferguson over 7 yearsHave tryed on Armbian: ffmpeg -i rtsp://mpv.cdn3.bigCDN.com:554/bigCDN/definst/mp4:bigbuckbunnyiphone_400.mp4 -vf drawtext="fontfile=/home/projekt/StreamTest/DejaVuSans.ttf: \ text='Stack Overflow': fontcolor=white: fontsize=36: box=1: [email protected]: \ boxborderw=5: x=(w-text_w)/2: y=(h-text_h)/2" -codec:a copy localhost:8090/monitoring1.ffm but I don't get any text in my stream.. also th --enable-libfreetype is present when i run ffmpeg
-
llogan over 7 years@Ferguson Provide a link to a pastebin that shows the complete
ffmpeg
console output. Does it work if you output to a local file such asoutput.mp4
? I know nothing of FFM (FFserver live feed), so I won't be helpful for anything to do withffserver
. -
Rico Picone over 7 years@chovy I think the homebrew option you mentioned should be
--with-freetype
-
Kishore Jethava about 6 years@LordNeckbeard can you please look into this thread
-
llogan over 5 years@Eftekhari I believe RTL is problematic with libfreetype (the library used by drawtext). You may have better results using the subtitles filter with ASS files.
-
Eftekhari over 5 years@llogan Thanks.
-
deFreitas about 4 yearsadd
:enable='between(t,00:00:15,00:00:20)
to specify the text duration, something likeffmpeg -i part02.mp4 -vf drawtext="text='Stack Overflow': fontcolor=white: fontsize=24: box=1: [email protected]: \ boxborderw=5: x=(w-text_w)/2: y=(h-text_h)/2: enable='between(t,00:00:15,00:00:20)" -codec:a copy output.mp4
-
Vivek Thummar almost 4 yearsI tried your command to draw text and it works well but when i increased font size it looks fuzzy just like text drawn in paint without antialias,can you please help me in this problem??
-
llogan almost 4 years@VivekThummar Can you show your command and the complete log? You can use a pastebin site and provide a link in a comment.
-
Vivek Thummar almost 4 yearsI have created pastebin account and posted code there,check out it - pastebin.com/iupjh8Cx
-
llogan almost 4 years@VivekThummar You're scaling after using drawtext. Remove
-s
and use the scale filter before drawtext:-vf scale=1280:720,drawtext=...
-
Vivek Thummar almost 4 yearsI tried your solution and i got some error can you please check pastebin url again because i updated my command there!
-
llogan almost 4 years@VivekThummar It needs to be in the form of
-vf "scale=1920:1080,drawtext=..."
Notice the comma (,
) connecting the filters. The comma is missing in your command being executed. This is a problem with your implementation of the ffmpeg command in android.