Процесс php ffmpeg exec и shell_exec останавливается через несколько секунд

Я использую файл сценария PHP с простым интерфейсом html для управления запуском и остановкой процесса FFMPEG из браузера, цель сценария - запустить прямую трансляцию на моем сервере, которая обычно работает в течение нескольких часов без остановки (используя ffmpeg и nginx-rtmp) мой сценарий был работает отлично, пока я недавно не заметил. Это странное поведение, вот мои переменные php-скрипта

$cast =" /usr/sbin/ffmpeg -loglevel 0 -thread_queue_size 32768 -re -i '".$src."' -i /var/www/example/logo.png -r 23.976 -strict -2 480x360 -aspect 16:9 -filter_complex 'overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)-23' -vcodec libx264 -x264opts colormatrix=bt709 -profile:v high444 4 -b:v 290k -maxrate 290k -bufsize 250k  -af "aresample=async=1:min_hard_comp=0.100000:first_pts=0" -acodec libfdk_aac -profile:a aac_he_v2 -b:a 16k -map_metadata -1 -f flv  rtmp://localhost/hls/live 2>/dev/null >/dev/null  & " ; 
$output =  shell_exec( $cast   )    ;

Это похоже на то, что процесс FFMPEG продолжается до тех пор, пока исходный процесс php (который его вызывает) не умрет, сначала я подумал, что это проблема с командой source или ffmpeg, но я тестирую ту же команду на продажу, и она работает отлично. Я подозреваю, что на STDIO и т. Д. Не было перенаправлено правильно. даже когда я запускаю тот же php-скрипт из оболочки, он останавливается через несколько секунд.

=Изменить=

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

Здесь подробности моей ОС: -

DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"

person Salem    schedule 30.09.2019    source источник
comment
Вы отправляете команду в фоновый режим, поэтому она немедленно вернется. Вы не получите от него результата. Также вы должны использовать escapeshellarg() php.net/escapeshellarg   -  person miken32    schedule 01.10.2019
comment
Эта страница заблокирована только с моим IP-адресом, в любом случае команда переходит в фоновый режим, но через короткое время она останавливается, в то время как я мог запускать ее из оболочки в течение нескольких часов.   -  person Salem    schedule 01.10.2019
comment
Попробуйте добавить nohup: nohup /usr/sbin/ffmpeg .....   -  person Jannes Botis    schedule 04.10.2019
comment
То же самое ffmpeg живет недолго, я думаю, проблема в ffmpeg программе, а не в PHP.   -  person Salem    schedule 05.10.2019
comment
Я не могу найти ссылку, но я, кажется, помню, что любой порожденный фоновый процесс умрет, когда завершится запрос apache, вызвавший его. Вы можете предотвратить это, используя префикс NOHUP для этой команды shell_exec.   -  person AD7six    schedule 07.10.2019


Ответы (2)


Хорошо, хорошо, после нескольких дней попыток и расследования проблема выглядит так, как будто основная проблема была с ffpmeg по неизвестной причине, по которой я отказываюсь работать без определения какого-либо выходного канала, я предполагаю, что входной поток время от времени пропускал некоторые кадры. в любом случае это то, что я добавляю в конец команды ffmpeg

$cast ="< /dev/null /usr/sbin/ffmpeg -loglevel verbose -thread_queue_size 12768 -re -i \"$link/$chnl\" -r 23.976 -s 480x360  -vcodec libx264 -b:v $bitrate -minrate $bitrate -maxrate $bitrate -bufsize $bitrate -acodec aac -b:a 29k -map_metadata -1 -f flv rtmp://localhost/hls/live  </dev/null >/dev/null 2>/var/www/vlc10/ffmpeg.log & " ;
exec(   $cast   ) ; 

Мне пришлось перенаправить ffmpeg в файл журнала, подобный этому </dev/null >/dev/null 2>/var/www/vlc10/ffmpeg.log & накануне ffmpeg был беззвучный режим, но он не работал "или, по крайней мере, вылетал через несколько секунд".

person Salem    schedule 06.10.2019

PHP в CLI и PHP в виде модуля FPM или Apache имеют разные конфигурации (php.ini)

Поэтому в вашем случае вам нужно изменить max_execution_time для правильной среды. Вы можете установить его в соответствующем php.ini или с помощью ini_set() или с помощью set_time_limit().

РЕДАКТИРОВАТЬ: Возможно, вы хотите переключиться на exec(), но, пожалуйста, продолжайте в уме:

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

И, пожалуйста, используйте escapeshellarg()

person DragonSGA    schedule 30.09.2019
comment
на самом деле exec не должен использовать параметр max_excution_time, так как предполагается, что он работает в фоновом режиме, и вы забыли, если установить максимальное время выполнения, браузер будет зависать, ожидая, пока процесс ffmpeg прекратит работу. - person Salem; 01.10.2019
comment
Я думаю, что это действительно связано с этим, если вы читаете документы: php. net/manual/en/function.shell-exec.php Выполнить команду через оболочку и вернуть полный вывод в виде строки. Таким образом, он работает до тех пор, пока процесс не даст вам результат, который является возвращаемым значением. - person DragonSGA; 04.10.2019
comment
Пожалуйста, перечитайте документы, на которые вы ссылаетесь, и вопрос, особенно этот бит: 2>/dev/null >/dev/null &. Это тривиально проверить с помощью такого скрипта <?php shell_exec("sleep 30 2>/dev/null >/dev/null &"); - person AD7six; 07.10.2019