Я играл с этим несколько дней. Эта штука с «ffmpegprogress» помогла, но мне было очень трудно приступить к работе с моими настройками, и трудно было прочитать код.
Чтобы показать прогресс ffmpeg, вам нужно сделать следующее:
- запустить команду ffmpeg из php без ожидания ответа (для меня это была самая сложная часть)
- скажите ffmpeg отправить его вывод в файл
- из внешнего интерфейса (AJAX, Flash и т. Д.) Попал либо в этот файл напрямую, либо в файл php, который может извлекать прогресс из вывода ffmpeg.
Вот как я решил каждую часть:
1.
Я получил следующую идею от "ffmpegprogress". Вот что он сделал: один файл PHP вызывает другой через сокет http. Второй фактически запускает "exec", и первый файл просто зависает на нем. Для меня его реализация была слишком сложной. Он использовал "fsockopen". Мне нравится CURL. Итак, вот что я сделал:
$url = "http://".$_SERVER["HTTP_HOST"]."/path/to/exec/exec.php";
curl_setopt($curlH, CURLOPT_URL, $url);
$postData = "&cmd=".urlencode($cmd);
$postData .= "&outFile=".urlencode("path/to/output.txt");
curl_setopt($curlH, CURLOPT_POST, TRUE);
curl_setopt($curlH, CURLOPT_POSTFIELDS, $postData);
curl_setopt($curlH, CURLOPT_RETURNTRANSFER, TRUE);
// # this is the key!
curl_setopt($curlH, CURLOPT_TIMEOUT, 1);
$result = curl_exec($curlH);
Установка CURLOPT_TIMEOUT в 1 означает, что он будет ждать ответа в течение 1 секунды. Желательно, чтобы это было ниже. Существует также CURLOPT_TIMEOUT_MS, который занимает миллисекунды, но у меня это не сработало.
Через 1 секунду CURL зависает, но команда exec все еще выполняется. Часть 1 решена.
Кстати - несколько человек предлагали использовать для этого команду «nohup». Но мне это не помогло.
* ТАКЖЕ! Наличие php-файла на вашем сервере, который может выполнять код непосредственно из командной строки, является очевидной угрозой безопасности. Вы должны иметь пароль или каким-либо образом закодировать данные поста.
2.
Сценарий exec.php выше также должен указывать ffmpeg выводить в файл. Вот код для этого:
exec("ffmpeg -i path/to/input.mov path/to/output.flv 1> path/to/output.txt 2>&1");
Обратите внимание на «1> путь / к / output.txt 2> & 1». Я не эксперт по командной строке, но из того, что я могу сказать, в этой строке написано "отправлять нормальный вывод в этот файл и отправлять ошибки в одно и то же место". Проверьте этот URL для получения дополнительной информации: http://tldp.org/LDP/abs/html/io-redirection.html
3.
Из внешнего интерфейса вызовите php-скрипт с указанием расположения файла output.txt. Этот php-файл будет извлекать прогресс из текстового файла. Вот как я это сделал:
// # get duration of source
preg_match("/Duration: (.*?), start:/", $content, $matches);
$rawDuration = $matches[1];
// # rawDuration is in 00:00:00.00 format. This converts it to seconds.
$ar = array_reverse(explode(":", $rawDuration));
$duration = floatval($ar[0]);
if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;
// # get the current time
preg_match_all("/time=(.*?) bitrate/", $content, $matches);
$last = array_pop($matches);
// # this is needed if there is more than one match
if (is_array($last)) {
$last = array_pop($last);
}
$curTime = floatval($last);
// # finally, progress is easy
$progress = $curTime/$duration;
Надеюсь, это кому-нибудь поможет.