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.mp4

Method 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.mp4

In 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.mp4

In 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.