'Fluent ffmpeg not running synchronously

I am writing a program where I need to process a video multiple times using ffmpeg. The ffmpeg codes (below) are inside a 'then' statement of a promise.

ffmpeg(path)
  .size('640x?')
  .aspect('1:1')
  .autopad('#682BAB')
  .saveToFile(`${userDirPath}/11-${userFileName}`)
  .on('end', () => {
    ffmpeg()
      .input('test-11-start.mp4')
      .mergeAdd(`${userDirPath}/11-${userFileName}`)
      .mergeAdd('test-11-end.mp4')
      .mergeToFile(`${userDirPath}/11-final-${userFileName}`, 'temp/')
      .on('end', () => console.log('FFmpeg done!'));
  });

There is another ffmpeg function after this (same, but with a different aspect ratio) and then, a 'then' statement with some other functions.

The problem is that this ffmpeg function runs asynchronously, and the next statements (which use the resulting file of ffmpeg func) are executed before it finishes executing and so I want it to run synchronously. I've tried async await (below) but it still runs asynchronously. What is wrong with code?

async function ffmpegMerge() {
  try {
    await ffmpeg(path)
    .size('640x?')
    .aspect('1:1')
    .autopad('#682BAB')
    .saveToFile(`${userDirPath}/11-${userFileName}`)
    .on('end', () => {
      ffmpeg()
        .input(`test-11-start.mp4`)
        .mergeAdd(`${userDirPath}/11-${userFileName}`)
        .mergeAdd(`test-11-end.mp4`)
        .mergeToFile(`${userDirPath}/11-final-${userFileName}.mp4`, 'temp/')
        .on('end', () => console.log('FFmpeg done!'));
    })
  }
  catch (err) {
    return Promise.reject(new Error(err));
  }
}


Solution 1:[1]

Create a function with promise and use await to wait until the function is resolved.

This is an example of using ffmpeg synchronously:

function ffmpegSync(){
   return new Promise((resolve,reject)=>{
      ffmpeg(path)
         .size('640x?')
         .aspect('1:1')
         .autopad('#682BAB')
         .saveToFile(`${userDirPath}/11-${userFileName}`)
         .on('end', () => {
            ffmpeg()
               .input(`test-11-start.mp4`)
               .mergeAdd(`${userDirPath}/11-${userFileName}`)
               .mergeAdd(`test-11-end.mp4`)
               .mergeToFile(`${userDirPath}/11-final-${userFileName}.mp4`, 'temp/')
               .on('end', () => console.log('FFmpeg done!'));
               resolve()
         })
         on('error',(err)=>{
            return reject(new Error(err))
         })
   })
}

Now just use the function ffmpegSync and await.

Solution 2:[2]

 createThumbnailForVideo().then(()=>{
      console.log('ok');
 })


 function createThumbnailForVideo(){

    return new Promise((resolve,reject)=>{

       const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg');
       const ffmpeg = require('fluent-ffmpeg');
       ffmpeg.setFfmpegPath(ffmpegInstaller.path);
       var path = require('path'), // Default node module
       pathToFile = path.join(__dirname, 'tempfiles', fileName),
       pathToSnapshot = path.join(__dirname, 'tempfiles');

       var proc = ffmpeg(pathToFile)
        .on('filenames', (filenames)=> {})
        .on('end', (data)=> {
          console.log('screenshots were saved');
      
        })
        .on('error', (err)=> {
          console.log('an error happened: ' + err.message);
          return reject(new Error(err))
        })
        .takeScreenshots({ count: 1,filename:`thumb_${onlyName}.png`, timemarks: [ '00:00:01.000' ], size: '250x?' },pathToSnapshot)
        .on('end', () => {
          console.log('FFmpeg done!')
          resolve()
        })
        .on('error', (err)=> {
          console.log('an error happened: ' + err.message);
          return reject(new Error(err))
        })
      
   })

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Josias da Paixao junior
Solution 2 fergolive