2016-11-15 85 views
0

我正在运行一项服务,用户可以上传视频。由于文件较大,我希望在上传后转换这些视频。上传后转换视频

我想要它,以便上传完成后,将调用一个PHP脚本,在该脚本中转换视频(使用FFMPEG)。转换完成后,用户会收到视频已准备好使用的通知。

我正在考虑使用POST中发送的路径的单独PHP脚本。然后它将调用shell_exec()中的FFMPEG行。但是,如何让它在后台运行,并在进程完成后向用户发送通知?

回答

1

你必须实现一些排队机制。例如,第一个脚本与用户交互,上传文件并将新作业插入到队列中。第二个脚本作为后台服务器每分钟由调度程序启动(Linux中的crontab,Windows中的任务计划程序)。如果队列不为空,后台脚本将从队列中接收最旧的作业并运行ffmpeg。当ffmpeg完成工作并且shell_exec返回控制时,您应该将此作业标记为“ready”。实现这种队列最简单的方法是简单的数据库表,或者可以使用特殊设计的队列管理器,例如RabbitMQ的。

另外一个好主意是编写第三个脚本来检查作业状态并每X秒从AJAX用户界面调用它。

0

我实现了一个类似于弗拉季斯拉夫描述的系统。我使用这个task spooler一次运行2个ffmpeg作业(根据您的硬件进行修改)。如果您没有设置队列,您最终可能会尝试同时转码数十个或数百个剪辑,从而导致服务器关闭。为您的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