如何解决php实现rtsp协议

1. 环境要求

使用php7在cli模式下运行。

2. 安装插件

使用插件 composer require phpbg/rtsp

3. 问题描述?

使用php编写rtsp协议,推流没有报错,但是拉流的时候没有数据,客户端会自动断开连接,没有搞明白拉流这里除了什么问题。

4. 业务源代码

<?php
require __DIR__ . '/vendor/autoload.php';
use PhpBg\Rtsp\Session;
$loop = React\EventLoop\Factory::create();
//Normal port is 554 but we use 5540 instead to avoid root required
$socket = new \React\Socket\TcpServer('tcp://0.0.0.0:5540', $loop);
$logger=new \PhpBg\MiniHttpd\Logger\Console(\Psr\Log\LogLevel::DEBUG, 'php://stderr', new \PhpBg\MiniHttpd\Logger\ConsoleFormatter(false));
global $sessions;
$middlewares = [
    //$logger,
new \PhpBg\Rtsp\Middleware\AutoCseq(),
new \PhpBg\Rtsp\Middleware\AutoContentLength(),
function (\PhpBg\Rtsp\Message\Request $request, \React\Socket\ConnectionInterface $connection)use($loop,$logger,$sessions) {
    static $sessions;
    var_dump($request);
    $method=$request->method;
    $response = \PhpBg\Rtsp\Message\MessageFactory::response();
    $response->setHeader('cseq', $request->getHeader('cseq'));
    switch ($method){
        case "SETUP":
            $response->setHeader('transport', $request->getHeader('transport').';server_port=');
            $transport=$request->getHeader('transport');
            $first=explode(';',$transport);
            $array=[];
            $rtpPort='';
            $rtcpPort='';
            foreach ($first as $k=>$v){
                list($key,$val)=explode('=',$v);
                $array[$key]=$val;
                if ($key=='client_port'){
                    echo "获取播放器的端口\r\n";
                    var_dump($val);
                    $ports = explode('-', $val);
                    $rtpPort = $ports[0];
                    $rtcpPort = $ports[1];
                }
            }
            $sessionId = rand(10000000, 99999999);
            $session =  new Session($sessionId, $loop, $connection, $logger);
            $session->proto = 'UDP';

            $session->ports = [$rtpPort, $rtcpPort];
            $address = $connection->getRemoteAddress();
            $session->clientIp = trim(parse_url($address, PHP_URL_HOST), '[]');
            $session->isInterleaved = false;
            $session->transport = $request->getHeader('transport');

            $uri = trim($request->uri, '/');
            $resourcePath = explode('/', $uri);
            $channelServiceId = array_pop($resourcePath);
            $session->uri = $uri;
            //var_dump($session);
            $sessions[$sessionId]=$session;
            $response->setHeader('session', $sessionId);
            $response->setHeader('rtp-info', 'url=rtsp://127.0.0.1:5540/live/streamid=1;url=rtsp://127.0.0.1:5540/live/streamid=0;');
            return $response;
            break;
        case "PLAY":

            $sessionId=$request->getHeader('session');
            $response->setHeader('rtp-info', 'url=rtsp://127.0.0.1:5540/live/streamid=1;url=rtsp://127.0.0.1:5540/live/streamid=0;');
            $session = $sessions[$sessionId];
            $session->play();
            return $response;
        case "DESCRIBE":
            $startTime = time() + 2208988800;
            $response->body = "v=0\r\no=- 0 $startTime IN IP4 0.0.0.0\r\ns=bar\r\nt=$startTime 0\r\nm=video 0 udp 33\r\n";
            $response->setHeader('content-type', 'application/sdp');
            return $response;
        case "OPTIONS":
            if ($request->hasHeader('session')) {
                $sessionId = (int)$request->getHeader('session');
                if (!isset($sessions[$sessionId])) {
                    $response->statusCode = 454;
                    $response->reasonPhrase = 'Session Not Found';
                    return $response;
                }
                $session = $sessions[$sessionId];
                $session->keepAlive();
            }
            $response->setHeader('public', 'SETUP, TEARDOWN, PLAY');
            return $response;
        case "TEARDOWN":
            $sessionId = (int)$request->getHeader('session');
            var_dump("客户端要求关闭TEARDOWN");
            var_dump($sessionId);
            $session = $sessions[$sessionId];
            if ($session!=null){
                $session->teardown();
            }
            return $response;
            break;
        default:
            //todo  本项目实现了rtsp协议,但是不能正常推流和拉流,根据猜测,还应该创建一个管道,将数据放入到管道,推流就是将数据存入到管道,拉流就是将数据取出,
            //todo 难点是推流的数据在哪里接收,知道了数据的位置才知道怎么处理数据
            return $response;
    }
}
];

$server = new \PhpBg\Rtsp\Server(new \PhpBg\Rtsp\Middleware\MiddlewareStack($middlewares));

$server->on('error', function (\Exception $e) {
echo $e->getMessage() . "\r\n";
echo $e->getTraceAsString() . "\r\n";
});

$server->listen($socket);
echo "Server started\r\n";
echo "Open any decent video player (e.g. vlc, mpv) and open rtsp://localhost:5540\r\n";
$loop->run();
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!