Я использую 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
Пожалуйста, предоставьте мне решение для того же как можно скорее.
Спасибо.
Естественный способ бега 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
,
Прочитайте официальная документация для получения дополнительной информации.
Это случилось со мной, я нашел это на другом форуме; хитрость внутри 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 отличается от пользователя, когда вы вводите текст прямо в командной строке. Я предполагаю, что у него нет такого же списка ярлыков или чего бы то ни было.
Не знаю точно, почему, но у меня это сработало!
Удачи.
Я рассмотрел решение, которое помогает большинству людей, с которыми я говорил об этом, в другой ветке.
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