3

我正在尝试使用 html5 视频播放存储在 MySQL DB 中的 .MP4 文件。我能够让它播放,但问题是它会在开始播放之前首先从数据库中下载所有内容。在线测试时,视频开始播放几乎要花很长时间。当您将视频作为文件系统中的文件播放时,这会有所不同。从文件播放随着文件的下载逐渐播放。无论如何我可以让它像文件系统一样播放。

您的帮助将不胜感激。

下面是使用适当的标头从数据库中检索的 PHP 代码。

        $size   = $meta_object->video_file_size;                     // File size
        $length = $size;                             // Content length
        $start  = 0;                                 // Start byte
        $end    = $size - 1;                         // End byte

        header('Content-type: video/mp4');
        header("Accept-Ranges: bytes");
        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;
            header('HTTP/1.1 206 Partial Content');
        } 
        header("Content-Transfer-Encoding: binary");
        header("Content-Range: bytes $start-$end/$size");

        while($row = mysql_fetch_array($query)){                
            extract($row);
            echo $video_file_data;
        }
        header("Content-Length: ".$length);

以下是适用于文件系统方法的方法:

    $fpath = "tmp_video/sugarcane.mp4";
    $fp = fopen($fpath, 'rb');

    $size   = filesize($fpath);                  // File size
    $length = $size;                             // Content length
    $start  = 0;                                 // Start byte
    $end    = $size - 1;                         // End byte

    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("Content-Range: bytes $start-$end/$size");
    header("Content-Length: ".$length);
    header('Content-type: video/mp4');
    header("Accept-Ranges: bytes");

    $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);
4

1 回答 1

2

不要将视频存储在数据库中。将其存储在文件系统上,其位置在 db.xml 中。当您将视频元素指向其 URI 时,您将能够利用渐进式下载。这也将使您的数据库更小更快。

于 2013-04-26T14:38:01.113 回答