在后台运行一个进程的ffmpeg(Run a ffmpeg process in the backg

2019-06-17 17:49发布

我想使用的ffmpeg转换视频在PHP的FLV。 目前我有这个工作,但直到上载文件并完成它挂起浏览器。 我一直在寻找如何在后台运行一个exec()过程中的PHP文件,同时更新使用返回的PID的进程。 以下是我发现:

//Run linux command in background and return the PID created by the OS
function run_in_background($Command, $Priority = 0)
{
    if($Priority)
        $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
    else
        $PID = shell_exec("nohup $Command > /dev/null & echo $!");
    return($PID);
}

还有,我用,如果后台任务使用返回的PID运行跟踪一招:

//Verifies if a process is running in linux
function is_process_running($PID)
{
    exec("ps $PID", $ProcessState);
    return(count($ProcessState) >= 2);
}

上午我想创建一个单独的PHP文件,然后从PHP CLI运行来执行这些功能呢? 我只是需要一点微调在得到这个工作,然后我可以从那里。

谢谢!

Answer 1:

上午我想创建一个单独的PHP文件,然后从PHP CLI运行来执行这些功能呢?

这可能是我会做的方式:

  • 在PHP网页数据库中添加一条记录,表示“该文件已被处理”
    • 并显示一条消息给用户; 像“你的文件将尽快处理”
  • 在CLI,有一批过程中新插入的文件
    • 第一,标记一个记录“处理”
    • 做ffmpeg的事
    • 将文件标记为“已处理”
  • 而且,在网页上,可以显示在其中陈述他的文件是用户:
    • 如果它没有被处理,但
    • 如果它被处理
    • 或者如果它被处理 - 你可以再给他链接到新的视频文件。

这里有一对夫妇的其他想法:

  • 你的应用程序变得更大一天,你可以有:
    • 一个“网络服务器”
    • 许多“处理服务器”; 在您的应用程序,它是将需要大量的CPU,而不是网页服务的ffmpeg的事; 因此,能够扩大那部分很不错(这是另一个“锁定”的文件,说明他们在DB“处理”:这样一来,你不会有几个处理服务器试图处理同一个文件)
  • 你只使用PHP从Web服务器生成的网页,它是一个网络服务器的济工作
    • 重/长处理不是Web服务器的工作!
    • 你要切换到PHP比别的东西的“处理”部分中的一天,它会更容易。

你的“处理脚本”将不得不推出每两分钟; 您可以使用的cron的是,如果你是一个类似于Linux的机器上。


编辑:更多的信息,看到后评论

由于处理部分是从CLI,而不是从Apache的完成,你不需要anykind的“背景”操作:你可以只使用shell_exec ,这将命令的整个输出中返回到您的PHP脚本时,它的完成做的工作。

对于用户观看网页说:“处理”,它会看起来像后台处理; 并且,在某种程度上,这将是,作为处理将通过另一个突未(甚至另一台机器上)来完成。

但是,对你来说,这将是简单得多:

  • 一个网页(没有“背景”)
  • 一个CLI脚本,没有背景的东西要么。

你处理脚本可能看起来像这样的事情,我想:

// Fetch informations from DB about one file to process
// and mark it as "processing"

// Those would be fetched / determined from the data you just fetched from DB
$in_file = 'in-file.avi';
$out_file = 'out-file.avi';

// Launch the ffmpeg processing command (will probably require more options ^^ )
// The PHP script will wait until it's finished : 
//   No background work
//   No need for any kind of polling
$output = shell_exec('ffmpeg ' . escapeshellarg($in_file) . ' ' . escapeshellarg($out_file));

// File has been processed
// Store the "output name" to DB
// Mark the record in DB as "processed"

真是站着比你首先想到的,不是吗? ;-)
只是不要再担心后台的东西:唯一重要的是,处理脚本定期推出,从crontab中。


希望这可以帮助 :-)



Answer 2:

你并不需要写一个单独的PHP脚本来做到这一点(虽然你可能想以后如果实现某种形式的排队系统)。

你快到了。 唯一的问题是,对了shell_exec()调用块等待外壳的回报。 你能避免这个,如果你从重定向命令的所有输出在外壳枯萎文件或/ dev / null的背景和任务(与&运算符)。 所以,你的代码将成为:

//Run linux command in background and return the PID created by the OS
function run_in_background($Command, $Priority = 0)
{
    if($Priority) {
        shell_exec("nohup nice -n $Priority $Command 2> /dev/null > /dev/null &");
    } else {
        shell_exec("nohup $Command 2> /dev/null > /dev/null &");
    }
}

我不认为有什么办法来检索PID,很遗憾。



文章来源: Run a ffmpeg process in the background