To create a 1080p black background with centered text using FFmpeg, you must use the color source filter to generate the solid black image and the drawtext filter to overlay the text. The key to centering is calculating the exact X and Y coordinates based on the video resolution (1920x1080) and the font dimensions, rather than relying on automatic alignment flags that may not exist in all versions.
Understanding the Filter Chain
The core of this process relies on chaining two specific filters:color and drawtext. The color filter acts as the source, generating a single frame of solid color. By specifying c=black, we ensure the background is pure black. The resolution is defined by s=1920x1080, which corresponds to standard 1080p Full HD. This frame is then passed into the drawtext filter, which renders the text onto the canvas.
It is crucial to understand that FFmpeg does not have a native "center" parameter for text positioning in older or standard builds. Instead, you must provide explicit coordinates. The coordinate system starts at the top-left corner (0,0). Therefore, to center text horizontally, you need to calculate half the width minus half the text width. Vertically, you calculate half the height minus half the text height. This manual calculation ensures precision across different fonts and sizes.
For more context on generating simple backgrounds, see our guide on Creating a Black Background Image (1920x1080) with FFmpeg.
The Command Structure
The following command demonstrates the complete syntax required to achieve this result. It uses the-f lavfi input flag to treat the filter graph as the source, eliminating the need for an external video file.
ffmpeg -f lavfi -i "color=c=black:s=1920x1080:d=1,drawtext=text='Hello World':fontfile=/path/to/font.ttf:fontsize=60:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2" -frames:v 1 output.png
Let us break down the critical components. The d=1 parameter sets the duration of the generated frame to one second, though since we are outputting a single image (-frames:v 1), this effectively just defines the canvas size. The text parameter specifies the string to render. The fontfile path must be absolute or relative to the working directory; if omitted, FFmpeg attempts to use a default font, which may vary by operating system.
The most important part is the x and y expressions. (w-text_w)/2 calculates the horizontal center by taking the total width (w) and subtracting the width of the rendered text (text_w), then dividing by two. Similarly, (h-text_h)/2 centers the text vertically. This method is robust and works regardless of the text length, provided the font metrics are consistent.
If you are adding non-Latin characters, such as Hindi, refer to Adding Hindi Text to MP4 Video File using FFmpeg for handling complex script rendering.
Common Pitfalls and Troubleshooting
One frequent error is the "Cannot find font" message. This occurs whenfontfile is not specified or points to a non-existent file. On Linux systems, fonts are typically located in /usr/share/fonts/. On Windows, they are in C:\Windows\Fonts\. Always verify the path exists before running the command.
Another issue arises with text clipping. If the calculated coordinates place the text partially outside the 1920x1080 frame, it will be cut off. Ensure your font size is appropriate for the resolution. For 1080p, a font size between 40 and 80 pixels is usually optimal for readability. Using excessively large fonts without adjusting the x and y calculations can lead to visual errors.
Additionally, some users attempt to use box=1 to create a background box behind the text. While this feature exists in newer FFmpeg versions, it is not universally supported and can cause compatibility issues. Stick to the basic drawtext parameters for maximum reliability. If you need a semi-transparent background for the text, consider using the format filter or compositing multiple layers, but for a simple black background, the color filter suffices.
Output Format Considerations
The example above outputs a PNG image. You can change the output extension to JPG or BMP if preferred. When using JPG, note that it does not support transparency, so the black background will remain solid. If you choose to output a video instead of a still image, remove the-frames:v 1 flag and add -t 1 to limit the duration to one second, ensuring the video matches the static nature of the background.
Remember that the lavfi input generates frames on the fly. There is no need to create a temporary video file first. This makes the process efficient and ideal for scripting or automated workflows where you need to generate thumbnails or title cards dynamically.
Frequently Asked Questions
Why is my text appearing in the top-left corner?
This happens because you did not specify the x and y parameters. Without these, FFmpeg defaults to the origin point (0,0). You must include the expressions x=(w-text_w)/2 and y=(h-text_h)/2 to force centering.
Can I use a variable font size and still center the text?
Yes, the text_w and text_h variables are dynamic. They automatically update based on the actual rendered dimensions of the text for the given font and size. As long as you use these variables in your x and y calculations, the text will remain centered regardless of size changes.
How do I change the text color?
Use the fontcolor parameter within the drawtext filter. You can specify colors by name (e.g., white, red) or by hex code (e.g., 0xFFFFFF). For example, fontcolor=yellow will render the text in bright yellow against the black background.
What if I want the text to wrap to multiple lines?
FFmpeg's drawtext does not support automatic word wrapping. You must manually insert newline characters (\n) in your text string. However, vertical centering becomes more complex with multi-line text, as text_h represents the height of the entire block, not individual lines.
Does this work for 4K resolution?
Yes, simply change the s parameter in the color filter to 3840x2160. The x and y expressions will automatically adjust because they rely on the relative width (w) and height (h) of the canvas, not fixed pixel values.