Create Custom Transitions with FFmpeg gltransition

The gltransition filter allows you to render hardware-accelerated video transitions using custom OpenGL Shading Language (GLSL) shaders in FFmpeg. This guide covers how to set up the filter, write a custom GLSL transition script, and execute the FFmpeg command to blend two video clips seamlessly.

1. Prerequisites and Build Requirements

The gltransition filter is not included in standard FFmpeg distributions by default. It requires an FFmpeg build compiled with the ffmpeg-gl-transition library and its corresponding dependencies:

  • Dependencies: OpenGL, GLEW, and GLFW3.
  • Compilation Flag: The build must include --enable-filter=gltransition.

Pre-built Docker containers containing FFmpeg with GLSL support are commonly used to bypass manual compilation.

2. Writing a Custom GLSL Transition

The gltransition filter relies on the GL Transitions specification. The shader calculates the output pixel color for any normalized coordinate (vec2 uv) at a given point in time (float progress).

Create a file named custom_wipe.glsl and add the following shader code:

// Uniforms automatically provided by gltransition
uniform float progress; // Value from 0.0 (start) to 1.0 (end)
uniform float ratio;    // Width / Height aspect ratio

// Helper functions provided to sample input streams
vec4 getFromColor(vec2 uv);
vec4 getToColor(vec2 uv);

// Custom transition logic (Horizontal Wipe with a soft edge)
vec4 transition(vec2 uv) {
  float smoothness = 0.1;
  float p = progress * (1.0 + smoothness);
  float edge = smoothstep(p - smoothness, p, uv.x);
  
  return mix(getToColor(uv), getFromColor(uv), edge);
}

Core Components of the Shader:

  • progress: A float ranging from 0.0 to 1.0 indicating the transition's lifecycle.
  • getFromColor(vec2 uv): Fetches the RGBA color from the first (outgoing) video.
  • getToColor(vec2 uv): Fetches the RGBA color from the second (incoming) video.
  • transition(vec2 uv): The required entry point that must return a vec4 RGBA color for each pixel.

3. Executing the FFmpeg Command

Once the shader file is saved, run FFmpeg using filter_complex to map two inputs into the gltransition filter.

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v][1:v]gltransition=duration=1.5:offset=4.0:source=custom_wipe.glsl[v]" \
-map "[v]" -c:v libx264 -pix_fmt yuv420p output.mp4

4. Filter Parameters Explained

  • offset: The exact timestamp (in seconds) on the first video's timeline where the transition begins. For example, if input1.mp4 is 5 seconds long and duration is 1 second, set offset=4.0.
  • duration: The length of the transition in seconds. During this window, progress runs from 0.0 to 1.0.
  • source: The local file path to your .glsl transition file.

5. Handling Audio Transitions

The gltransition filter only processes video frames. To prevent audio cuts during the video transition, blend the audio streams using the acrossfade audio filter in the same command:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v][1:v]gltransition=duration=1.5:offset=4.0:source=custom_wipe.glsl[v]; \
 [0:a][1:a]acrossfade=d=1.5[a]" \
-map "[v]" -map "[a]" -c:v libx264 -pix_fmt yuv420p output.mp4