Fix FFmpeg -shortest Option Not Working
The FFmpeg -shortest option is designed to end the
output file as soon as the shortest input stream finishes, which is
highly useful when combining audio and video of different lengths.
However, this option frequently fails, causing the output to render
indefinitely or pad the file with silence or blank frames. This article
explains the underlying causes of this buffering glitch and provides
direct, practical solutions to ensure FFmpeg terminates correctly.
Why the -shortest
Option Fails
The failure of the -shortest flag is almost always
caused by how FFmpeg buffers and interleaves packets from different
input streams.
- Multiplexing Buffers (Interleaving): FFmpeg buffers packets in memory to ensure audio and video are properly interleaved (aligned) in the output container. If one stream ends, FFmpeg may continue waiting for packets from the other stream to fill its buffer before it realizes the shorter stream has actually stopped.
- Infinite Loops (
-loop 1): When looping a single image to match an audio track, the image input is treated as infinite. The frame rate and buffer settings can cause FFmpeg to read too far ahead, preventing the-shortestflag from triggering. - Default Interleave Limits: By default, FFmpeg’s maximum interleave duration is 10 seconds. If the difference between your streams falls within this buffering window, the command will ignore the end of the shorter stream.
How to Resolve the Issue
Solution 1: Use
-max_interleave_delta 0
The most effective way to fix the -shortest issue is to
set the maximum buffering duration for interleaving to zero. This forces
FFmpeg to write packets to the output immediately without waiting for
large buffers to fill, allowing the program to detect the end of the
shortest stream instantly.
Place -max_interleave_delta 0 right before the output
file name:
ffmpeg -loop 1 -i image.jpg -i audio.mp3 -c:v libx264 -c:a aac -shortest -max_interleave_delta 0 output.mp4Solution 2: Set
-shortest_buf_duration
In newer versions of FFmpeg, a specific option called
-shortest_buf_duration controls the buffering limit
specifically for the -shortest flag. By default, this is
set to 10 seconds. Reducing this to a low value (like 1 second or 0.5
seconds) resolves the issue without completely disabling interleaving
optimization.
ffmpeg -loop 1 -i image.jpg -i audio.mp3 -c:v libx264 -c:a aac -shortest -shortest_buf_duration 1.0 output.mp4Solution 3: Use Filter-Level Shortest Parameters
If you are using complex filters (like amix to combine
multiple audio streams), the global -shortest flag can get
bypassed. Instead, use the built-in duration parameter
inside the filter itself.
For example, when mixing audio:
ffmpeg -i video.mp4 -i audio.mp3 -filter_complex "amix=inputs=2:duration=shortest" output.mp4Solution 4: Add the
-fflags nobuffer Option
For real-time streams or cases where input buffering causes sync
issues that break -shortest, you can instruct FFmpeg to
disable input buffering entirely using the -fflags nobuffer
flag at the beginning of your command:
ffmpeg -fflags nobuffer -loop 1 -i image.jpg -i audio.mp3 -c:v libx264 -c:a aac -shortest output.mp4