Goal
I have a video and an image (a template for the video) that I'm trying to combine into one output video (1080w x 1920h - 9:16 aspect ratio).
This image shows what I'm trying to accomplish. The two orange sections are the input image - it's a single .png
with a transparent section in the middle for the video.
As mentioned in the title, I'm trying to accomplish this using FFMPEG
. More specifically, I'm using the fluent-ffmpeg npm package.
Current Status
I can read in both inputs just fine but I have issues getting the two to play nicely with one another.
If I get the overlay working then my output video is 1920x1080 instead of 1080x1920.
If I get the output video dimensions right, then the video is either stretched or I get errors adding my overlay.
Code
Here's what I have at the moment. I'm happy to answer any questions. Thank you in advance for taking a look :)
var ffmpeg = require('fluent-ffmpeg');
var command = ffmpeg();
var timemark = null;
command
.on('end', onEnd )
.on('progress', onProgress)
.on('error', onError)
.input('./input-video.mp4')
.input('./template.png')
.complexFilter([
{
filter: 'scale',
options: { width: 1080, height: 1920 }
},
// {
// filter: 'overlay',
// options: { x: 100, y: 100 }
// },
])
.outputFps(30)
.output('./output-video.mp4')
.run();
/* Misc */
function onProgress(progress){
if (progress.timemark != timemark) {
timemark = progress.timemark;
console.log('Time mark: ' + timemark + "...");
}
}
function onError(err, stdout, stderr) {
console.log('Cannot process video: ' + err.message);
}
function onEnd() {
console.log('Finished processing');
}
Thanks to user Voldrix_Suroku on Reddit I was able to figure this out.
To avoid being a DenverCoder9 the CLI command to get this to work is:
ffmpeg -i input-video.mp4 -i template.png -filter_complex "[0:V]scale=1080:-1,pad=0:1920:0:(oh-ih)/2[vid];[vid][1:v]overlay" output-video.mp4
And if you're using fluent-ffmpeg
like I am, the full code is below:
var ffmpeg = require('fluent-ffmpeg');
var command = ffmpeg();
var timemark = null;
command
.on('end', onEnd )
.on('progress', onProgress)
.on('error', onError)
.input('./input-video.mp4')
.input('./template.png')
.complexFilter([
"[0:V]scale=1080:-1,pad=0:1920:0:(oh-ih)/2[vid];[vid][1:v]overlay"
])
.outputFps(30)
.output('./output-video.mp4')
.run();
/* Misc */
function onProgress(progress){
if (progress.timemark != timemark) {
timemark = progress.timemark;
console.log('Time mark: ' + timemark + "...");
}
}
function onError(err, stdout, stderr) {
console.log('Cannot process video: ' + err.message);
}
function onEnd() {
console.log('Finished processing');
}