2012-05-07 5 views
4

Я сейчас разрабатываю сайт об обмене видео в Интернете. поток выглядит следующим образом: пользователь загружает видео -> серверная сторона получает видео и использует 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()' действительно не работает в контексте веб-запроса, если вы выходите из основного процесса, чтобы вернуть ответ, вы оставите осиротевший процесс. Намного лучше 'exec ('php /path/to/script.php>/dev/null 2> & 1 &')', если вы хотите сделать что-то подобное. – DaveRandom

2

Сделайте очередь видеороликов, которые необходимо преобразовать, и конвертируйте видео по одному с помощью задания cron, например. Эта очередь может храниться в виде очереди сообщений или базы данных.

Использование базы данных можно создать таблицу, содержащую столбцы ID, StartDatetime, EndDatetime, Filename, Status, Owner и установить те, соответственно, когда видео загружается. Когда какой-либо пользователь запрашивает статус любого из своих видеороликов, вы просто просматриваете статус в базе данных, где (например) 1 = добавлено, 2 = в настоящее время обрабатывается, 3 = done, 4 = ошибка.

Теперь ваше задание cron начинает обрабатывать все предметы, один за другим, где состояние равно 1; при обработке он обновляет его до 2, а затем до 3 или 4 соответственно.


По всем вилам/Exec/выбег фона-подобных решений, где вы сразу же начать обработку загруженного видео, вы позволяете всем пользователям задыхаться серверами. Что делать, если несколько пользователей одновременно начинают обработку большого видео? Вы не контролируете отдельные процессы, и все они работают одновременно, вероятно, сильно замедляя работу вашего сервера.

После обработки элементов последовательно с использованием одного процесса (начатого через cron), вы можете лучше управлять используемыми ресурсами.

1

PHP не является многопоточным каким-либо образом, формой или формой. Вы можете подделать его с несколькими методами, но они не так «нити»:

  1. ignore_user_abort(TRUE) позволяет сценарий, чтобы продолжать работать даже после того, как разъединяет пользователей.
  2. exec() может запустить новый процесс на уровне оболочки, который может работать в фоновом режиме, но это будет совершенно самостоятельным процесс и не управляем из родительского сценария без дополнительных мер
  3. pcntl_fork() создаст клон тока скрипт, который затем может продолжить обработку, но снова будет номинально независимым от родительского скрипта. Для этого требуется расширение pcntl и оно небезопасно для использования в контексте веб-запроса.
0

Вы можете создать ffmpeg как фоновый процесс. См. Подробное объяснение here.

Я предлагаю сохранить загруженный видеофайл где-нибудь, затем запустить ffmpeg на нем и отобразить «Обработка файла ..» до тех пор, пока файл не будет создан (но вы не можете ждать ffmpeg, просто убедитесь, что он создал файл).

Другой вариант - поместить файл в какой-либо каталог, скажем/видео. Затем создайте задание cron, которое будет контролировать папку/videos и конвертировать любые новые файлы.

Конечно, вы можете подумать о более сложном и отказобезопасном методе.

Смежные вопросы