Как стать автором
Обновить

Установить время выполнения консольной команды

Время на прочтение3 мин
Количество просмотров4.4K
Довелось однажды писать скрипт, который в процессе своей работы пробегал по списку видео файлов и для каждого запускал ffmpeg с ключом, позволяющим получить информацию о файле. Мне собственно требовалось время воспроизведения.

Все бы хорошо, да вот на одном файле ffmpeg подвисал и не думал завершаться, а в момент завершения отваливался и php скрипт без видимых на то причин.

После долгих поисков решения данной проблемы, был найден код, который после небольшой переделки я готов представить на ваш суд :)


Основная проблема заключалась в том, что не было возможности ограничить время выполнения ffmpeg.

Помог следующий код:

<?php

  /**
   * Run process with timeout
   * @param str $command
   * @param int $timeout - sec
   * @param int $sleep
   * @param str $file_out_put - if default value, then return true else return out of process
   * @return bool or str
   */
  function PsExecute($command, $timeout = 10, $sleep = 1, $file_out_put = '/dev/null') {

    $pid = PsExec($command, $file_out_put);

    if( $pid === false ) {
      return false;
    }

    $cur = 0;

    // пока не истекло время отведенное на выполнение скрипта продолжаем ждать
    while( $cur < $timeout ) {
      sleep($sleep);
      $cur += $sleep;
      
      if( !PsExists($pid) ) {
        // скрипт завершил своё выполнение, можно посмотреть его результат или просто вернуть true
        if ($file_out_put != '/dev/null') {
          return file_get_contents($file_out_put);
        } else {
          return true;
        }
      }
    }

    // не дождались пока звершиться скрипт, по этому автоматически убиваем его
    PsKill($pid);
    return false;
  }

  /**
   * Run process in background with out buffer to file
   * @param str $commandJob
   * @param str $file_out_put
   * @return int or false
   */
  function PsExec($commandJob, $file_out_put) {
    $command = $commandJob.' > '.$file_out_put.' 2>&1 & echo $!';
    exec($command ,$op);
    $pid = (int)$op[0];

    if($pid!="") return $pid;

    return false;
  }

  /**
   * If process exists then return true else return false
   * @param int $pid
   * @return bool
   */
  function PsExists($pid) {

    exec("ps ax | grep $pid 2>&1", $output);

    while( list(,$row) = each($output) ) {

      $row_array = explode(" ", $row);
      $check_pid = $row_array[0];

      if($pid == $check_pid) {
        return true;
      }

    }

    return false;
  }

  /**
   * Kill process
   * @param int $pid
   */
  function PsKill($pid) {
    exec("kill -9 $pid", $output);
  }

?>


* This source code was highlighted with Source Code Highlighter.


Код довольно простой и понятный, по этому наверное нет смысла писать к нему описание.

Пример использования

PsExecute('ffmpeg -i video_file.flv', 5, 1, '/tmp/1.txt');
Если за 5 секунд ffmpeg не завершится, то он будет завершен автоматически.

Скачать в архиве
Теги:
Хабы:
Всего голосов 31: ↑27 и ↓4+23
Комментарии23

Публикации

Истории

Работа

PHP программист
184 вакансии

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
26 октября
ProIT Network Fest
Санкт-Петербург
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань