How to Use FFmpeg xfade for Video Transitions

This guide provides a direct walkthrough on merging two video clips with custom transition effects using FFmpeg's xfade filter. You will learn the fundamental command structure, how to correctly calculate the transition timing offset, how to synchronize audio using acrossfade, and how to resolve common input mismatches.

Basic Syntax and Parameters

The xfade filter blends two video streams together over a set duration. The basic filter syntax requires specifying the transition type, the transition duration, and the start offset:

xfade=transition=NAME:duration=D:offset=OFFSET
  • transition: The visual effect to apply (e.g., fade, wipeleft, slideup, circleopen, dissolve).
  • duration: The length of the transition effect in seconds.
  • offset: The exact timestamp (in seconds) in the first video where the transition begins.

Calculating the Offset

The offset parameter is critical. It must be set to the duration of the first video minus the duration of the transition:

\[\text{Offset} = \text{Duration of Video 1} - \text{Transition Duration}\]

For example, if the first video is 10 seconds long and you want a 1-second transition, the transition must begin at the 9-second mark (offset=9).

Complete Command Example with Audio

To create a clean cut that includes both video and audio transitions, use xfade for video and acrossfade for audio:

ffmpeg -i first.mp4 -i second.mp4 -filter_complex \
"[0:v][1:v]xfade=transition=fade:duration=1:offset=9[v]; \
 [0:a][1:a]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" output.mp4

In this command:

  • [0:v][1:v] routes the video streams of both inputs into the xfade filter.
  • [0:a][1:a] routes both audio streams into acrossfade with a matching 1-second overlap (d=1).
  • -map "[v]" and -map "[a]" assign the processed streams to the final output file.

Handling Different Resolutions and Frame Rates

The xfade filter requires both input videos to have identical dimensions, pixel formats, time bases, and frame rates. If your input videos differ, standardize them inside the filter_complex graph before applying xfade:

ffmpeg -i first.mp4 -i second.mp4 -filter_complex \
"[0:v]settb=AVTB,fps=30,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,format=yuv420p[v0]; \
 [1:v]settb=AVTB,fps=30,scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,format=yuv420p[v1]; \
 [v0][v1]xfade=transition=wipeleft:duration=1:offset=9[v]; \
 [0:a][1:a]acrossfade=d=1[a]" \
-map "[v]" -map "[a]" output.mp4

Available Transition Types

FFmpeg supports dozens of transition names for the transition option. Some of the most commonly used include:

  • fade / fadeblack / fadewhite
  • wipeleft / wiperight / wipeup / wipedown
  • slideleft / slideright / slideup / slidedown
  • smoothleft / smoothright / smoothup / smoothdown
  • circlecrop / circleclose / circleopen
  • dissolve
  • pixelize
  • radial
  • hblur