FFmpeg Drawtext Filter for Overlays, Scrolling Text, Timestamps on Videos

2020-10-233:2218179ottverse.com

Learn FFmpeg's drawtext filter to draw text on video to display text, timestamps, copyright notices, scrolling text, credits, etc. Configure font-style, font-size, position, background-color using…

Learn FFmpeg’s drawtext filter to dynamically overlay text on video and display information such as timecode, frame resolution, watermarks, etc. Also, let’s learn how to configure the font, font-size, position, background-color, alignment, multiple lines, etc. using FFmpeg’s drawtext filter.

Step 0: Ensure your FFmpeg Is Compiled with libfreetype

In order to use drawtext, you needed to have configured FFmpeg with --enable-libfreetype. As per the documentation, you need the following options as well if you want to,

  • enable default font fallback and the font option you need to configure FFmpeg with --enable-libfontconfig.
  • enable the text_shaping option, you need to configure FFmpeg with --enable-libfribidi.

Complete List of Options for drawtext

The complete list of options for drawtext filter can be accessed here. It is far too much for me to explain here, but, if you have any questions, that is the first place you should refer.

In this article, I’ll walk through several common use-cases that should make the concepts easy to understand.

Display Text on the Video using drawtext filter

Here is the commandline and an explanation of the options

ffmpeg -i inputClip.mp4 -vf "drawtext=text='My text starting at 640x360':x=640:y=360:fontsize=24:fontcolor=white" -c:a copy output.mp4

Here,

  • inputClip.mp4 is the input video on which you want to display the text; and the output (containing the text) is to be stored in output.mp4
  • no audio re-encoding as indicated by -c:a copy
  • we use the drawtext filter as indicated by the commands -vf "drawtext=........"
  • text='My text starting at 640x360' is the text that will be shown on the video (you could make it your name for watermarking the video, right?)
  • position of the text
    • x=640:y=360 indicates that the x and y coordinates as 640px and 360px. Also, as a side note, the video’s resolution is 1280x720.
    • font size is 24
    • font color is white

Let’s see how the output looks, shall we?

ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits

A better way to this is to offset the text by the length of the text that you are printing on the screen.

Confused?

If you look at the image above, you’ll see that it starts at the center of the video and extends towards the right.

If you want to center the text itself, then you can subtract the height and width of the rendered text when telling drawtext where to render the text.

Here’s how. You use the command x=(w-text_w)/2:y=(h-text_h)/2 and it will center the text. Here is our new commandline –

ffmpeg -i inputClip.mp4 -vf "drawtext=text='Centered Text':x=(w-text_w)/2:y=(h-text_h)/2:fontsize=24:fontcolor=white" -c:a copy output.mp4

Now, the text looks nice and pretty 🙂

ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits

Fantastic – you now know how to overlay text onto a video using FFmpeg’s drawtext filter. Do you think you can add your own watermark or copyright? Let’s try 🙂

Let’s modify the command as follows to indicate my name and the copyright symbol.

ffmpeg -i inputClip.mp4 -vf "drawtext=text='© Krishna':x=640:y=360:fontsize=24:fontcolor=white" -c:a copy output.mp4

This produces an output like this – looks good right? You can play around with the x and y coordinates to align the text the way you want to.

ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits

Adding Text with Background Color using FFmpeg’s drawtext filter

To add a background color, we need

ffmpeg -i inputClip.mp4 -vf "drawtext=text='© Krishna':x=(1100-text_w):y=(600-text_h):fontsize=32:fontcolor=black:box=1:[email protected]: boxborderw=5" -c:a copy output.mp4

The new commands here are –

  • box : this is either 1 (enabled) or  (disabled)
  • boxcolor: [email protected] implies a white colored box with a 50% opacity.
  • boxborderw is the width of the box’s border and the border color is taken from boxcolor.

And there you have it, text with a background. In this example, I switched the color of the text to black so that it contrasts well with a light background bounding box (which in-turn contrasts well with a dark background.)

ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits

Displaying TimeCodes / TimeStamps using FFmpeg’s drawtext filter

This is a very useful application of the drawtext filter and is used in demonstrating low-latency applications or visual quality testing so that one knows precisely what the timestamps/timecodes are at each time.

ffmpeg -i inputClip.mp4 -vf "drawtext=text='timestamp: %{pts \: hms}': x=500: y=500: fontsize=32:[email protected]: box=1: [email protected]" -c:a copy output.mp4

This uses the timestamp and pts options to display time in hour:min:sec format using the hms format specifier. The notations and formatting are complex in my opion! So, a lot of trial and error might be needed before you format your display correctly.

