Combinu
Combinu

Reputation: 907

PHP mp4 stream to browser

I am trying to stream a simple mp4 video to a video.js player using php.

I found here a simple function to use and modified a bit but the video player is issuing an error even when i go directly to the link i get an error that media is not ok or plugin failed to load (when using the direct link on safari)

Here is the code snippet:

$token = $_GET['token'];

if ($token == 1 )
{

    $path = '../videos/vid1.mp4';

    $size=filesize($path);

    $fm=@fopen($path,'rb');
    if(!$fm) {
        // You can also redirect here
        header ("HTTP/1.0 404 Not Found");
        die();
    }

    $begin=0;
    $end=$size;

    if(isset($_SERVER['HTTP_RANGE'])) {
        if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) {
            $begin=intval($matches[0]);
            if(!empty($matches[1])) {
                $end=intval($matches[1]);
            }
        }
    }

    if($begin>0||$end<$size)
        header('HTTP/1.0 206 Partial Content');
    else
        header('HTTP/1.0 200 OK');

    header("Content-Type: video/mp4");
    header('Accept-Ranges: bytes');
    header('Content-Length:'.($end-$begin));
    header("Content-Disposition: inline;");
    header("Content-Range: bytes $begin-$end/$size");
    header("Content-Transfer-Encoding: binary\n");
    header('Connection: close');

    $cur=$begin;
    fseek($fm,$begin,0);

    while(!feof($fm)&&$cur<$end&&(connection_status()==0))
    { print fread($fm,min(1024*16,$end-$cur));
        $cur+=1024*16;
        usleep(1000);
    }
    die();
}

Ignore token as that is for testing purposes only. Is there something wrong with my code and is there any other practical way to stream mp4 or other media types to the browser?

Regards

Upvotes: 1

Views: 8497

Answers (2)

Ibrahim
Ibrahim

Reputation: 11

here's a simple solution:

if (access_token_valid()) {
$file = $_GET['file'];
    if (file_exists($file)) {
    header('Location: 
        '.$file);
    } else {
    header('Location: 
        404.mp4');
    }
} else {
header('Location: 
    403.mp4');
}

Upvotes: 1

Combinu
Combinu

Reputation: 907

Solved using this also found here... Sorry for posting but to who will be redirected here can have options.

Working code snippet:

$file = '../videos/vid1.mp4';
$fp = @fopen($file, 'rb');

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

header('Content-type: video/mp4');
//header("Accept-Ranges: 0-$length");
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;
    fseek($fp, $start);
    header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: " . $length);

$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);
exit();

Upvotes: 4

Related Questions