Stop FFmpeg Encoding at Longest Audio Stream
By default, FFmpeg’s -shortest parameter forces output
encoding to stop as soon as the shortest input stream ends. If you are
combining a looped or extended video with multiple audio tracks of
varying lengths, -shortest will prematurely cut off when
the first (shortest) audio track finishes. This article
demonstrates how to configure FFmpeg to stop encoding only when the
longest audio stream finishes, either by mixing streams with
amix or by calculating the maximum duration for separate
tracks.
The Limitation of
-shortest
The -shortest flag monitors all active input streams and
sends an end-of-file (EOF) signal to the encoder as soon as any single
stream reaches its end. If you have a video stream and two audio streams
(e.g., 3 minutes and 5 minutes), -shortest stops processing
at 3 minutes.
Because -shortest cannot natively evaluate conditional
"maximum" lengths among multiple streams, you must use one of the
solutions below depending on whether you want a single mixed audio track
or multiple separate audio tracks.
Method 1:
Mix Audio Tracks Using amix
(duration=longest)
If you want to merge your audio inputs into a single playback track,
use the amix audio filter. By default, amix
sets its duration to longest, keeping the stream alive
until the final audio input finishes.
ffmpeg -stream_loop -1 -i video.mp4 -i audio1.mp3 -i audio2.mp3 -filter_complex "[1:a][2:a]amix=inputs=2:duration=longest[aout]" -map 0:v -map "[aout]" -shortest -c:v copy output.mp4-stream_loop -1 -i video.mp4: Loops the video indefinitely so it is guaranteed to be longer than any audio track.amix=inputs=2:duration=longest: Blends the two audio inputs and pads the shorter track with silence until the longest one ends.-shortest: Halts encoding as soon as the mixed audio stream finishes, cutting off the infinite video loop.
Method
2: Retain Separate Audio Streams Using ffprobe and
-t
If your output file requires multiple separate audio streams (such as
multi-language tracks or commentary tracks), amix cannot be
used. Because -shortest will always exit on the first track
to finish, the standard approach is to extract the duration of the
longest audio track using ffprobe and supply it to
-t instead of using -shortest.
Step 1: Find the duration of each audio file
Run ffprobe to determine the length (in seconds) of each
audio track:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 audio1.mp3
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 audio2.mp3Step 2: Encode using the largest duration value
Take the larger of the two values (for example, 324.5
seconds) and use it with the -t option while looping the
video:
ffmpeg -stream_loop -1 -i video.mp4 -i audio1.mp3 -i audio2.mp3 -map 0:v -map 1:a -map 2:a -t 324.5 -c:v copy output.mp4-t 324.5: Instructs FFmpeg to encode exactly up to the end of the longest audio stream.- The shorter audio stream will simply finish and remain silent for the remainder of the timeline, preserving both tracks without truncating the file early.
Method 3: Pad the
Shorter Audio Stream (apad)
If you must use -shortest without pre-calculating the
duration, you can pad the shorter audio stream with silence so that it
does not trigger -shortest early.
ffmpeg -stream_loop -1 -i video.mp4 -i audio_short.mp3 -i audio_long.mp3 -filter_complex "[1:a]apad[padded_a]" -map 0:v -map "[padded_a]" -map 2:a -shortest -c:v copy output.mp4[1:a]apad[padded_a]: Extends the shorter audio stream indefinitely with silence.-shortest: Because the video is infinite and the short audio is now infinite,audio_long.mp3becomes the only stream with a finite end. FFmpeg stops encoding the momentaudio_long.mp3finishes.