Альтернативный метод захвата вывода PHP exec() из программы строки cmd (rtmpdump.exe)

В прошлом я несколько раз использовал функцию exec() для сбора информации из исполняемых файлов командной строки и намеревался сделать это снова с помощью RTMPDump.exe. PHP-код выглядит следующим образом и работает с любыми другими примерами командной строки, которые я использовал в прошлом, но в этом случае ничего не дает $output:

    $cmd = 'c:\rtmpdump\rtmpdump -r "rtmp://fms.domain.com/live/live_800"';
    exec($cmd, $output);
    foreach ($output as $item){
        // do something with this $item
    }

Я попробовал это, поместив командную строку Windows в файл .bat и запустив ее, в которой ase $output содержит только то, что было отражено в файле bat, но не вывод, показанный ниже, что и получается, когда я запустите команду вручную из командной строки.

C:\rtmpdump>rtmpdump -r "rtmp://fms.domain.com/live/live_800"
RTMPDump v2.3
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
Connecting ...
INFO: Connected...
ERROR: rtmp server sent error
Starting Live Stream
For duration: 2.000 sec
INFO: Metadata:
INFO:   author
INFO:   copyright
INFO:   description
INFO:   keywords
INFO:   rating
INFO:   title
INFO:   presetname            Custom
INFO:   creationdate          Tue May 08 03:00:23 2012
INFO:   videodevice           Osprey-440 Video Device 1B
INFO:   framerate             25.00
INFO:   width                 480.00
INFO:   height                360.00
INFO:   videocodecid          avc1
INFO:   videodatarate         800.00
INFO:   avclevel              30.00
INFO:   avcprofile            66.00
INFO:   videokeyframe_frequency10.00
INFO:   audiodevice           Osprey-440 Audio Device 1B
INFO:   audiosamplerate       22050.00
INFO:   audiochannels         1.00
INFO:   audioinputvolume      75.00
INFO:   audiocodecid          mp4a
INFO:   audiodatarate         48.00
#######
Download complete

C:\rtmpdump>rtmpdump

Программа запускается, это не проблема, есть выходной файл, который показывает дамп видеоданных, так что синтаксис исполняемого файла не проблема - вопрос в том, есть ли другой способ перехватить то, что rtmpdump.exe выводит на командное окно, которое НЕ захватывается при запуске его из PHP через exec().

И если это имеет значение, мне интересно использовать «INFO:...». Я пытаюсь определить, идет ли потоковое видео в реальном времени или нет. Сервер работает, но мне нужно знать, транслируется ли конкретный поток (live_800) или нет.


person GDP    schedule 09.05.2012    source источник
comment
Если команда выдает вывод в командной строке, которую exec не захватывает, вероятно, он выводится в stderr, а не в stdout. Полагаю, вам придется использовать proc_open.   -  person John Flatness    schedule 09.05.2012
comment
Можете ли вы запустить команду c:\rtmpdump\rtmpdump -r "rtmp://fms.domain.com/live/live_800" > out.txt в командной строке и посмотреть, были ли строки INFO отображены на терминале или захвачены в текстовом файле?   -  person Salman A    schedule 09.05.2012
comment
Салман, уже пробовал, но безуспешно. Джон Ф. - Похоже, что proc_open обладает огромным потенциалом - у меня не было возможности использовать его раньше, поэтому я с нетерпением жду возможности попробовать этот!   -  person GDP    schedule 09.05.2012
comment
JohnF: call_proc открыл для меня новые двери для исследования этой проблемы, поэтому, если вы хотите добавить свое предложение в качестве ответа, я с радостью приму его, в противном случае я отвечу на него сам, чтобы закрыть его.   -  person GDP    schedule 09.05.2012


Ответы (2)


Спасибо JohnF, который помог мне встать на правильный путь, если это понадобится другим новичкам, вот как я это сделал, используя proc_open:

$descriptorspec = array(
0 => array("pipe", "r"),    // stdin is a pipe that the child will read from
1 => array("pipe", "w"),    // stdout is a pipe that the child will write to
2 => array("pipe", "w")     // stderr is a pipe that the child will write to
);
$cmd = c:\rtmpdump\rtmpdump -r "rtmp://fms.domain.com/live/live_800 -B 1 -m 3";
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
    $stdin = stream_get_contents($pipes[0]);
    $stdout = stream_get_contents($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[0]);  fclose($pipes[1]);  fclose($pipes[2]);
    // It is important that you close any pipes before calling proc_close in order to avoid a deadlock
    $return_value = proc_close($process);   
}
person GDP    schedule 11.05.2012

Попробуйте функцию passthru.

person Fanda    schedule 09.05.2012
comment
Отличное предложение, но без кубиков :( - person GDP; 09.05.2012