2012-05-07 36 views
4

我現在正在開發一個關於在Internet上共享視頻的網站。 流程如下: 用戶上傳視頻 - >服務器端接收視頻並使用ffmpeg將視頻格式轉換爲flv - >用戶在網站上做其他事情。 現在我想建立另一個線程來做轉換工作(使用ffmpeg將視頻格式轉換爲flv),以便用戶可以在不等待視頻轉換爲flv的情況下做其他事情。但不知道如何!如何在php中使用多線程

+0

你打算通知當視頻轉換完成的用戶? – Manuel

+2

PHP不是,從來沒有,並且可能永遠不會是多線程的。你最好的選擇是'exec()'外部腳本來完成這項工作。 – DaveRandom

回答

6

PHP不支持線程。您應該使用由cron腳本運行的後臺任務來執行此操作。

你可以有一個包含待處理作業的表,例如,包含磁盤上的文件名,狀態(掛起,轉換,準備好)等等,然後讓腳本獲取所有掛起的作業,更改它們狀態轉換,轉換文件,然後將狀態更改爲就緒。這樣您也可以將信息呈現給用戶,並且如果您希望同時轉換多個文件,則可以運行多個腳本。

+0

或者他可以fork php進程 –

+0

@DenisErmolin,當然,但這不是線程。另外,分叉*請求*運行ffmpeg可能是一個非常糟糕的主意。 – rid

+2

@DenisErmolin'pcntl_fork()'在Web請求的上下文中並不真正起作用,如果您退出主進程以返回響應,您將離開一個孤立的進程。如果你想做類似這樣的事情,對exec('php /path/to/script.php>/dev/null 2>&1&')來說更好。 – DaveRandom

2

創建一個需要轉換的視頻隊列,然後使用cron作業逐個轉換視頻。這個隊列可以存儲在諸如消息隊列或數據庫之類的東西中。

使用數據庫,你可以創建一個包含列IDStartDatetimeEndDatetimeFilenameStatusOwner表,並適當設置這些當視頻被上傳。當某個用戶請求他或她的任何視頻的狀態時,只需查看數據庫中的狀態,其中(例如)1 =已添加,2 =當前正在處理,3 =已完成,4 =錯誤。

現在您的cron作業開始處理所有項目,一個接一個,狀態等於1;處理時將其更新爲2,然後適當地更新爲3或4。


通過所有叉/ EXEC /解決方案,在那裏你立即開始處理上載的視頻背景般的運行,你允許所有用戶嗆服務器。如果多個用戶同時開始處理大型視頻會怎麼樣?您無法控制單獨的進程,並且它們都在同一時間運行,可能會嚴重降低服務器速度。

通過使用一個進程順序處理項目(從cron開始),您可以更好地管理正在使用的資源。

1

PHP不是以任何方式,形狀或形式的多線程。你可以用一些方法假的,但他們不是真正的「主題」:

  1. ignore_user_abort(TRUE)允許一個腳本來保持甚至是用戶斷開連接後運行。
  2. exec()可以火起來的,可以在後臺運行shell級別一個新的進程,但是這將是一個完全獨立的過程,而不是從父腳本控制,無需額外措施
  3. pcntl_fork()將創建當前的克隆腳本,然後可以繼續進行處理,但是名義上將獨立於父腳本。這要求pcntl擴展可用,並且在Web請求的上下文中使用不安全。
0

你可以產生ffmpeg作爲後臺進程。 請參閱詳細說明here

我建議將上傳的視頻文件保存到某處,然後在其上運行ffmpeg,並顯示「處理文件..」,直到文件被創建(但您不會等待ffmpeg,只是檢查它是否創建了文件)。

另一種選擇是將文件放在某個目錄中,比如/ videos。然後創建一個cron作業,它將監視/ videos文件夾並轉換任何新文件。

當然,您可以考慮採用更復雜和更安全的方法。