How to Use FFmpeg -shortest with Complex Filters
When combining multiple audio and video inputs of varying lengths
using FFmpeg’s filter_complex, the output duration can
sometimes exceed expectations. This guide explains how to properly apply
the -shortest option alongside complex filtergraphs to
ensure your output file terminates as soon as the shortest input stream
ends, preventing frozen frames or trailing silence.
The Basic Syntax
By default, FFmpeg will continue rendering until all input streams
are exhausted. To stop the output when the shortest input ends, place
the -shortest flag at the end of your command, right before
the output file name.
Here is a standard example of merging a video and an audio file where the audio is longer than the video:
ffmpeg -i video.mp4 -i long_audio.mp3 -filter_complex "[0:v]copy[v];[1:a]copy[a]" -map "[v]" -map "[a]" -shortest output.mp4In this command, -shortest tells FFmpeg to stop encoding
as soon as video.mp4 reaches its end, even if
long_audio.mp3 has remaining playtime.
Using Filter-Specific Shortest Parameters
Sometimes, global flags like -shortest do not behave as
expected when complex filters process the streams. Certain filters have
their own internal parameter to handle stream termination.
The Overlay Filter
If you are overlaying a short video or image onto a longer background
video, use the shortest=1 option directly inside the
overlay filter:
ffmpeg -i background.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=10:10:shortest=1[outv]" -map "[outv]" output.mp4The Amix Filter
If you are mixing multiple audio streams, the amix
filter uses the duration parameter. Set this to
shortest to stop mixing when the shortest audio input
ends:
ffmpeg -i audio1.mp3 -i audio2.mp3 -filter_complex "amix=inputs=2:duration=shortest[outa]" -map "[outa]" output.mp3Fixing Common Sync and Buffer Issues
A common issue when using -shortest with complex
filtergraphs is that the output file still ends up too long, often with
a frozen frame at the end. This happens because FFmpeg buffers frames to
ensure sync.
To solve this, use the -shortest_buf_duration option.
This tells FFmpeg how far ahead (in seconds) it is allowed to buffer
before forcing the stream to end. Setting this to a low value like
1.0 or 0.5 usually resolves frozen frame
issues:
ffmpeg -i video.mp4 -i audio.mp3 -filter_complex "[0:v]scale=1280:-1[v];[1:a]volume=0.8[a]" -map "[v]" -map "[a]" -shortest -shortest_buf_duration 1.0 output.mp4By combining the global -shortest flag, filter-specific
arguments like shortest=1, and adjusting the buffer
duration, you can successfully control the output duration of any FFmpeg
complex filtergraph.