How to Use FFmpeg sendcmd Filter for Runtime Commands

This article provides a practical guide on how to use the FFmpeg sendcmd filter to send commands to other filters during runtime. You will learn the syntax of command files, how to apply changes at specific timestamps, and see concrete examples of dynamically updating filters like drawtext and volume without needing to split your video into multiple segments.

Understanding the sendcmd Filter

The sendcmd filter reads a list of commands and dispatches them to other filters in your filtergraph when the video playback reaches specified timestamps. This allows you to change parameters—such as text content, volume, position, or opacity—dynamically during processing.

You can feed commands to the filter in two ways: 1. From an external text file (using the f parameter, recommended for complex sequences). 2. Directly inside the command line (using the c parameter, ideal for quick, simple changes).


Command Syntax

Whether written in a file or inline, each command must follow this specific format:

time [target] command arguments;

Using an external file keeps your terminal command clean and avoids complex character escaping issues.

Step 1: Create the Command File

Create a plain text file named commands.txt and define your timeline:

2.0 drawtext reinit text='First text update';
5.0 drawtext reinit text='Second text update';
8.5 drawtext reinit text='Final text update';

Step 2: Run the FFmpeg Command

Reference the file using sendcmd=f=commands.txt before the filter you want to control in your filtergraph:

ffmpeg -i input.mp4 -vf "sendcmd=f=commands.txt,drawtext=fontfile=Arial.ttf:text='Starting Text':x=w/2-text_w/2:y=h/2-text_h/2:fontsize=24:fontcolor=white" -c:a copy output.mp4

Method 2: Using Inline Commands

For simple, single-command changes, you can write the command directly in your command line using the c parameter. Note that you must escape internal quotes carefully.

ffmpeg -i input.mp4 -vf "sendcmd=c='3.0 drawtext reinit text=\'Dynamic Inline Text\'',drawtext=text='Original Text':x=10:y=10" -c:a copy output.mp4

Targeting Specific Filters (Using Instances)

If you use multiple instances of the same filter (for example, two different text overlays), you must assign an identifier using @ to ensure the command reaches the correct target.

Example: Control distinct text tracks

In your command line, assign names to your filters:

ffmpeg -i input.mp4 -vf "sendcmd=f=commands.txt,drawtext@top=text='Top Line':y=50,drawtext@bottom=text='Bottom Line':y=400" -c:a copy output.mp4

In your commands.txt file, target those specific names:

3.0 drawtext@top reinit text='New Top Text';
6.0 drawtext@bottom reinit text='New Bottom Text';

Real-World Example: Dynamic Audio Volume Control

The sendcmd filter works seamlessly with audio filters too (via asendcmd). This example lowers the audio volume to 10% at the 3-second mark and restores it to 100% at the 8-second mark.

Create audio_commands.txt:

3.0 volume reinit volume=0.1;
8.0 volume reinit volume=1.0;

Run FFmpeg command:

ffmpeg -i input.mp4 -af "asendcmd=f=audio_commands.txt,volume=1.0" -c:v copy output.mp4