Change Audio Volume Over Time with FFmpeg sendcmd
This article explains how to dynamically alter the volume of an audio
track at specific timestamps using FFmpeg’s sendcmd filter.
You will learn how to format the command text file, construct the FFmpeg
command line, and apply precise volume transitions to your audio files
without needing to split and re-merge them.
Understanding the
sendcmd and volume Filters
The sendcmd (send command) filter in FFmpeg allows you
to pass commands to other filters at precise time intervals during
processing. When paired with the volume filter, you can
instruct FFmpeg to change the audio level at specific seconds or
frames.
To make this work, the volume filter must be set to
evaluate the volume parameter on every frame using
eval=frame. By default, the volume filter only calculates
the volume level once at the start of the stream.
Step 1: Create the Commands File
The cleanest way to use sendcmd is by writing your
time-based instructions in a separate text file. Create a file named
commands.txt and define your volume changes using the
following syntax:
[time] [filter_target] [parameter] [value];
For example, to start the audio at full volume, drop it to 20% at 2
seconds, and bring it back to full volume at 5 seconds, write the
following inside commands.txt:
0.0 volume volume 1.0;
2.0 volume volume 0.2;
5.0 volume volume 1.0;
0.0/2.0/5.0: The timestamp in seconds (you can also usehh:mm:ssformat).volume: The target filter receiving the command.volume: The specific parameter of the filter to change.1.0/0.2: The value.1.0represents 100% volume, while0.2represents 20% volume. You can also use decibels (e.g.,volume -10dB).
Step 2: Run the FFmpeg Command
Once your commands.txt file is saved in the same
directory, run the following FFmpeg command to apply the changes:
ffmpeg -i input.mp3 -filter_complex "sendcmd=f=commands.txt,volume=eval=frame" output.mp3Command breakdown: * -i input.mp3: Your
input audio file. * -filter_complex: Invokes the filter
graph. * sendcmd=f=commands.txt: Points FFmpeg to your
command file. * volume=eval=frame: Enables the volume
filter and forces it to listen for real-time command updates on a
per-frame basis. * output.mp3: Your processed audio file
with dynamic volume changes.
Alternative: Writing Commands Inline (No File Required)
If you only have one or two quick volume changes, you can write the
commands directly into the terminal string using the c
(command) argument instead of f (file).
Use semicolons to separate multiple commands:
ffmpeg -i input.mp3 -filter_complex "sendcmd=c='2.0 volume volume 0.1; 6.0 volume volume 1.0',volume=eval=frame" output.mp3This inline command keeps the volume at its original level until the 2-second mark, lowers it to 10%, and then restores it to 100% at the 6-second mark.