ffmpeg — читает и пишет один и тот же файл зависает

Я пытаюсь использовать FFMPEG, чтобы сделать некоторые работы с видео на сервере, и что мне нужно сделать, это получить прогресс процесса.

Я немного искал и нашел это решение который говорит записать журнал в файл, а затем прочитать и проанализировать его.

Что сводит меня с ума, так это то, что я говорю FFMPEG — с exec — (процесс А) записать журнал в файл, но когда я пытаюсь его прочитать — с file_get_contents() — (процесс Б) не показывает содержимое до процесс А закончен (или прервал сценарий PHP).

Так когда процесс А заканчивается или он говорит «Тайм-аут сценария PHP», тогда я могу читать файл сколько угодно раз, обновляя страницу (процесс Б) и показывая содержимое в то время.

Я пытался использовать fopen() создать файл с w, w+ а также a параметры, используя — и без использования — fclose(), Я пытался использовать также flock() на всякий случай становится быстрее читать процесс Б если он знает, что он уже заблокирован и не должен ждать, но тогда FFMPEG не сможет записать в файл.

Я искал многопоточность тоже, но я думаю, что должно быть проще и проще.

Я использовал также контекст CURL и HTTP, как эта ссылка предлагает, но не повезло.

Я тоже пытался использовать PHP-FFMPEG, но он не поддерживает последнюю версию FFMPEG, поэтому я не могу его использовать.

Когда я говорил раньше «(или прервал сценарий PHP)», это потому, что я пытался ждать и, когда PHP получил тайм-аут, процесс Б работал хорошо, и файл все еще обновлялся.

Процесс A (fileA.php)

exec('ffmpeg -y -i input_file.mp4 output_file.avi 2> C:\Full\Path\To\File\log.txt 1>&2');

Процесс Б (fileB.php)

$content = file_get_contents($file);

if($content){
//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 time in the file that is already encoded
preg_match_all("/time=(.*?) bitrate/", $content, $matches);

$rawTime = array_pop($matches);

//this is needed if there is more than one match
if (is_array($rawTime)){$rawTime = array_pop($rawTime);}

//rawTime is in 00:00:00.00 format. This converts it to seconds.
$ar = array_reverse(explode(":", $rawTime));
$time = floatval($ar[0]);
if (!empty($ar[1])) $time += intval($ar[1]) * 60;
if (!empty($ar[2])) $time += intval($ar[2]) * 60 * 60;

//calculate the progress
$progress = round(($time/$duration) * 100);

echo "Duration: " . $duration . "<br>";
echo "Current Time: " . $time . "<br>";
echo "Progress: " . $progress . "%";

}

Процесс

Я просто открываю fileA.php на вкладке Chrome и через несколько секунд я открываю fileB.php на другой вкладке Chrome (и остается погрузка).

Что мне нужно

Мне нужно иметь возможность загрузить файл и показать информацию, которую я хочу показать во время записи файла ( exec а также FFMPEG или другие сценарии PHP), поэтому я могу обновлять процент выполнения с помощью некоторых вызовов AJAX.

Дополнительная информация

На данный момент я использую PHP 5.4 на IIS 7.5 с Windows 7 Professional.

Спасибо всем за потраченное время, помощь и терпение!

С наилучшими пожеланиями.

3

Решение

Кажется, сейчас работает. После стольких попыток без работы единственное изменение, которое я сделал, кажется, имеет смысл писать session_write_close() до вызывая exec команда. Итак, следуя моему примеру, это будет что-то вроде:

session_write_close();
exec('ffmpeg -y -i input_file.mp4 output_file.avi 2> C:\Full\Path\To\File\log.txt 1>&2');

Теперь, я был бы очень рад, если бы кто-то сказал мне, имеет ли это какой-то смысл или это имеет отношение к чему-то еще, что я не вижу.

Спасибо!

0

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

Других решений пока нет …

По вопросам рекламы [email protected]