杀死由NodeJ中的生成触发的FFmpeg进程

时间:2018-11-22 09:56:45

标签: node.js ffmpeg spawn kill-process

我遇到了一个问题,想杀死FFmpeg本机spawn软件包中child_process触发的NodeJs进程。

这是我用来触发ffmpeg进程的脚本。

假设转换需要很长时间,例如大约2个小时。

/**
 * Execute a command line cmd
 * with the arguments in options given as an array of string
 * processStore is an array that will store the process during its execution
 * and remove it at the end of the command or when error occurs
 */
function execCommandLine({
   cmd,
   options = [],
   processStore = [],
}) {
  return new Promise((resolve, reject) => {
    const spwaned_process = childProcess.spawn(cmd, options);

    // Append the process to a buffer to keep track on it
    processStore.push(spwaned_process);

    // Do nothing about stdout
    spwaned_process.stdout.on('data', () => true);

    // Do nothing about stderr
    spwaned_process.stderr.on('data', () => true);

    spwaned_process.on('close', () => {
      const index = processStore.indexOf(spwaned_process);

      if (index !== -1) {
        processStore.splice(index, 1);
      }

      resolve();
    });

    spwaned_process.on('error', () => {
      const index = processStore.indexOf(spwaned_process);

      if (index !== -1) {
        processStore.splice(index, 1);
      }

      reject();
    });
  });
}

const processStore = [];

await execCommandLine({
  cmd: 'ffmpeg',

  options: [
    '-i',
    '/path/to/input',
    '-c:v',
    'libvpx-vp9',
    '-strict',
    '-2',
    '-crf',
    '30',
    '-b:v',
    '0',
    '-vf',
    'scale=1920:1080',
    '/path/to/output',
  ],

  processStore,
});

在转换期间,将调用以下代码以杀死所有进入processStore的进程,包括被触发的FFmpeg进程。

// getProcessStore() returns the const processStore array of the above script
getProcessStore().forEach(x => x.kill());

process.exit();

程序退出后,当我运行ps -ef | grep ffmpeg时,仍然有一些FFmpeg进程正在运行。

  

根198 1 0 09:26? 00:00:00 ffmpeg -i / path / to / input -ss 00:01:47 -vframes 1 / path / to / output

     

根217 1 0 09:26? 00:00:00 ps -ef

您是否知道如何正确终止ffmpeg进程的方法?

1 个答案:

答案 0 :(得分:1)

subprocess.kill([signal])的{​​{3}}中所述,默认发送信号为SIGTERM

Ffmpeg不接受node.js documentation中@sashoalm解释的接收SIGTERM的术语。

  

至少在Ubuntu上,新版本的ffmpeg不再使用'q'   Oneiric,相反,他们说要按Ctrl + C停止它们。所以用   较新的版本,您可以简单地使用'killall -INT'向其发送SIGINT   而不是SIGTERM,它们应该干净地退出。


因此致电x.kill('SIGINT');