我正在使用PHP来启动FFMPEG转码命令。这是在Ubuntu 10.04 Server上运行的典型LAMP设置,配置没有什么特别之处。
我遇到的问题是当我运行PHP Exec命令时它会返回错误的进程ID。它不是返回正确的PID,而是返回高2的值。即FFMPEG进程ID为3557,但PHP Exec返回3559。
我一直设法制作这个。问题是,我真的需要正确的进程ID,所以如果我选择的话,我可以稍后停止进程。
FFMPEG命令的运行和启动没有问题,因此我认为这不是问题的根源:
$cmd = "ffmpeg -r 4 -f mjpeg -an -i 'http://" . $internalhost . ":" . $stream_port . "'
-vcodec libx264 -vpre fastfirstpass -vpre baseline -b 24k -bt 32k -threads 0
http://localhost:8090/" . $localport . ".ffm";
$ffmpg = new Process($cmd);
我知道......这很丑陋,但它有效,我不认为变量很重要。
要启动代码,我正在使用PHP手册网站上的一个类,如下所示:
class Process
{
private $pid;
private $command;
public function __construct($cl=false){
if ($cl != false){
$this->command = $cl;
$this->runCom();
}
}
private function runCom(){
$command = 'nohup '.$this->command.' > /dev/null 2> /dev/null & echo $!';
exec($command ,$op);
$this->pid = (int)$op[0];
}
public function setPid($pid){
$this->pid = $pid;
}
public function getPid(){
return $this->pid;
}
public function status(){
$command = 'ps -p '.$this->pid;
exec($command,$op);
if (!isset($op[1]))return false;
else return true;
}
public function start(){
if ($this->command != '')$this->runCom();
else return true;
}
public function stop(){
$command = 'kill '.$this->pid;
exec($command);
if ($this->status() == false)return true;
else return false;
}
}
我猜想发生的事情是,由于某种原因,FFMPEG正在开始另外两个进程而不是为主进程返回PID,它将返回最后一个进程的PID。
虽然可能是错的,但我仍在摸不着头脑。
答案 0 :(得分:0)
进程ID来自echo $!
,Bash手册指出$!
“扩展为最近执行的后台(异步)命令的进程ID。”我会像你一样预感FFMPEG正在产生额外的进程,其中至少有一个进程在后台,而$!
因此得到了它。你可以运行一些额外的测试来检查这个吗?首先,代替'ffmpeg',运行长期存在的$cmd
,你知道它不会产生后台进程,例如md5sum /dev/zero
,并查看你从getPid()
得到的进程ID匹配您在ps
中看到的内容。其次,当您运行原始代码时,ps X
(在命令行上)说运行的是什么,其中X是getPid()
报告的数字?运行ps fwax | grep -3 X
(再次,替换X)是否表示X是ID为X-2的进程的子进程?
如果这个过程确实是'ffmpeg'产生的后台进程,你试过杀了吗?这也可能足以杀死父进程。