Understanding the Drawtext Filter
The drawtext filter is one of FFmpeg's most powerful overlay capabilities, allowing you to render text onto video frames dynamically. While it supports static positioning using fixed pixel values, achieving motion requires the use of expressions. These expressions are evaluated for each frame, enabling complex behaviors like sliding, fading, or pulsing text based on time, audio levels, or other variables.
To implement a sliding effect, you must understand how the coordinate system works. The origin (0,0) is typically the top-left corner of the output video. The x parameter controls the horizontal position, while y controls the vertical position. For a horizontal slide, you will primarily manipulate x, keeping y constant to maintain a steady height on the screen.
Constructing the Time-Based Expression
The core of any sliding text animation lies in the mathematical relationship between time and position. FFmpeg provides a built-in variable called t, which represents the timestamp of the current frame in seconds. You can combine this with a speed factor to determine where the text should appear at any given moment.
A basic linear expression looks like this: x = w + (t - start_time) * speed. Here, w represents the width of the video stream. This formula starts the text off-screen to the right (at position w) and moves it leftward by subtracting distance over time. Alternatively, if you want the text to enter from the left and move right, you would use: x = -text_w + t * speed.
In these expressions, text_w is a special variable that automatically calculates the width of the rendered text string. Using text_w ensures that your text does not overlap awkwardly with itself or disappear prematurely, regardless of the font size or content length. This dynamic calculation is crucial for maintaining visual consistency across different resolutions and text lengths.
Setting the Speed Parameter
The speed parameter determines how many pixels the text moves per second. A higher value results in faster movement, while a lower value creates a slow, gentle drift. Common speeds range from 50 to 200 pixels per second, depending on your video resolution and desired aesthetic. For example, in a 1920x1080 video, a speed of 100 means the text travels half the screen width every second.
Implementing the Command Line Syntax
Putting it all together, the FFmpeg command structure involves specifying the input file, applying the filter, and defining the output. Below is a robust example that slides text from right to left, entering smoothly and exiting cleanly.
ffmpeg -i input.mp4 -vf "drawtext=text='Sliding Text Example':fontfile=/path/to/font.ttf:fontsize=48:fontcolor=white:x=w+10-(t*100):y=H/2" -c:a copy output.mp4
Let's break down the critical components of this command. The -vf flag invokes the video filter chain. Inside the quotes, text='...' defines the content. fontfile points to a valid TrueType font on your system; omitting this may cause errors if the default font is unavailable. fontsize and fontcolor handle the styling.
The magic happens in the x parameter: w+10-(t*100). This starts the text just outside the right edge (w) plus a small buffer (10 pixels), then subtracts 100 pixels for every second that passes (t*100). The y parameter is set to H/2, centering the text vertically relative to the video height. The -c:a copy flag ensures the audio stream is copied without re-encoding, speeding up the process significantly.
Refining the Animation with Easing
Linear movement can sometimes feel robotic. To add polish, you can incorporate easing functions using trigonometric operations or conditional logic. For instance, you might want the text to fade in before it starts moving, or to stop at a specific point rather than flying off-screen.
You can achieve conditional behavior using the if() expression syntax. For example, to make the text visible only between the 5th and 10th second:
x='if(lte(t,5), -100, if(lte(t,10), w-(t-5)*100, w+100))'
This complex expression checks the current time t. If t is less than or equal to 5, it holds the text off-screen to the left. Between 5 and 10 seconds, it applies the sliding math. After 10 seconds, it pushes the text back off-screen to the right. This level of control allows for professional-grade intros, lower thirds, and dynamic captions.
For more advanced users, combining drawtext with other filters like fade can enhance the visual appeal further. You can chain filters using commas within the -vf argument, such as -vf "drawtext=..., fade=t=in:st=0:d=1" to fade the text in during its first second of appearance.
Troubleshooting Common Issues
If your text does not appear, verify that the font file path is correct and accessible. FFmpeg requires absolute paths or paths relative to the working directory. Additionally, ensure that the font supports the characters you are trying to display; standard ASCII fonts may not render emojis or non-Latin scripts correctly.
If the movement is jittery, check your frame rate. Expressions rely on accurate timestamps, so ensuring consistent frame rates in both input and output helps maintain smooth motion. Use -r 30 or -r 60 in your output flags if necessary to enforce a specific frame rate.
Frequently Asked Questions
How do I make the text slide from left to right instead?
Change the x expression to increase over time rather than decrease. Use a formula like x=-text_w+t*speed to start off-screen on the left and move toward the right edge. Ensure you account for the text width so it doesn't jump into view abruptly.
Can I use drawtext to scroll multiple lines of text?
Yes, but you need to calculate the total height of the text block. Use the n variable for line numbers or manually define line breaks with \n. Adjust the y parameter dynamically based on the line index to stack them vertically while sliding horizontally.
Why is my text flickering or disappearing intermittently?
This usually happens when the expression evaluates to negative values or values exceeding the video dimensions unexpectedly. Check your bounds in the if() statements and ensure that text_w is correctly calculated. Adding clamping functions like between() can help stabilize the position.
Does this method work with transparent backgrounds?
Yes, FFmpeg supports alpha channels. Use format=rgba in your output codec settings and ensure your font color includes an alpha component, such as [email protected]. This allows the text to blend seamlessly over varying background colors without a solid box behind it.
How can I pause the text in the middle of the screen?
Modify the x expression to hold the value constant after a certain time. For example, x=if(gt(t,5), w/2-text_w/2, -text_w+(t*100)) will slide the text until the 5-second mark, then keep it centered until the end of the clip or another condition triggers.