видео — FFMpeg работает в командной строке, но не в скрипте PHP

Я использую FFMpeg для преобразования видео, и он работает нормально из командной строки. Я использую следующую команду:

ffmpeg -i input.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv

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

exec("ffmpeg -i input.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv",$output, $returnvalue);

$returnvalue = 127;

Установленный путь FFMPEG:

[root@localhost ~]# which ffmpeg

/root/bin/ffmpeg

Мой путь к сценарию:

www.domainname.com/core/foldername/ffmpeg.php

Пожалуйста, предоставьте мне решение для того же как можно скорее.

Спасибо.

5

Решение

Естественный способ бега ffmpeg из сценариев PHP это что-то вроде:

<?php
echo "Starting ffmpeg...\n\n";
echo shell_exec("ffmpeg -i input.avi output.avi &");
echo "Done.\n";
?>

Здесь есть несколько вопросов, на которые нужно обратить внимание. Во-первых, хотя мы указали, что мы хотим ffmpeg выполняется в фоновом режиме (с помощью оператора амперсанда «&») PHP скрипт будет не продолжать это исполнение до ffmpeg закончил свое исполнение. Это связано с тем, что упоминается в одной из заметок для PHP exec() функция, которая говорит:

Если программа запускается с этой функцией, чтобы она
продолжить работу в фоновом режиме, вывод программы должен быть
перенаправлен в файл или другой поток вывода. Неспособность сделать это будет
заставить PHP зависать, пока не закончится выполнение программы.

Не смущайтесь из-за показанного примераshell_exec() звоните вместо ​exec(), Все функции выполнения программы PHP поделиться похожей базой кода и ограничения.

Итак, чтобы обойти эту проблему, нам нужно сделать что-то вроде этого:

<?php
echo "Starting ffmpeg...\n\n";
echo shell_exec("ffmpeg -i input.avi output.avi >/dev/null 2>/dev/null &");
echo "Done.\n";
?>

Часть, которая говорит «> / DEV / нуль» перенаправит стандартный OUTPUT (стандартный вывод) ffmpeg экземпляр для /dev/null (эффективно игнорируя вывод) и «2> / DEV / нуль» перенаправит стандартную ОШИБКУ (stderr) на /dev/null (эффективно игнорируя любые сообщения журнала ошибок). Эти два могут быть объединены в более короткое представление: «> / dev / null 2>&1». Если хотите, вы можете прочитать больше о перенаправлении ввода / вывода.

Важное примечание должно быть упомянуто здесь. ffmpeg инструмент командной строки использует stderr для вывода сообщений журнала ошибок и stdout зарезервировано для возможного использования каналов (для перенаправления выходного медиапотока, сгенерированного из ffmpeg к другому инструменту командной строки). Это, как говорится, если вы запускаете свой ffmpeg в фоновом режиме вы, скорее всего, захотите перенаправить stderr в файл журнала, чтобы иметь возможность проверить это позже.

Еще одна вещь, о которой нужно позаботиться, это стандартный INPUT (stdin). Командная строка ffmpeg Инструмент выполнен в виде интерактивной утилиты, которая принимает вводимые пользователем данные (обычно с клавиатуры) и сообщает журнал ошибок на текущем экране / терминале пользователя. Когда мы бежим ffmpeg на заднем плане, мы хотим сказать ffmpeg что никакие входные данные не должны быть приняты (или ожидаемые) от stdin, Мы можем сказать это ffmpegснова используя перенаправление ввода / вывода ** «инструмент командной строки ffmpeg в фоновом режиме будет выглядеть примерно так:

<?php
echo "Starting ffmpeg...\n\n";
echo shell_exec("ffmpeg -y -i input.avi output.avi </dev/null >/dev/null 2>/var/log/ffmpeg.log &");
echo "Done.\n";
?>

The«-Y» опция используется для автоматической перезаписи выходного файла (output.avi) без запроса yes/no подтверждение. Если вам нужен противоположный сценарий, чтобы автоматически отменить весь процесс, если выходной файл уже существует, используйте «-N» вариант вместо

Библиотеки Обертки

Некоторые библиотеки PHP допускают перенос ffmpeg вызывает в PHP объекты и дает вам хороший синтаксис для работы, если вы не любите использовать командную строку. Одним из них является активно поддерживаемыйPHP-FFMpeg. Требуется только загрузить последние ffmpeg а также ffprobe построить отдельно от установки компонентов PHP. Затем вы можете запустить код PHP следующим образом:

$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
$video
->filters()
->resize(new FFMpeg\Coordinate\Dimension(320, 240))
->synchronize();
$video
->save(new FFMpeg\Format\Video\X264(), 'export-x264.mp4')

Конечно, вам нужно позаботиться о запуске такой задачи в фоновом режиме. Библиотеки, такие какGearmanClient облегчить это.

Замечания: FFmpeg-PHP это расширение, которое не разрабатывается с 2007 года (и требует «ffmpeg-0.4.9_pre1 или выше»), что означает, что вы можете использовать очень старую версию ffmpeg без возможности обновить ее до последней версии. Так как сделано много изменений / улучшений, внутри ffmpeg's код, каждый день, это делает ffmpeg-php несовместим с последними ffmpeg,

Прочитайте официальная документация для получения дополнительной информации.

4

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

Это случилось со мной, я нашел это на другом форуме; хитрость внутри PHP заключается в том, чтобы дать абсолютный путь к FFMPEG. Попробуйте запустить это так …

exec("/root/bin/ffmpeg -i input.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv",$output, $returnvalue);

Кое-что о том, что php отличается от пользователя, когда вы вводите текст прямо в командной строке. Я предполагаю, что у него нет такого же списка ярлыков или чего бы то ни было.

Не знаю точно, почему, но у меня это сработало!

Удачи.

2

Я рассмотрел решение, которое помогает большинству людей, с которыми я говорил об этом, в другой ветке.

https://stackoverflow.com/a/38626752/2074077

По сути, ваш пользователь должен иметь доступ к общедоступным каталогам.

<?php
exec('whoami'); // Gives you the running user; often it's www-data
?>

Затем измените свою общественную собственность на whoami пользователь.

sudo chown -R www-data:root /var/www
1
По вопросам рекламы [email protected]