How to Use FFmpeg xfade with Multiple Videos
Applying transitions between multiple videos in FFmpeg can be
challenging because the xfade filter only accepts two video
inputs at a time. This article provides a clear, step-by-step guide on
how to chain multiple xfade filters together to transition
three or more videos, including how to calculate the correct offsets and
transition durations for seamless video editing using the command
line.
The Logic of Chaining xfade
Because xfade only transitions between two inputs, to
merge three or more videos you must chain the filters sequentially. This
means you transition Video 1 and Video 2 to create a temporary video
stream, and then transition that temporary stream with Video 3, and so
on.
To do this successfully, you must calculate the exact start time
(offset) for each subsequent transition.
The Offset Calculation Formula
The formula to calculate the offset for any transition in the chain is:
\[\text{Offset}_n = \text{Offset}_{n-1} + \text{Duration of the incoming video} - \text{Transition Duration}\]
For the very first transition, the offset is simply:
\[\text{Offset}_1 = \text{Duration of Video 1} - \text{Transition Duration}\]
Step-by-Step Example with Three Videos
Let’s assume you have three videos, each exactly 10 seconds long, and you want a 1-second fade transition between them.
- First Transition (Video 1 + Video 2):
- Video 1 duration = 10s
- Transition duration = 1s
- Offset 1 = \(10 - 1 = 9\) seconds.
- This creates a merged stream of \(10 + 10 - 1 = 19\) seconds.
- Second Transition (Merged Stream + Video 3):
- Merged stream duration before this transition starts = 19s
- Incoming Video 3 duration = 10s
- Transition duration = 1s
- Offset 2 = \(\text{Offset 1} + \text{Video 2 duration} - \text{Transition duration}\)
- Offset 2 = \(9 + 10 - 1 = 18\) seconds.
The FFmpeg Command
Here is the FFmpeg command to execute this three-video chain using
filter_complex:
ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -filter_complex \
"[0:v][1:v]xfade=transition=fade:duration=1:offset=9[v01]; \
[v01][2:v]xfade=transition=fade:duration=1:offset=18[outv]" \
-map "[outv]" output.mp4How the Command Works
-i video1.mp4 -i video2.mp4 -i video3.mp4: Imports the three source video files as streams0:v,1:v, and2:v.[0:v][1:v]xfade=...[v01]: Fades Video 1 into Video 2 at the 9-second mark for 1 second. The output of this transition is labeled as a temporary stream[v01].[v01][2:v]xfade=...[outv]: Takes the temporary stream[v01]and transitions it into Video 3 at the 18-second mark. The final video output is labeled[outv].-map "[outv]": Tells FFmpeg to write the final processed video stream to the output file.
Scaling to Four or More Videos
To add a fourth 10-second video with a 1-second transition, you would
add a third xfade step. The offset would be \(18 + 10 - 1 = 27\) seconds.
ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -i video4.mp4 -filter_complex \
"[0:v][1:v]xfade=transition=fade:duration=1:offset=9[v01]; \
[v01][2:v]xfade=transition=fade:duration=1:offset=18[v02]; \
[v02][3:v]xfade=transition=fade:duration=1:offset=27[outv]" \
-map "[outv]" output.mp4By following this mathematical progression, you can chain an
unlimited number of videos using the FFmpeg xfade
filter.