【问题标题】:Fluent ffmpeg not running synchronously流畅的ffmpeg没有同步运行
【发布时间】:2020-04-07 10:51:35
【问题描述】:

我正在编写一个程序,我需要使用 ffmpeg 多次处理视频。 ffmpeg 代码(如下)位于承诺的“then”语句中。

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!'));
  });

在此之后还有另一个 ffmpeg 函数(相同,但纵横比不同),然后是带有其他一些函数的“then”语句。

问题是这个 ffmpeg 函数是异步运行的,并且下一个语句(使用 ffmpeg func 的结果文件)在它完成执行之前执行,所以我希望它同步运行。我已经尝试过异步等待(如下),但它仍然异步运行。代码有什么问题?

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));
  }
}

【问题讨论】:

  • 为什么不将第一个 ffmpeg "code" 放入一个函数中,该函数返回一个 Promise 并在渲染完成时解析(您记录 FFMPEG 完成!)。然后第二个ffmpegMerge() 函数在第一个解析时被调用?
  • 我确实尝试过,但奇怪的是没有奏效。我在promise 中使用promise 来解决这个问题,将其余代码放在第二个ffmpeg().on('end', () => {}) 中。我曾经认为嵌套的 Promise 是一种不好的做法,这就是为什么我之前没有这样做,但事实并非如此。

标签: javascript node.js ffmpeg async-await fluent-ffmpeg


【解决方案1】:

使用promise 创建一个function 并使用await 等待function 解决。

这是一个同步使用ffmpeg的例子:

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))
         })
   })
}

现在只需使用函数ffmpegSyncawait

【讨论】:

  • End 监听器应该是这样的:on('end', () => { console.log('FFmpeg done!'); resolve();}) 是错字还是应该这样?
  • 这不是错字,它会在上一个终端监听器上解决。
【解决方案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))
        })
      
   })

【讨论】:

  • 请对您的代码添加一些说明,以便更容易理解发生了什么和/或为什么 OP 的代码首先不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
相关资源
最近更新 更多