te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Fluent ffmpeg not running synchronously - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fluent ffmpeg not running synchronously - Stack Overflow

programmeradmin4浏览0评论

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

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));
  }
}
Share Improve this question asked Dec 14, 2019 at 2:22 sciencaholicsciencaholic 1431 gold badge2 silver badges12 bronze badges 2
  • Why not put the first ffmpeg "code" into an function which returns a Promise and resolves when the render is finished(where you log FFMPEG done!). The second ffmpegMerge() function then is called on the resolve of the first? – Mattstir Commented Jan 23, 2020 at 10:18
  • I did try that, but it weirdly did not work. I used promise inside a promise to solve this, put the rest of the code inside the second ffmpeg()'s .on('end', () => {}). I used to think nested promises are a bad practice, that's why I wasn't going for it before, but they're not. – sciencaholic Commented Jan 24, 2020 at 6:35
Add a ment  | 

2 Answers 2

Reset to default 13

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.

 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))
        })
      
   })
发布评论

评论列表(0)

  1. 暂无评论