-
-
Save ranacseruet/9826293 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* Description of VideoStream | |
* | |
* @author Rana | |
* @link http://codesamplez.com/programming/php-html5-video-streaming-tutorial | |
*/ | |
class VideoStream | |
{ | |
private $path = ""; | |
private $stream = ""; | |
private $buffer = 102400; | |
private $start = -1; | |
private $end = -1; | |
private $size = 0; | |
function __construct($filePath) | |
{ | |
$this->path = $filePath; | |
} | |
/** | |
* Open stream | |
*/ | |
private function open() | |
{ | |
if (!($this->stream = fopen($this->path, 'rb'))) { | |
die('Could not open stream for reading'); | |
} | |
} | |
/** | |
* Set proper header to serve the video content | |
*/ | |
private function setHeader() | |
{ | |
ob_get_clean(); | |
header("Content-Type: video/mp4"); | |
header("Cache-Control: max-age=2592000, public"); | |
header("Expires: ".gmdate('D, d M Y H:i:s', time()+2592000) . ' GMT'); | |
header("Last-Modified: ".gmdate('D, d M Y H:i:s', @filemtime($this->path)) . ' GMT' ); | |
$this->start = 0; | |
$this->size = filesize($this->path); | |
$this->end = $this->size - 1; | |
header("Accept-Ranges: 0-".$this->end); | |
if (isset($_SERVER['HTTP_RANGE'])) { | |
$c_start = $this->start; | |
$c_end = $this->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 $this->start-$this->end/$this->size"); | |
exit; | |
} | |
if ($range == '-') { | |
$c_start = $this->size - substr($range, 1); | |
}else{ | |
$range = explode('-', $range); | |
$c_start = $range[0]; | |
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $c_end; | |
} | |
$c_end = ($c_end > $this->end) ? $this->end : $c_end; | |
if ($c_start > $c_end || $c_start > $this->size - 1 || $c_end >= $this->size) { | |
header('HTTP/1.1 416 Requested Range Not Satisfiable'); | |
header("Content-Range: bytes $this->start-$this->end/$this->size"); | |
exit; | |
} | |
$this->start = $c_start; | |
$this->end = $c_end; | |
$length = $this->end - $this->start + 1; | |
fseek($this->stream, $this->start); | |
header('HTTP/1.1 206 Partial Content'); | |
header("Content-Length: ".$length); | |
header("Content-Range: bytes $this->start-$this->end/".$this->size); | |
} | |
else | |
{ | |
header("Content-Length: ".$this->size); | |
} | |
} | |
/** | |
* close curretly opened stream | |
*/ | |
private function end() | |
{ | |
fclose($this->stream); | |
exit; | |
} | |
/** | |
* perform the streaming of calculated range | |
*/ | |
private function stream() | |
{ | |
$i = $this->start; | |
set_time_limit(0); | |
while(!feof($this->stream) && $i <= $this->end) { | |
$bytesToRead = $this->buffer; | |
if(($i+$bytesToRead) > $this->end) { | |
$bytesToRead = $this->end - $i + 1; | |
} | |
$data = fread($this->stream, $bytesToRead); | |
echo $data; | |
flush(); | |
$i += $bytesToRead; | |
} | |
} | |
/** | |
* Start streaming video content | |
*/ | |
function start() | |
{ | |
$this->open(); | |
$this->setHeader(); | |
$this->stream(); | |
$this->end(); | |
} | |
} |
Is it possible for the controls not to be displayed on that page? Or at least not be able to download the video? or do you need a script for that?
This code need UPDATE, he cannot read EXTERNAL URL VIDEO, only local videos, for solve this problem I create a new package that works with laravel, check it out: https://github.com/micilini/video-stream.
My Package can handle local and external video files 👯
I got an error please help
filesize(): stat failed for http://laraveltest.test/ElephantsDream.mp4
got error here. from class VideoStream
$this->size = filesize($this->path);
where code
$a = 'http://laraveltest.test/ElephantsDream.mp4'; // public folder video
$stream = new VideoStream($a);
return response()->stream(function() use ($stream) {
$stream->start();
});
Any help please using laravel 9
trying to access a file using http://
does not look valid to me, probably you want something like one of these:
$a = storage_path('ElephantsDream.mp4');
$a = public_path('ElephantsDream.mp4');
$a = asset('ElephantsDream.mp4');
depending on where the file is physically in your laravel directory.
@carcinocron thanks so external url not supported right ?
Is there a way to do this same process but with AJAX?
Here is my code. For sure require to check URL and File. Just assume file path / URL is correct.
// Check starting string
if (substr($this->path, 0, 3) == 'htt' || substr($this->path, 0, 3) == 'ftp') { /* External URL - allow_url_fopen=On /
$headers = get_headers($this->path, 1);
$this->size = $headers["Content-Length"];
}else{ / Internal file */
$this->size = filesize($this->path);
}
:
//fseek($this->stream, $this->start);
header('HTTP/1.1 206 Partial Content');
header("Content-Length: ".$length);
header("Content-Range: bytes $this->start-$this->end/".$this->size);
// Use stream_get_contents instead of fseek
echo stream_get_contents($this->stream, -1, $this->start);
Hello i need a help
what i get is only the video.mp4 that I moved to the root server
The script worked for me, but forward and backward movement of the video is not supported.
This script is better supports Video of forward and backward movement :
https://gist.github.com/kicktv/4239c499101494538d384ce7995bb1af
himadrisaha89, this usually means that the software that is sending the streaming file is either calculating or formatting the size information that it sends to the client player incorrectly. If you look at the network information in a browser developer tool, you might be able to see the problem.