Intereting Posts
Загрузите файл через PHP-скрипт с FTP-сервера в браузер с заголовком Content-Length без сохранения файла на веб-сервере Неустранимая ошибка: вызов неопределенной функции mb_strlen () Неустранимая ошибка: вызов неопределенной функции new_mysqli () в C: \ wamp \ www \ work \ conn.php в строке 8 Как получить все имена таблиц и столбцов из базы данных в Yii Framework Как сохранить php-файл как расширение .php или .html? Сообщение пользователя Ajax для чата ORA-06502: PL / SQL: числовая или значащая ошибка: слишком строчный буфер символьной строки – выполнение с использованием интерфейса OCI php jquery, как механизм выбора Доступ к $ _COOKIE сразу после setcookie () сумма строк не обновляется при запуске AJAX-кода до обновления F5 Коды Php показаны в исходниках добавление переменной php в значение формы HTML как конвертировать несколько html-файлов с помощью Dompdf? Временные интервалы PHP Ошибка ODBC в PHP: «Нет кортежей, доступных в этом индексе результата»

Запустить процесс ffmpeg в фоновом режиме

Я хочу использовать ffmpeg для преобразования видео в .flv в php. В настоящее время у меня это работает, но он зависает браузера, пока файл не будет загружен и не будет завершен. Я смотрел документы php о том, как запустить процесс exec () в фоновом режиме, а также обновлять процесс с помощью возвращаемого PID. Вот что я нашел:

//Run linux command in background and return the PID created by the OS function run_in_background($Command, $Priority = 0) { if($Priority) $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!"); else $PID = shell_exec("nohup $Command > /dev/null & echo $!"); return($PID); } 

Существует также трюк, который я использую для отслеживания работы фоновой задачи с использованием возвращаемого PID:

 //Verifies if a process is running in linux function is_process_running($PID) { exec("ps $PID", $ProcessState); return(count($ProcessState) >= 2); } 

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

Благодаря!

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

Вероятно, так я и сделал:

  • веб-страница PHP добавляет запись в базу данных, чтобы указать, «этот файл должен быть обработан»
    • и отображает сообщение пользователю; что-то вроде «ваш файл будет обработан в ближайшее время»
  • В CLI выполните пакетный процесс с новыми вставленными файлами
    • во-первых, отметьте запись как «обработку»,
    • делать ffmpeg вещь
    • отметьте файл как «обработанный»,
  • И, на веб-странице, вы можете показать пользователю, в каком состоянии находится его файл:
    • если он еще не обработан
    • если он обрабатывается
    • или если он был обработан – вы можете дать ему ссылку на новый видеофайл.

Вот пара других мыслей:

  • В тот день, когда ваше приложение станет больше, вы сможете:
    • один «веб-сервер»
    • многие «серверы обработки»; в вашем приложении это функция ffmpeg, которая потребует большого количества CPU, а не для обслуживания веб-страниц; поэтому, имея возможность масштабировать эту часть, это хорошо (это другое – «блокировать» файлы, указывая на них как «обработку» в БД: таким образом, у вас не будет нескольких серверов обработки, пытающихся обрабатывать один и тот же файл)
  • Вы используете PHP только с веб-сервера для создания веб-страниц, на которых работает веб-сервер.
    • Тяжелая / длительная обработка – это не работа веб-сервера!
    • В тот день, когда вы захотите переключиться на что-то еще, кроме PHP для части «обработки», это будет проще.

Ваш «скрипт обработки» должен запускаться каждые две минуты; вы можете использовать cron для этого, если вы находитесь на Linux-подобной машине.


Изменить: немного больше информации, после просмотра комментария

Поскольку часть обработки выполняется из CLI, а не из Apache, вам не нужны какие-либо «фоновые» манипуляции: вы можете просто использовать shell_exec , который вернет весь вывод команды в ваш PHP-скрипт, когда он закончит делать это. работа.

Для пользователя, просматривающего веб-страницу с надписью «Обработка», она будет выглядеть как обработка фона; и, в некотором смысле, это будет, так как обработка будет выполняться другим процессом (возможно, даже на другой машине).

Но для вас это будет намного проще:

  • одна веб-страница (ничего "фон")
  • один сценарий CLI, без каких-либо фоновых данных.

Ваш сценарий обработки может выглядеть примерно так, я полагаю:

 // Fetch informations from DB about one file to process // and mark it as "processing" // Those would be fetched / determined from the data you just fetched from DB $in_file = 'in-file.avi'; $out_file = 'out-file.avi'; // Launch the ffmpeg processing command (will probably require more options ^^ ) // The PHP script will wait until it's finished : // No background work // No need for any kind of polling $output = shell_exec('ffmpeg ' . escapeshellarg($in_file) . ' ' . escapeshellarg($out_file)); // File has been processed // Store the "output name" to DB // Mark the record in DB as "processed" 

На самом деле проще, чем вы впервые подумали, не так ли? 😉
Просто не беспокойтесь о фоновых материалах: важно только, чтобы скрипт обработки запускался регулярно, начиная с crontab.

Надеюсь это поможет 🙂

Вам не нужно писать отдельный скрипт php для этого (хотя вы можете захотеть позже, если вы реализуете какую-то систему очередей).

Ты почти там. Единственная проблема заключается в том, что shell_exec () вызывает блокировку для ожидания возврата оболочки. Вы можете избежать этого, если вы перенаправляете весь вывод из команды в оболочке, чтобы затушить файл или / dev / null и выполнить фоновое задание (с помощью оператора &). Таким образом, ваш код станет следующим:

 //Run linux command in background and return the PID created by the OS function run_in_background($Command, $Priority = 0) { if($Priority) { shell_exec("nohup nice -n $Priority $Command 2> /dev/null > /dev/null &"); } else { shell_exec("nohup $Command 2> /dev/null > /dev/null &"); } } 

К сожалению, я не думаю, что есть способ получить PID.