Here is how the video looks. Hope Vimeo shows you the video without a lot of delay 🙂

And here is the same command, but using the flt option to provide microsecond time accuracy! Fancy 🙂

ffmpeg -i inputClip.mp4 -vf "drawtext=text='timestamp: %{pts \: flt}': x=500: y=500: fontsize=32:[email protected]: box=1: [email protected]" -c:a copy output.mp4
ffmpeg-drawtext-filter-dynamic-overlays-timecode-scrolling-text-credits

Display Movie Credits using FFmpeg’s drawtext filter

Finally, let’s learn how to show a movie’s credits using the draw text filter. Here are two main concepts that you need to understand.

  • providing a lot of text: you can’t do this via the commandline, so, you need to read a text file that contains the text. And you can read that using the textfile option.
  • and, specify the speed of scrolling using the y text position. Here, you can provide an equation instead of a constant number. You start off by telling by FFmpeg that the y-position is h - 80*t so that everytime the value of time increases, the value of h - 80*t* decreases, and the text is displayed higher. Makes sense?

Tip: change 80 to 100 or 120 and see the effect on the scrolling speed.

ffmpeg -i inputClip.mp4 -vf "drawtext=textfile=credits.txt: x=200: y=h-80*t: fontsize=36:[email protected]: box=1: [email protected]" -c:a copy outputCredits.mp4

Here is the output:

That’s it for this tutorial on using FFmpeg’s drawtext filter to produce dynamic overlays on your videos. It is a very versatile and handy tool that you can use to overlay text, timecodes, credits, copyrights notices on your videos.

If you are interested in video compression, check out our comparison of LCEVC (MPEG5 Part 2) vs H.264/AVC. Stunning results, I tell you 🙂

lcevc avc ffmeg
krishna rao vijayanagar

Read the original article

