Text on video ffmpeg

109,997

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

Text centered on video

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:

Moving / animated / looping / scrolling text

See:

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
Share:
109,997
Admin
Author by

Admin

Updated on July 08, 2022

Comments

  • Admin
    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
    Noah Ternullo about 10 years
    Thank 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
    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
    Janki Gadhiya about 8 years
    Unable to find suitable output format for 'text='Stack'. Getting this error please help me..!!
  • llogan
    llogan about 8 years
    @jankigadhiya I can't help without seeing your actual command and the complete console output.
  • Janki Gadhiya
    Janki Gadhiya about 8 years
    @LordNeckbeard see my question here :stackoverflow.com/q/37404476/6127411. And please help me if you can.
  • Chinmay235
    Chinmay235 almost 8 years
    Thanks 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
    llogan almost 8 years
    @chovy Your ffmpeg needs to be built with --enable-libfreetype.
  • chovy
    chovy almost 8 years
    fyi, for those installing with brew, you can pass that flag --with-libefreetype to the install command.
  • Ferguson
    Ferguson over 7 years
    Have tryed on Armbian: ffmpeg -i rtsp://mpv.cdn3.bigCDN.com:554/bigCDN/definst/mp4:bigbuckbun‌​nyiphone_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
    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 as output.mp4? I know nothing of FFM (FFserver live feed), so I won't be helpful for anything to do with ffserver.
  • Rico Picone
    Rico Picone over 7 years
    @chovy I think the homebrew option you mentioned should be --with-freetype
  • Kishore Jethava
    Kishore Jethava about 6 years
    @LordNeckbeard can you please look into this thread
  • llogan
    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
    Eftekhari over 5 years
    @llogan Thanks.
  • deFreitas
    deFreitas about 4 years
    add :enable='between(t,00:00:15,00:00:20) to specify the text duration, something like ffmpeg -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
    Vivek Thummar almost 4 years
    I 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
    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
    Vivek Thummar almost 4 years
    I have created pastebin account and posted code there,check out it - pastebin.com/iupjh8Cx
  • llogan
    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
    Vivek Thummar almost 4 years
    I tried your solution and i got some error can you please check pastebin url again because i updated my command there!
  • llogan
    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.