如何在node.js中删除ffmpeg进程

rjzwgtxy  于 2023-01-16  发布在  Node.js
关注(0)|答案(4)|浏览(240)

我正在使用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文件,而不杀死节点应用程序。

oxf4rvwz

oxf4rvwz1#

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

q9yhzks02#

这最终成为我的解决方案:

child.stdin.end()

它在跨平台上工作得很好。在我的特定案例中,FFmpeg也从STDIN阅读流数据。SIGTERM不工作。Windows能够使用SIGTERM杀死进程,但只是因为它实际上没有使用这些信号,而是强行杀死进程。
因此,您可以尝试结束STDIN,看看这是否也能解决您的使用问题!

fafcakar

fafcakar3#

您正在从child.on('exit')回调调用child.kill(),这可能是问题所在,因为该回调未被触发。实际上,当子进程完成时,将调用child.on('exit')
另外,如果你需要杀死子进程,这意味着命令不会自己退出,如果是这样的话,也许你需要设置一个超时,在运行一段时间后调用child.kill()

f5emj3cl

f5emj3cl4#

在stdin中发送'q'是一个很好的解决方案,但是我发现它有点不稳定,因为它不是每次都有效。
剩下的进程不是直接从主NodeJS进程派生的,换句话说,它们是派生进程的查尔兹进程。我在exec打开一个shell,shell派生一个ffmpeg进程的例子中看到过这个问题。
目前,child_process中没有方法来终止整个进程树,但here中有一个特性请求。
另一个解决方案是使用tree-kill模块,下面是我从他们的Github page中偷来的一个例子:
杀死pid为1的进程的所有后代进程,包括pid为1的进程本身:

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

所以如果你想杀死进程树:

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

相关问题