Comments

  • By dqv 2020-10-2312:353 reply

    Here's mine for doing crab videos

        ffmpeg -ss 66 -i crab.mp4 -t 30 -crf 27 -preset veryfast -vf "drawtext=fontfile=/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf:text='YOUR TEXT HERE':fontcolor=white:fontsize=240:shadowx=5:shadowy=5:box=1:boxcolor=black@0.0:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2:enable='between(t,9,30)',scale=iw/3:ih/3" -c:v libx264 -filter:a "volume=0.2" -c:a libmp3lame output.mp4
    
    You just need to get the original crab rave video from youtube: https://www.youtube.com/watch?v=LDU_Txk06tM

    You might also need to supply your own font path I'm not sure how universal they are.

    • By dmd 2020-10-2316:302 reply

      If you don't mind my asking... what's a crab video

      • By dqv 2020-10-2318:11

        You afix a caption describing an unfortunate scenario onto the song for comical juxtaposition, since the Crab Rave song itself is jovial sounding. For example, one might add the caption "I got fired".

    • By jjice 2020-10-2314:311 reply

      When I switched to Linux and started using FFmpeg, the idea of automating video production (this thing that was so time intensive in my mind) was so appealing. This is an awesome little example. What a damn good piece of software.

      • By ralph87 2020-10-2319:15

        Just wait until you try out Gstreamer

        (and suffer a few weeks learning it! I don't even remember C++ being so painful)

    • By FR10 2020-10-2315:411 reply

      I downloaded the video (720p) and I have to tweak slightly the command to make it work on MacOS Catalina (FFmpeg installed via brew)

        ffmpeg -ss 66 -i crab.mp4 -t 30 -crf 27 -preset veryfast \
        -vf "drawtext=fontfile=~/Library/Fonts/SF-Compact-Display-Bold.otf:text='YOUR TEXT HERE':fontcolor=white:fontsize=68:shadowx=5:shadowy=5:box=1:boxcolor=black@0.0:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2:enable='between(t,9,30)'" \
        -c:v libx264 -filter:a "volume=0.2"  output.mp4
      
      Thank you very much, crazy how powerful but hard is FFmpeg.

      • By dqv 2020-10-2315:52

        Ah yes! Sorry the settings I posted are for the original crab rave music video in 4k.

  • By est 2020-10-236:299 reply

    My experience with fmpeg is like a DSL embedded into another DSL. It's very powerful yet confusing at times. I saved a ton of ffmpeg one-liners in a notebook just in case.

    • By antihero 2020-10-239:05

      FWIW when I asked about doing something on IRC (splitting a stream, process one, and overlay it over the existing one at 20%), they were quite helpful.

      It was: `split[a][b];[b]lut3d=${path}[c];[a][c]blend=all_mode=overlay:all_opacity=${opacity}`

    • By demomode 2020-10-2310:202 reply

      I find gstreamer (using gst-launch)[1] a more pleasant experience than ffmpeg.

      You can't use some expresions on the command line like `x=(w-text_w)/2:y=(h-text_h)` but it can be workaround with some scripting using python bindings for example.

      Some (simple) text overlay can be acomplished with:

        gst-launch filesrc location=sample.mp4 \
          ! decodebin \
          ! videoconvert \
          ! textoverlay text="Hello" font-desc="Sans Bold 150px" y-absolute=0.5 \
          ! autovideosink
      
      
      1. http://manpages.org/gst-launch

      • By kingosticks 2020-10-2313:162 reply

        They also have very cool support for HTML overlays: https://base-art.net/Articles/web-overlay-in-gstreamer-with-...

        • By potench 2020-10-2315:28

          Looks like BBC’s Brave project was the inspiration for this: https://github.com/bbc/brave (specifically the gst-WebRenderSrc) Brave is a real-time remote video/audio editing app. Looks neat.

          Unrelated but wow, BBC has quite a bit of interesting and relevant open source projects. Simorgh, their react SSR framework, caught my eye “used on some of our biggest websites”. Encouraging for those looking to build out performance react/amp platforms https://github.com/bbc/simorgh

        • By iso1210 2020-10-2317:17

          I used CasparCG[0] to do live html overlays with a major broacaster out of Singapore about 5 years ago, still going strong. The actual on air graphics that were used rather tame compared with the sample ones I did to prove the system.

          [0] https://github.com/CasparCG/

      • By dylan604 2020-10-2315:451 reply

        Why do you say you can't do expressions like that on the command line? I do it all of the time. You have to escape the parentheses, but other than that it is totally doable.

        • By demomode 2020-10-2317:59

          You can't use expressions like that (from ffmpeg cmld) in gst-launch.

          As far as I know in gst-launch you can't access properties from one element (video stream width) in other elements.

    • By iso1210 2020-10-2310:46

      Yes, and the best part is everything is turned into command line arguments.

      ffmpeg of 15 years ago was confusing, but now it's so simple - to compile, to add your own filters, and to use, they've done a great job.

    • By pfortuny 2020-10-236:39

      Yes, same here. The big problem is that the filters DSL is probably too complex because it uses too many short expressions.

      It is unbelievably powerful though.

    • By ponderingfish 2020-10-236:411 reply

      Very true. And, the parameters change over time, but, the stackoverflow answers using the old parameters remain on top. This IMO adds to the confusion :)

      • By _Gyan_ 2020-10-237:201 reply

        Yes, the stackexchange (implicit) model contributes to this. It assumes once a Q has been asked and answered, the issue is resolved. Due to the non-duplicates policy, any corrections or updates are supposed to be added to the same thread. But the original accepted answer will have a tick mark next to it and likely a high score. So naive users don't read further and the obsolete answers remain heeded.

        Some sort of deprecation or salience decay needs to be added.

        • By madeofpalk 2020-10-239:461 reply

          You can edit the accepted answer!

          • By _Gyan_ 2020-10-2310:12

            I don't like to mix voices - that's inorganic when the changes are more than minor and can lead to parts of the 'answer' being at odds with itself.

            Except for typos, syntax..etc, I don't edit someone else's answer; I leave a comment and let the original respondent edit.

    • By emarsden 2020-10-2310:31

      Indeed. I use libraries such as MoviePy* that wrap ffmpeg and allow you to implement effects on each frame.

      * https://zulko.github.io/moviepy/index.html

    • By modernlearner 2020-10-2313:06

      Seems like everyone has a notebook of ffmpeg commands: https://hhsprings.bitbucket.io/docs/programming/examples/ffm...

    • By raverbashing 2020-10-237:261 reply

      Yes

      And the worse part is everything is turned into command line arguments

      It would be easier if you could specify it in something more human readable like (sigh) yaml

      • By est 2020-10-238:41

        someone need to make a GPT-3 to ffmpeg commands converter

    • By Hamuko 2020-10-237:40

      I wrote a small Python front-end for ffmpeg just so I can do some of my most common video encoding tasks done without Google.

  • By vianneychevalie 2020-10-237:111 reply

    I am not a native English speaker and needed a translation for OTT (Over The Top). Here's a link from this very website (hard to find):

    https://ottverse.com/what-is-ott-video-streaming/

    • By mcdoh 2020-10-2313:411 reply

      It's confusing for native English speakers as well.

      • By iso1210 2020-10-2317:19

        I'm a broadcast engineer with 15 years of experience, and before that experience doing web broadcasting before things like youtube existed.

        I still get confused by the terminology.

HackerNews