Symfony2视频流

时间:2013-01-28 09:51:12

标签: symfony streaming video-streaming

我正在symfony2编写应用,我遇到了视频流问题。

如果一个操作需要很长时间才能执行 - 例如1 minute,整个应用程序将被冻结(在第二个选项卡中打开时),并且必须等待执行结束。

问题出在哪里?

// EDIT

    public function streamAction($fileName) {

    $user = $this->get('security.context')->getToken()->getUser();
    $request = $this->getRequest();

    $uid = $request->get('uid') != 'null' ? $user->getId() : $request->get('uid');

    $libPath = $this->_libPath('Users', 'uid' . str_pad($uid, 6, "0", STR_PAD_LEFT));

    $file = pathinfo($fileName);
    $fileName = $file['basename'];
    $fileExt = $file['extension'];
    $filePath = realpath($libPath . $fileName);

    if (in_array($fileExt, $this->formats['video'])) {
        $mime = 'video';
    }

    if (in_array($fileExt, $this->formats['audio'])) {
        $mime = 'audio';
    }

    $mime .= '/' . $fileExt;

    header("Accept-Ranges: bytes");

    if (is_file($filePath)) {
        header("Content-type: $mime");
        if (isset($_SERVER['HTTP_RANGE'])) {

            $fp = fopen($filePath, 'rb');
            $size = filesize($filePath);
            $length = $size;
            $start = 0;
            $end = $size - 1;

            if (isset($_SERVER['HTTP_RANGE'])) {
                $c_start = $start;
                $c_end = $end;
                list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);

                if (strpos($range, ',') !== false) {
                    header('HTTP/1.1 416 Requested Range Not Satisfiable');
                    header("Content-Range: bytes $start-$end/$size");
                    exit;
                }

                if ($range == '-') {
                    $c_start = $size - substr($range, 1);
                } else {
                    $range = explode('-', $range);
                    $c_start = $range[0];
                    $c_end = ( isset($range[1]) && is_numeric($range[1]) ) ? $range[1] : $size;
                }

                $c_end = ($c_end > $end) ? $end : $c_end;
                if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
                    header('HTTP/1.1 416 Requested Range Not Satisfiable');
                    header("Content-Range: bytes $start-$end/$size");
                    exit;
                }

                $start = $c_start;
                $end = $c_end;
                $length = $end - $start + 1;
                fseek($fp, $start);
                header('HTTP/1.1 206 Partial Content');
                header('ETag: "' . md5(microtime()) . '"');
            }

            header("Content-Range: bytes $start-$end/$size");
            header("Content-Length: $length");
            header('Connection: Close');

            $buffer = 1024 * 8;
            while (!feof($fp) && ($p = ftell($fp)) <= $end) {
                if ($p + $buffer > $end) {
                    $buffer = $end - $p + 1;
                }
                set_time_limit(0);
                echo fread($fp, $buffer);
                flush();
            }
            fclose($fp);
        } else {
            header("Content-Length: " . filesize($filePath));
            readfile($filePath);
        }
    } else {
        echo "error";
    }
    die();
}

问题不是代码,因为symfony2不仅阻止了流式传输,还阻止了下载文件等其他长时间操作。

2 个答案:

答案 0 :(得分:5)

如果你使用像Symfony这样的OOP框架,为什么还要使用程序方法而不是Symfony提供的方法呢? 例如StreamedResponse类。

我为您提供了更多面向OOP / Symfony, 但是,如果提供的范围只是>php -m [PHP Modules] bcmath calendar Core ctype curl date dom ereg fileinfo filter ftp gd hash iconv imap json ldap libxml mbstring mcrypt mhash mysql mysqli mysqlnd odbc openssl pcre PDO pdo_mysql pdo_sqlite pdo_sqlsrv Phar Reflection session SimpleXML soap SPL standard tokenizer wddx xml xmlreader xmlwriter zip zlib [Zend Modules] ,您当前将范围重置为...文件大小?我很确定这不是你应该做的。我想你应该仔细检查一下!

以下是streamAction()的审核版本:

-

答案 1 :(得分:0)

这是因为PHP锁定了会话。您的第一个请求将锁定会话,并且相同会话的后续请求(您的第二个选项卡)将在session_start()中阻止,直到第一个请求完成。 (具有相同会话的请求将按顺序完成,一个接一个地完成。)

有关会话并发的更多信息,请查看this link