Уничтожение процесса FFmpeg, вызванного порождением в NodeJs - PullRequest
0 голосов
/ 22 ноября 2018

Я столкнулся с проблемой, желающей завершить процесс FFmpeg, запущенный spawn из пакета child_process native 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.

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

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

У вас есть идея, как правильно завершить процесс ffmpeg?

1 Ответ

0 голосов
/ 22 ноября 2018

Как указано в документации node.js из subprocess.kill([signal]), отправляемый сигнал по умолчанию - SIGTERM.

Ffmpeg не прерывает прием SIGTERM, как объяснено @sashoalmв здесь .

Более новые версии ffmpeg больше не используют 'q', по крайней мере в Ubuntu Oneiric, вместо этого они говорят, что нажимают Ctrl + C, чтобы остановить их.Таким образом, в более новой версии вы можете просто использовать killall -INT для отправки им SIGINT вместо SIGTERM, и они должны выйти чисто.


Так что звоните x.kill('SIGINT');

...