Crossfade between two videos using FFmpeg

Crossfading is a video transition effect in which one scene gradually fades out while another fades in. Crossfading is commonly used to transition between scenes, but it has many other applications in video production as well. Thanks to its versatility, it is one of the most popular fade effects seen in video content today.

This guide walks you through how to create a crossfade between two mp4 videos using two methods—FFmpeg, and the Editframe API. Once you master the crossfade, you might also want to try using other transitions, like dissolve or push-pull. Before you know it, you’ll be a regular Francis Ford Scorsese Spielberg.

Action!

File assets

In this tutorial, we will use the two sample video files below provided by pexels.com:

file1.mp4

file2.mp4

Part 1: Using FFmpeg

First, we’ll walk through this workflow using FFmpeg.

Required tools:

  • Sample videos (provided above)
  • FFmpeg: (You’ll need to install FFmpeg and set up the appropriate environment variables before beginning this tutorial)

Here is the complete FFmpeg command to merge two videos with a crossfade transition effect:

ffmpeg -i file1.mp4 -i file2.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS[v0]; \[1:v]format=yuva420p,fade=in:st=0:d=5:alpha=1,setpts=PTS-STARTPTS+(8/TB)[v1]; \[v0][v1]overlay,format=yuv420p[outv]" \-c:v libx264 -map "[outv]" crossfade.mp4

Let’s break this down and see what each part of the command is doing.

  • In this line, we import the videos files, file1.mp4 and file2.mp4:
ffmpeg -i file1.mp4 -i file2.mp4 \
  • In this line, we include the filter complex:
-filter_complex "[0:v]setpts=PTS-STARTPTS[v0];\
  • In this line, we select the second file's video stream and add a fade-in effect fade=in with a 5-second duration d=5. We will start at the beginning of the video st=0 , change the PTS (Presentation Time Stamp) of the input frames to setpts=PTS-STARTPTS+(8/TB), and set this composition variable to [v1]:
[1:v]format=yuva420p,fade=in:st=0:d=5:alpha=1,setpts=PTS-STARTPTS+(8/TB)[v1]; \
  • In this line, we will take the first and second video compositions as overlays to accomplish the cross fade-in transition effect. Essentially, we’re using the end of the first video (which uses the fade-out effect) and combining it with the fade-in effect of the second video. This creates a crossfade effect:
[v0][v1]overlay,format=yuv420p[outv]" \
  • In this line, we copy the video streams, then map the video composition into the crossfade.mp4 video:
-c:v libx264 -map "[outv]" crossfade.mp4

Here is the final output video using the FFmpeg command:

crossfade.mp4

Part 2: Using Editframe

Now let’s perform the same task using Editframe instead of FFmpeg.

Required tools:

  • Node.js installed on your machine (v16+)
  • Editframe API Token (you can create an account from this link)

*No need to have FFmpeg installed on your machine

  • Create a folder for your project:
mkdir editframe-cross-fade-in
  • Initialize the Node.js project:
cd editframe-cross-fade-in && yarn init -y
  • Install the Editframe Node.js SDK:
yarn add @editframe/editframe-js
  • Create a create-video.js file to merge the two videos into one:
const { Editframe } = require("@editframe/editframe-js");

async function main() {
  const editframe = new Editframe({
    develop: true,
    clientId: "YOUR_EDITFRAME_CLIENT_ID",
    token: "YOUR_EDITFRAME_TOKEN",
  });

  const composition = await editframe.videos.new({
    backgroundColor: "#000",
    dimensions: {
      height:1080,
      width: 1920,
    },
  });
  const video1 = await composition.addVideo(`${__dirname}/file1.mp4`);
  const video2 = await composition.addVideo(`${__dirname}/file2.mp4`);

  video1.addTransition({
    options: {
			duration: 5,
    },
		type: "crossfadeOut",
  });
  await composition.addSequence([video1, video2]);
  const video = await composition.encodeSync();
  console.log(video);
}

main();

Let’s break down some of the code above:

  • Here, we initialize an Editframe instance with the Editframe API Token (which you can get by creating an Editframe application). Also, we set develop to true, which opens the output video in a new tab when encoding has finished:
const editframe = new Editframe({
    develop: true,
    clientId: "YOUR_EDITFRAME_CLIENT_ID",
    token: "YOUR_EDITFRAME_TOKEN",
  });
const composition = await editframe.videos.new({
    backgroundColor: "#000",
    dimensions: {
      height: 1080,
      width: 1920,
    }
  });
const video1 = await composition.addVideo(`${__dirname}/file1.mp4`);
const video2 = await composition.addVideo(`${__dirname}/file2.mp4`);
  await composition.addSequence([video1, video2]);
video1.addTransition({
    options: {
			duration: 5,
    },
    type: "crossfadeOut",
  });
const video = await composition.encodeSync();
console.log(video);
  • Run the video script:
node create-video

Here is the output video:

editframe-crossfade.mp4

Note: You can add transitions, filters, trim videos, and more using the Editframe API, and Editframe API docs.

Here is a comparison the videos created with FFmpeg and the Editframe API:

compare.mp4

© 2024 Editframe
Making video creation easier for software developers.