我正在使用node.js代码,该代码使用FFMPEG将Axis Ipcamera实时流转换为mp4
var childProcess=require('child_process');
var childArguments = [];
var child=[];
var cmd='ffmpeg -i rtsp://172.24.22.117:554/axis-media/media.amp -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -preset slower -crf 18 -vf "scale=trunc(in_w/2)*2:trunc(in_h/2)*2"'+' '+__dirname+'/uploads/ouput.mp4';
child=childProcess.exec(
cmd,
childArguments,
{
env: process.env,
silent:true
}, function (err, stdout, stderr) {
if (err) {
throw err;
}
console.log(stdout);
});
// here generate events for listen child process (works properly)
// Listen for incoming(stdout) data
child.stdout.on('data', function (data) {
console.log("Got data from child: " + data);
});
// Listen for any errors:
child.stderr.on('data', function (data) {
console.log('There was an error: ' + data);
});
// Listen for exit event
child.on('exit', function(code) {
console.log('Child process exited with exit code ' + code);
child.stdout.pause();
child.kill();
});
我上面的代码工作得很完美。2它给出了我想要的输出,但是我不能终止(停止)ffmpeg命令。3我使用下面的代码来停止进程,但是在后台它仍然继续。
child.kill("SIGTERM");
我还使用了以下命令:删除子对象(“SIGUSR 1”);杀死儿童(“SIGHUP”);杀害儿童(“信号情报”);删除子对象(“SIGUSR 2”);终止这个进程,但它不起作用。
目前我强制杀死节点应用程序以停止ffmpeg命令并生成mp4文件。我不希望这样。但我希望命令停止ffmpeg进程并生成mp4文件,而不杀死节点应用程序。
4条答案
按热度按时间oxf4rvwz1#
q9yhzks02#
这最终成为我的解决方案:
它在跨平台上工作得很好。在我的特定案例中,FFmpeg也从STDIN阅读流数据。
SIGTERM
不工作。Windows能够使用SIGTERM
杀死进程,但只是因为它实际上没有使用这些信号,而是强行杀死进程。因此,您可以尝试结束
STDIN
,看看这是否也能解决您的使用问题!fafcakar3#
您正在从
child.on('exit')
回调调用child.kill()
,这可能是问题所在,因为该回调未被触发。实际上,当子进程完成时,将调用child.on('exit')
。另外,如果你需要杀死子进程,这意味着命令不会自己退出,如果是这样的话,也许你需要设置一个超时,在运行一段时间后调用
child.kill()
。f5emj3cl4#
在stdin中发送'q'是一个很好的解决方案,但是我发现它有点不稳定,因为它不是每次都有效。
剩下的进程不是直接从主NodeJS进程派生的,换句话说,它们是派生进程的查尔兹进程。我在
exec
打开一个shell,shell派生一个ffmpeg进程的例子中看到过这个问题。目前,child_process中没有方法来终止整个进程树,但here中有一个特性请求。
另一个解决方案是使用tree-kill模块,下面是我从他们的Github page中偷来的一个例子:
杀死pid为1的进程的所有后代进程,包括pid为1的进程本身:
所以如果你想杀死进程树: