2016-11-15 89 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