简体   繁体   English

如何杀死node.js中的ffmpeg进程

[英]How to Kill ffmpeg process in node.js

I am using node.js code that convert Axis Ipcamera live stream into mp4 using FFMPEG我正在使用 node.js 代码,使用 FFMPEG 将 Axis Ipcamera live stream 转换为 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();
    });

my above code works perfectly.我上面的代码完美运行。 It gives the output as I want, but I am not able to kill(stop) the ffmpeg command.它根据需要提供 output,但我无法终止(停止)ffmpeg 命令。 I am using the code below for stopping the process, but in background it still continues.我正在使用下面的代码停止进程,但在后台它仍然继续。

child.kill("SIGTERM"); 

I also used following commands: child.kill('SIGUSR1');我还使用了以下命令:child.kill('SIGUSR1'); child.kill("SIGHUP"); child.kill("SIGHUP"); child.kill("SIGINT");child.kill('SIGUSR2'); child.kill("SIGINT");child.kill('SIGUSR2'); for killing this process but it not works.杀死这个过程,但它不起作用。

Currently I forcefully kill the node application to stop ffmpeg command and generate mp4 file.目前我强行杀死节点应用程序以停止 ffmpeg 命令并生成 mp4 文件。 I do not want this.我不想这样。 But I want commands that stop ffmpeg process and generate mp4 file, without killing the node application.但我想要停止 ffmpeg 进程并生成 mp4 文件的命令,而不终止节点应用程序。

var cp = require('child_process');
var cmd = 'ffmpeg...'
var child = cp.exec(cmd, function(err, stdout, stderr) {})
child.stdin.write('q')

This ended up being the solution for me:这最终成为我的解决方案:

child.stdin.end()

It works fine cross-platform.它可以很好地跨平台工作。 In my specific case, FFmpeg was reading from STDIN for stream data as well.在我的具体案例中,FFmpeg 也从 STDIN 读取 stream 数据。 SIGTERM wasn't working. SIGTERM没有工作。 Windows was able to kill with SIGTERM , but only because it doesn't actually use these signals and was forcefully killing the process. Windows 能够用SIGTERM终止,但这只是因为它实际上并没有使用这些信号,而是强行终止了进程。

So, you might try just ending STDIN and see if that solves it for your usage as well!所以,您可以尝试结束STDIN ,看看是否也能解决您的使用问题!

You are calling child.kill() from the child.on('exit') callback, that could be the issue since that callback is not been triggered. 您正在从child.on('exit')回调中调用child.kill() ,这可能是问题所在,因为未触发该回调。 child.on('exit') is called actually when the child process finished. child.on('exit')实际上在子进程完成时被调用。

Also if you need to kill the child process explicitly means that the command is not exit by it self. 同样,如果您需要明确杀死子进程,则意味着该命令本身不会退出。 If thats the case maybe you want to set a timeout to call child.kill() after some time of been running. 如果是这样的话,也许您想设置一个超时时间以在运行一段时间后调用child.kill()

Sending 'q' in stdin is a good solution but I find it a bit unstable since it doesn't work every time.在 stdin 中发送 'q' 是一个很好的解决方案,但我发现它有点不稳定,因为它并非每次都有效。 So here is what I have found.所以这就是我所发现的。

The processes that are remaining are not spawned directly from your main NodeJS process.剩余的进程不是直接从您的 NodeJS 主进程生成的。 In other words they are the childs of your spawned process.换句话说,它们是您生成的进程的孩子。 I've seen this issue in my case where exec opens up a shell and the shell forks a ffmpeg process.我在exec打开 shell 和 shell 分叉 ffmpeg 进程的情况下看到了这个问题。

Currently there is no method in child_process to kill the complete process tree but there is a feature request for it here .目前在child_process中没有杀死整个进程树的方法,但是这里有一个功能请求。

Another solution is to use a module tree-kill .另一种解决方案是使用模块tree-kill Here's an example I sneaked from their Github page :这是我从他们的Github 页面偷偷摸摸的一个例子:

Kill all the descendent processes of the process with pid 1, including the process with pid 1 itself:杀死 pid 为 1 的进程的所有后代进程,包括 pid 为 1 的进程本身:

var kill = require('tree-kill');
kill(1);

So if you want to kill the process tree:所以如果你想杀死进程树:

var treekill = require('tree-kill');
treekill(child.pid);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM