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 durationd=5
. We will start at the beginning of the videost=0
, change the PTS (Presentation Time Stamp) of the input frames tosetpts=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",
});
- In these lines, we create a new video composition with 1920x1080 dimensions:
const composition = await editframe.videos.new({
backgroundColor: "#000",
dimensions: {
height: 1080,
width: 1920,
}
});
- With these two variables, we add two video files using composition.addVideo method:
const video1 = await composition.addVideo(`${__dirname}/file1.mp4`);
const video2 = await composition.addVideo(`${__dirname}/file2.mp4`);
- In this line, we will add the video layers to the video composition using the composition.addSequence method:
await composition.addSequence([video1, video2]);
- Here, we add a fade out transition to the first video using videoLayer.addTransition method:
video1.addTransition({
options: {
duration: 5,
},
type: "crossfadeOut",
});
- In the code below, we encode the video synchronously (though we can also do this async with a webhook):
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: