FFmpeg xfade: Setting Duration and Easing Curves

This guide explains how to properly configure the xfade filter in FFmpeg to control transition duration, offset timing, and transition types. It also covers how to implement non-linear easing curves to replace default linear transitions, either by adjusting presentation timestamps (setpts) or by utilizing expression-based blending filters.

Configuring xfade Duration and Timing

The xfade filter requires two primary parameters to control transition length and timing: duration and offset.

  • duration: Sets the length of the transition effect in seconds.
  • offset: Sets the timestamp (in seconds) on the first video stream's timeline when the transition begins.

To ensure a seamless transition without cutting off the end of your first clip, calculate the offset using this formula:

\[\text{offset} = \text{duration of first input} - \text{transition duration}\]

For example, if the first clip is 5 seconds long and you want a 1-second fade transition:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v][1:v]xfade=transition=fade:duration=1:offset=4[v]" \
-map "[v]" output.mp4

Transition Types

You can change the style of the transition using the transition parameter. Common options include:

  • fade (standard crossfade)
  • wipeleft, wiperight, wipeup, wipedown
  • slideleft, slideright, slideup, slidedown
  • circlecrop, rectcrop
  • dissolve

Example using a slide transition:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v][1:v]xfade=transition=slideleft:duration=1.5:offset=3.5[v]" \
-map "[v]" output.mp4

Implementing Easing Curves

By default, FFmpeg’s xfade calculates progress linearly from 0.0 to 1.0. The native xfade filter does not feature an integrated easing parameter. To achieve ease-in, ease-out, or bezier-style curves, you can manipulate the progression through timestamp warping or expression blending.

Method 1: Time Remapping with setpts

You can alter the speed of the transition by applying a mathematical power or curve to the presentation timestamps (PTS) of the transition window before sending frames into xfade.

Accelerating the beginning (ease-in) or slowing the end (ease-out) compresses or expands the perceived frame progression during the crossfade.

Method 2: Mathematical Easing via the blend Filter

For full control over easing curves (such as sinusoidal, quadratic, or cubic easing), use the blend filter with custom expressions instead of xfade.

The blend filter allows frame-by-frame alpha mixing using the all_expr parameter.

Ease-In-Out Quadratic Blend Formula: When \(T\) progresses from \(0\) to \(1\):

  • If \(T < 0.5\): \(2 \times T^2\)
  • If \(T \ge 0.5\): \(1 - \frac{(-2 \times T + 2)^2}{2}\)

Example using a sine-based ease-in-out transition between two overlapping clips:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v]trim=start=0:end=5,setpts=PTS-STARTPTS[v0]; \
 [1:v]trim=start=0:end=5,setpts=PTS-STARTPTS[v1]; \
 [v0][v1]blend=all_expr='A*(0.5*(1+cos(PI*(T/1)))) + B*(1-(0.5*(1+cos(PI*(T/1)))))'[v]" \
-map "[v]" output.mp4
  • A represents the pixel value from the first video.
  • B represents the pixel value from the second video.
  • T represents the current time in seconds within the overlapping region.
  • The trigonometric function transforms linear time into an S-curve easing profile.