Skip to content

Instantly share code, notes, and snippets.

@langemike
Forked from m4tthumphrey/streamed.php
Last active December 28, 2022 08:06
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save langemike/d196fe2d201c1e574205 to your computer and use it in GitHub Desktop.
Save langemike/d196fe2d201c1e574205 to your computer and use it in GitHub Desktop.
Laravel response macro for streamed responses with seeking support (with bug fixes & usage example)
<?php
Response::macro('streamed', function($type, $size, $name, $callback) {
$start = 0;
$length = $size;
$status = 200;
$headers = [
'Content-Type' => $type,
'Content-Length' => $size,
'Accept-Ranges' => 'bytes'
];
if (false !== $range = Request::server('HTTP_RANGE', false)) {
list($param, $range) = explode('=', $range);
if (strtolower(trim($param)) !== 'bytes') {
header('HTTP/1.1 400 Invalid Request');
exit;
}
list($from, $to) = explode('-', $range);
if ($from === '') {
$end = $size - 1;
$start = $end - intval($from);
} elseif ($to === '') {
$start = intval($from);
$end = $size - 1;
} else {
$start = intval($from);
$end = intval($to);
}
if ($end >= $length) {
$end = $length - 1;
}
$length = $end - $start + 1;
$status = 206;
$headers['Content-Range'] = sprintf('bytes %d-%d/%d', $start, $end, $size);
$headers['Content-Length'] = $length;
}
return Response::stream(function() use ($start, $length, $callback) {
call_user_func($callback, $start, $length);
}, $status, $headers);
});
// Usage
$path = storage_path('secured_video.mp4');
$name = basename($path);
$size = File::size($path);
$type = 'video/mp4';
return Response::streamed($type, $size, $name, function($offset, $length) use ($path) {
$stream = GuzzleHttp\Stream\Stream::factory(fopen($path, 'r'));
$stream->seek($offset);
while (!$stream->eof()) {
echo $stream->read($length);
}
$stream->close();
});
@MistrySaurabh
Copy link

I tried your code , got this error :

Non-static method Illuminate\Http\Request::server() should not be called statically

from this line if (false !== $range = Request::server('HTTP_RANGE', false)) {

@rouve
Copy link

rouve commented Mar 10, 2020

use Request; instead

@mirko77
Copy link

mirko77 commented Mar 18, 2020

This works but seeking does not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment