video — запускать PHP exec () асинхронно, но проверять завершение?

Я пишу бэкэнд сайта, который будет включать загруженное пользователем видео. Чтобы обеспечить максимальную доступность, я сжимаю загруженные видео и снова сохраняю их в формате .mp4 и .webm, чтобы охватить все браузеры (или как можно больше). Для этого я запускаю команду avconv в функции PHP exec ().

Я не хочу заставлять пользователя ждать завершения сценария до загрузки страницы, поэтому я выполняю код асинхронно. Мой код пока ниже.

exec('bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libx264 ' . $transpose . ' ' . $newPath . 'mp4 > /dev/null 2>/dev/null &"');
exec('bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libvpx ' . $transpose . ' ' . $newPath . 'webm > /dev/null 2>/dev/null &"');

Помимо запуска функций exec, я также сохраняю видео в базе данных и отправляю пользователю электронное письмо с благодарностью за загрузку видео.

Вот в чем проблема: я хочу, чтобы сервер ПОДОЖДИЛ, пока преобразование видео не закончится, и ТОГДА добавьте его в базу данных и отправьте пользователю электронное письмо. По сути, поток программы будет:

Пользователь загружает видео.
Видео помещается во временную папку.
Пользователь перешел на страницу с благодарностью, указав, что его видео появится в ближайшее время.
Сервер выполняет две команды avconv для преобразования и сжатия видео для использования в Интернете.
После завершения обоих преобразований информация о видео добавляется в базу данных MySQL, пользователю отправляется электронное письмо, а исходное загруженное видео удаляется.

Это может быть просто мое незнание командной строки (на самом деле это почти наверняка), но как я могу «поставить в очередь» эти команды? Сначала выполните оба преобразования, затем вызовите сценарий PHP для добавления в базу данных, затем удалите исходное видео, все это при асинхронности с исходным сценарием PHP?

РЕДАКТИРОВАТЬ: я пытался поставить их в очередь с&&Оператор, как показано ниже:

exec('bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libx264 ' . $transpose . ' ' . $newPath . 'mp4 && avconv -i ' . $tempPath . ' -c:v libvpx ' . $transpose . ' ' . $newPath . 'webm > /dev/null 2>/dev/null &"');

Тем не менее, это, кажется, сводит на нет тот факт, что я запускаю его асинхронно, поскольку теперь страница, похоже, ожидает завершения команды.

1

Решение

Вы должны начать асинхронный PHP-скрипт командной строки который кодирует как видео, так и затем отправляет электронное письмо:

upload.php:

exec('/usr/bin/php -f encode_files.php > /dev/null 2>/dev/null &"');
echo "Files will be encoded, come back later !";

encode_files.php

exec('avconv ...'); // Synchronously ! Without > /dev/null etc ...
exec('avconv ...'); // webm ...

mail('[email protected]', 'Encoding complete ! ', 'Great ! ');

Я оставил вызов как «bash -c exec …», но я думаю, что есть более короткие способы асинхронного вызова сценариев php:
Асинхронная оболочка в PHP
Вы даже можете передавать параметры (например, идентификатор пользователя / видео, …)

$cmd = 'nohup /usr/bin/php -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);
5

Другие решения

Вы можете отключить PHP-скрипт от клиента, но оставить его включенным для выполнения ваших задач.

// Your preliminary stuff here ...
/// then send the user elsewhere but carry on in the background
ignore_user_abort(true);
set_time_limit(0); // i.e. forever

header("Location: thankyoubutwait.php", true);
header("Connection: close", true);
header("Content-Encoding: none\r\n");
header("Content-Length: 0", true);

flush();
ob_flush();

session_write_close();
// more of your video stuff here including database writes
// and clean up bits
// (you may end up with zombie processes though so check your logs or write statuses to files etc.)
1

Легко просто проверить правильность выполнения командной строки следующим образом:

// Your code before...
$command = 'bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libx264 ' . $transpose . ' ' . $newPath . 'mp4 > /dev/null 2>/dev/null &"'
exec($command, $return, $status);
if($status == 0 ) {
$command2 = 'bash -c "exec nohup setsid avconv -i ' . $tempPath . ' -c:v libvpx ' . $transpose . ' ' . $newPath . 'webm > /dev/null 2>/dev/null &"';
exec($command2, $return2, $status2);

if($status2==0){
// let your user know your video traitement has been done
// lauch a new function for alert him
}
}


// Kill your process at end
die();
1
По вопросам рекламы [email protected]