一旦循环开始,将stdin传递给ReactPhp进程

时间:2019-09-15 09:17:09

标签: php ratchet reactphp

因此,我有一个使用ReactPHP来运行进程的应用程序,我需要保持该子进程在后台运行,并能够提供其stdin数据。

在到目前为止的示例中,事情是在运行事件循环之前完成了stdin和stdout IO。

实际上,我已经尝试运行循环,并尝试稍后再写入子进程的stdin ...结果是错误,告诉我stdin为null。我转储了该过程,却发现确实stdin,stdout和stderr都为空。

那么,如何在已经开始的循环中继续将输入提供给正在运行的进程?

代码如下:

<?php
namespace MyApp;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

use React\EventLoop\Factory;
use React\ChildProcess\Process;


class Chat implements MessageComponentInterface {
    private $streamUrl;
    private $streamName;
    private $vcodec; 

    private $ffpmeg; // The ffmpeg process


    public function onOpen(ConnectionInterface $conn) {
        error_log('EVENT! socket open');
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        error_log('EVENT! socket message');
        error_log("message is: $msg");

        if (substr($msg, 0, 13) == 'stream_name: ') {
            error_log('SETTING STREAM NAME!.');
            $this->streamName = substr($msg, 13);
        } elseif (substr($msg, 0, 12) == 'stream_url: ') {
            error_log('SETTING STREAM URL!.');
            $this->streamUrl = substr($msg, 12);
        } elseif (substr($msg, 0, 8) == 'vcodec: ') {
            error_log('SETTING VCODEC!.');
            $this->vcodec = substr($msg, 8);
        } elseif ($msg == 'reset_stream') {
            error_log('RESETTING STREAM!.');
            //todo kill process.
            $this->ffmpeg = null;

            $this->streamUrl = null;
            $this->streamName = null;
            $this->vcodec = null;
        }

        $hasStreamInfo = !empty($this->vcodec) && !empty($this->streamUrl) && !empty($this->streamName);

        if ($hasStreamInfo && empty($this->ffmpeg)) {
            error_log("We essentially have all we need to stream at this point.");

            $loop = Factory::create();

            $this->ffmpeg = new Process('ffmpeg', [
                // Facebook requires an audio track, so we create a silent one here.
                // Remove this line, as well as `-shortest`, if you send audio from the browser.
                '-f', 'lavfi', '-i', 'anullsrc',

                // FFmpeg will read input video from STDIN
                '-i', '-',

                // Because we're using a generated audio source which never ends,
                // specify that we'll stop at end of other input.  Remove this line if you
                // send audio from the browser.
                '-shortest',

                // If we're encoding H.264 in-browser, we can set the video codec to 'copy'
                // so that we don't waste any CPU and quality with unnecessary transcoding.
                // If the browser doesn't support H.264, set the video codec to 'libx264'
                // or similar to transcode it to H.264 here on the server.
                '-vcodec', $this->vcodec,

                // AAC audio is required for Facebook Live.  No browser currently supports
                // encoding AAC, so we must transcode the audio to AAC here on the server.
                '-acodec', 'aac',

                // FLV is the container format used in conjunction with RTMP
                '-f', 'flv',

                // The output RTMP URL.
                // For debugging, you could set this to a filename like 'test.flv', and play
                // the resulting file with VLC.  Please also read the security considerations
                // later on in this tutorial.

                '/home/hel/Desktop/workspace/soketo/test.flv'
                //  $this->streamUrl
            ]);
            error_log("FFMPEG CREATED.");

            $this->ffmpeg->start($loop);

            error_log("FFMPEG STARTED.");

            $this->ffmpeg->stdout->on('data', function ($chunk) {
                echo $chunk;
            });

            $this->ffmpeg->on('exit', function($exitCode, $termSignal) {
                echo 'Process FFMPEG exited with code ' . $exitCode . PHP_EOL;
            });

            $this->ffmpeg->stdout->on('error', function (Exception $e) {
                echo 'error: ' . $e->getMessage();
            });


            /*    $process->stdin->write($data);
            $process->stdin->end($data = null);*/

            error_log("Stream created, it is time to die.");
            $loop->run();

            error_log('RUN LOOP.');

            return;
        } elseif ($hasStreamInfo && !empty($this->ffmpeg)) {
            error_log('ffmpeg NOT EMPTY. writing to it.');

            var_dump($this->ffmpeg);
            $this->ffmpeg->stdin->write($msg);
        }
        //$process->stdin->end($data = null);

    } 

    public function onClose(ConnectionInterface $conn) {
        error_log('EVENT! socket close');
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        error_log('EVENT! socket error');
    }
}

确实,可能不是我有史以来最好的代码,但是我有点仓促和沮丧。 另外,是的,这个想法是有一个棘轮套接字,我的应用程序将连接到该棘轮套接字,以便将视频流传输到rtmp服务器。

谢谢大家!

0 个答案:

没有答案