我正在运行一项人们可以上传视频的服务。由于文件较大,我希望在上传后转换这些视频。
我希望它能在上传完成后调用一个PHP脚本来转换视频(使用FFMPEG)。转换完成后,用户会收到视频可以使用的通知。
我在想一个单独的PHP脚本,它使用POST中发送的路径。然后它将在shell_exec()中调用FFMPEG行。但是,如何让它在后台运行并在完成该过程后向用户发送通知?
答案 0 :(得分:1)
您必须实现一些队列机制。例如,第一个脚本与用户交互,上传文件并将新作业插入队列。第二个脚本由调度程序(Linux中的crontab,Windows中的任务计划程序)每分钟作为后台服务器进程启动。如果队列不为空,则后台脚本从队列接收最旧的作业并运行ffmpeg。当ffmpeg完成工作并且shell_exec返回控制时,您应该将此作业标记为“就绪”。实现此类队列的最简单方法是使用简单的DB表,或者您可以使用特殊设计的队列管理器,例如,的RabbitMQ。
最好编写第三个脚本来检查作业状态,并每隔X秒用AJAX从用户界面调用它。
答案 1 :(得分:0)
我实施了类似于弗拉迪斯拉夫所描述的系统。我使用此task spooler来运行我的ffmpeg作业,一次2个(根据您的硬件进行修改)。如果您没有设置队列,最终可能会尝试同时转码数十个或数百个剪辑,从而关闭服务器。保留一些线程为您的Web服务打开。我编写了一个PHP文件(通过ajax检查),它调用一个shell脚本,提供用户反馈,队列中有等等。这里是bash shell脚本的业务端。
STATUS=$(ts | grep $NEWNAME | awk '{print $2}')
if [ "$STATUS" = "running" ] || [ "$STATUS" = "finished" ]; then
CURRID=$(ts | grep $NEWNAME | awk '{print $1}')
PID=$(ts -p $CURRID)
echo "p$PID"
exit 0
elif [ "$STATUS" = "queued" ]; then
RUNNINGID=$(ts | grep running | awk '{print $1}')
CURRID=$(ts | grep $NEWNAME | awk '{print $1}')
LASTQ=$(ts | grep queued | tail -1 | awk '{print $1}')
ALLQ=$(($LASTQ-$RUNNINGID))
LEFT=$(($CURRID-$RUNNINGID))
echo "q$LEFT.$ALLQ"
exit 0
else
echo "done"
fi