How to use FFmpeg sendcmd to move text overlay
This article explains how to dynamically change the position of a
text overlay in a video using FFmpeg’s sendcmd filter. You
will learn how to structure command files, define time-based triggers,
apply these commands to the drawtext filter to create
moving text, and use both external command files and inline
commands.
Understanding sendcmd and drawtext
The sendcmd filter reads a list of commands and passes
them to other filters in the filtergraph at specified timestamps. To
change the position of text over time, you couple sendcmd
with the drawtext filter, utilizing the reinit
command supported by drawtext.
The reinit command allows you to re-evaluate parameters
like coordinate positions (x and y), font
size, or even the text string itself at specific intervals.
Method 1: Using an External Command File
Using an external text file is the cleanest way to manage multiple position changes.
Step 1: Create the Command File
Create a text file named commands.txt and define the
times and coordinates. The syntax for each line is:
[timestamp] [target_filter] [command] [arguments];
0.0 drawtext reinit x=50:y=50;
2.0 drawtext reinit x=200:y=100;
4.0 drawtext reinit x=400:y=300;
6.0 drawtext reinit x=100:y=400;
In this file: * At 0.0 seconds, the text starts at coordinates (50, 50). * At 2.0 seconds, the text instantly jumps to (200, 100). * At 4.0 seconds, the text jumps to (400, 300). * At 6.0 seconds, the text jumps to (100, 400).
Step 2: Run the FFmpeg Command
Reference the command file using the f parameter of the
sendcmd filter:
ffmpeg -i input.mp4 -vf "sendcmd=f=commands.txt,drawtext=text='Spoken Word':fontcolor=white:fontsize=24" -c:a copy output.mp4Method 2: Using Inline Commands
If you only have a few position changes and prefer not to use an
external file, you can pass the commands directly inside the FFmpeg
filtergraph using the c parameter.
When writing inline commands, you must escape the colons
(:) used in the reinit arguments with a
backslash (\:), as FFmpeg uses colons to separate filters
and main filter arguments.
Here is the inline equivalent of the command:
ffmpeg -i input.mp4 -vf "sendcmd=c='2.0 drawtext reinit x=200\:y=100; 4.0 drawtext reinit x=400\:y=300',drawtext=text='Spoken Word':x=50:y=50:fontcolor=white:fontsize=24" -c:a copy output.mp4In this command, the text starts at the default
x=50:y=50 defined in the drawtext filter, then
changes to the new coordinates at 2.0 and 4.0 seconds.
Smooth Transitions vs. Hard Jumps
The sendcmd filter performs instantaneous parameter
updates, resulting in sudden jumps. If you require smooth, continuous
movement (like a scrolling ticker or a diagonal slide), you do not need
sendcmd. Instead, write mathematical expressions directly
inside the drawtext filter’s x and
y parameters using the t (time in seconds)
variable:
ffmpeg -i input.mp4 -vf "drawtext=text='Smooth Motion':x='50+t*100':y='50+t*50':fontcolor=white:fontsize=24" -c:a copy output.mp4In this smooth movement example, the text moves 100 pixels
horizontally and 50 pixels vertically every second. Use
sendcmd when you need timed, step-by-step cue changes, and
mathematical expressions when you need constant animation.