我想用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运行以执行其中一个函数?我只需要稍微轻推一下,然后我可以从那里拿走它。
谢谢!
答案 0 :(得分:10)
我想创建一个单独的.php 然后从php cli运行的文件 执行其中一个功能?
这可能是我这样做的方式:
以下是其他一些想法:
你的“处理脚本”必须每隔几分钟启动一次;如果您使用的是类似Linux的计算机,则可以使用cron。
编辑:看到评论
之后的更多信息由于处理部分是从CLI完成的,而不是从Apache完成的,因此您不需要任何“后台”操作:您可以使用shell_exec
,它会将命令的全部输出返回给您PHP脚本完成它的工作后。
对于观看网页说“处理”的用户,它看起来像后台处理;并且,在某种程度上,它将是,因为处理将由另一个进程(甚至可能在另一台机器上)完成。
但是,对你来说,它会更简单:
我认为你的处理脚本看起来像这样:
// 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定期启动的。
希望这会有所帮助: - )
答案 1 :(得分:0)
您不需要编写单独的PHP脚本来执行此操作(尽管您可能希望稍后实现某种排队系统)。
你快到了。唯一的问题是,shell_exec()调用阻塞等待shell的返回。如果您将shell中命令的所有输出重定向到w / a文件或/ 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。