我想知道如何在exec()
(ffmpeg)之后关闭页面并继续工作。
我有一个表格,允许人们使用ffmpeg转换视频文件,但是如果用户单击该页面,则exec()会继续运行,但是在此exec未执行后,一切都会发生。
<?php
if (!empty($_POST) && $imgDir) {
exec('"/dir/to/ffmpeg" -f image2 -i "' . $imgDir . '" -r 12 -s 610x489 /dir/to/out.avi', $out);
/* INSERT statement (Not being executed) */
$sql = "INSERT INTO requests (userID,image) VALUES (?,?)";
$stmt= $pdo->prepare($sql);
$stmt->execute([$user_id, $imgDir]);
}
?>
我希望用户能够单击一个离开的页面,这样他们就不必等待,以后就可以下载文件了。
答案 0 :(得分:1)
这种情况下的常见解决方案是将转换过程转移到后台脚本(例如,由cron定期触发的作业)。这样可以避免长时间运行的进程超时或外部命令行进程无法正确返回的问题。
网页只会将请求放入队列(例如,在db表中)并保存文件。
然后,后台服务将从队列中选择下一个项目,对其进行处理并将其标记为完成。
然后,您必须考虑如何通知用户。您可以通过电子邮件向他们发送电子邮件,或者拥有一个状态页,他们可以在其中检查其作业并下载已准备好的任何文件,或者同时下载和下载这两个文件,或者选择其他一些过程。也许您可以允许用户指定要如何通知他们。
答案 1 :(得分:1)
如果要在后台从PHP启动此命令,则可以通过以下模式运行非阻塞进程:
if(is_resource($proc = proc_open($cmd, [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes)))
{
stream_set_blocking($pipes[1], false);
stream_set_blocking($pipes[2], false);
在Linux系统上,您可以使用前置nohup
来启动命令,例如
$cmd = 'nohup "/dir/to/ffmpeg" -f image2 -i "' . $imgDir . '" -r 12 -s 610x489 /dir/to/out.avi'
使用nohup
之后,您甚至可以退出启动新流程的流程。它将与父进程分离。