How can I encode/convert multiple video files one by one using fluent ffmpeg?

I have a nodejs script which encodes/converts multiple video files using the fluent-ffmpeg package. Since FFmpeg is very resource intensive my Linux server runs out of resources and my scripts start throwing an error. This is because all the videos are encoded concurrently.
Is there a way to encode the videos one at a time and not concurrently?
My code snippet looks like this:
const Ffmpeg = require(“fluent-ffmpeg”);
videos.forEach(video=> {
covertVideo(filename, (compressionResult)=>{
//do something here
});
});
function covertVideo(filename, callback){
var ffmpeg = new FfmpegCommand(filename);
ffmpeg.setFfmpegPath(pathToFfmpeg);
ffmpeg.addOptions(“-threads 1”)
.fps(23)
.complexFilter([
“scale=w=‘if(gt(a,0.75),240,trunc(320*a/2)*2)’:h=‘if(lt(a,0.75),320,trunc(240/a/2)*2)’,pad=w=240:h=320:x=‘if(gt(a,0.75),0,(240-iw)/2)’:y=‘if(lt(a,0.75),0,(320-ih)/2)’:color=black[scaled]”
])
.on(‘error’, function(err) {
console.log('An error occurred: ’ + err.message);
return callback(false);
})
.on(‘end’, function() {
console.log(‘Compression finished !’);
return callback(true);
})
.save(“./tmp/”+filename);
}

Instead of this, you can process the videos synchronously to make sure that they are encoded one at a time rather than concurrently. This can be accomplished by encoding each video in turn, and waiting for it to finish before starting the next. For this sequential processing, you can change your code to make use of a promise chain or a recursive function. A promise chain is used in the following example:

const FfmpegCommand = require("fluent-ffmpeg");
const pathToFfmpeg = "/path/to/ffmpeg"; // Replace with the actual path to ffmpeg
const videos = ["video1.mp4", "video2.mp4", "video3.mp4"]; // Replace with your video file names

function processVideos(videos) {
  if (videos.length === 0) {
    console.log("All videos processed");
    return;
  }

  const filename = videos.shift();

  convertVideo(filename, (compressionResult) => {
    // Do something here with the result if needed
    // ...

    // Continue processing the remaining videos
    processVideos(videos);
  });
}

function convertVideo(filename, callback) {
  var ffmpeg = new FfmpegCommand(filename);
  ffmpeg.setFfmpegPath(pathToFfmpeg);
  ffmpeg.addOptions("-threads 1")
    .fps(23)
    .complexFilter([
      "scale=w=‘if(gt(a,0.75),240,trunc(320*a/2)*2)’:h=‘if(lt(a,0.75),320,trunc(240/a/2)*2)’,pad=w=240:h=320:x=‘if(gt(a,0.75),0,(240-iw)/2)’:y=‘if(lt(a,0.75),0,(320-ih)/2)’:color=black[scaled]"
    ])
    .on('error', function (err) {
      console.log('An error occurred: ' + err.message);
      return callback(false);
    })
    .on('end', function () {
      console.log('Compression finished!');
      return callback(true);
    })
    .save("./tmp/" + filename);
}

// Start processing videos sequentially
processVideos(videos.slice()); // Pass a copy of the videos array to avoid modifying the original array

This change processes each video individually using a recursive function called processVideos. Every video has the convertVideo function called for it; the process doesn’t stop until the current video has been handled. This lowers the possibility of resource depletion by ensuring that the movies are processed in a sequential manner.

Great! works for me, Thanks.