Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

MistrySaurabh commented Apr 6, 2019

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