Create Split Screen Video with Animated Border in FFmpeg

Creating a split-screen video with a dynamic, moving boundary adds a professional and engaging touch to your video edits. This article provides a straight-to-the-point guide on how to use FFmpeg, the powerful command-line tool, to combine two video inputs and animate the dividing line between them using complex video filters and mathematical expressions.

The Core Concept

To animate the boundary between two videos in FFmpeg, you use a technique called masked merging. Instead of physically cropping the videos, you create a dynamic, grayscale animated mask.

By writing a mathematical formula that changes the transition point of the black-and-white mask over time, you can create sliding, oscillating, or custom-shaped animated boundaries.


The FFmpeg Command

Below is the complete FFmpeg command to create an oscillating vertical split-screen. In this example, the boundary moves back and forth across the center of the screen every 5 seconds.

ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex \
"[0:v]scale=1920:1080[v1]; \
 [1:v]scale=1920:1080[v2]; \
 nullsrc=size=1920x1080[maskbase]; \
 [maskbase]geq=luc='if(lt(X, (W/2) + (W/4)*sin(2*PI*t/5)), 255, 0)'[mask]; \
 [v1][v2][mask]maskedmerge[outv]" \
 -map "[outv]" -c:v libx264 -crf 23 -pix_fmt yuv420p output.mp4

How the Filter Graph Works

Here is a step-by-step breakdown of how this filter complex processes the video:

  1. [0:v]scale=1920:1080[v1] and [1:v]scale=1920:1080[v2]
    Both input videos are scaled to a matching resolution (1080p). This ensures the mask aligns perfectly with both video sources.

  2. nullsrc=size=1920x1080[maskbase]
    This creates a blank, empty canvas of the same resolution to serve as the template for our mask.

  3. geq=luc='if(lt(X, ...), 255, 0)'
    The geq (generic equation) filter evaluates an equation for every pixel.

    • X is the current horizontal pixel coordinate.
    • W is the width of the video.
    • t is the current timestamp of the video in seconds.
    • sin(2*PI*t/5) creates a smooth sine-wave oscillation that completes one full cycle every 5 seconds.
    • If the horizontal position X is less than (lt) the calculated center boundary, the pixel is colored white (255). Otherwise, it is colored black (0).
  4. [v1][v2][mask]maskedmerge[outv]
    The maskedmerge filter takes the two scaled videos and overlays them using the dynamic mask.


Alternative Animation Styles

By changing the math formula inside the geq filter, you can achieve different types of animated boundaries.

1. Linear Left-to-Right Wipe

To make the split-screen sweep across the screen from left to right over a 10-second period, use this formula:

geq=luc='if(lt(X, t*(W/10)), 255, 0)'

At t=0, the boundary is at 0. At t=10, the boundary reaches the full width (W).

2. Angled Diagonal Split-Screen

To make the dividing boundary diagonal instead of strictly vertical, factor the vertical coordinate Y into the equation:

geq=luc='if(lt(X + Y, W + (W/4)*sin(2*PI*t/5)), 255, 0)'

3. Horizontal Split (Top and Bottom)

To split the screen horizontally and animate the boundary up and down, evaluate the vertical position Y and height H:

geq=luc='if(lt(Y, (H/2) + (H/4)*sin(2*PI*t/5)), 255, 0)'