-
-
Save daymwk/43fb1208c6e258834fd1cffabce0d0f5 to your computer and use it in GitHub Desktop.
PHP VideoStream class for HTML5 video streaming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Description of VideoStream | |
* | |
* @author Rana | |
* Customized by Daym for remote videos | |
* @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; | |
} | |
/** | |
* Remote file size | |
*/ | |
public function getFileSize($file){ | |
if(!empty($file)){ | |
$this->path = $file; | |
foreach(get_headers($file) as $head){ | |
if(strpos($head, 'Content-Length:') === 0){ | |
return str_replace('Content-Length: ', '', $head); | |
} | |
} | |
} | |
return 0; | |
} | |
/** | |
* Fetches the remote partial content | |
*/ | |
public function getRange($url,$start,$end){ | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, $url); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, array( | |
'Range: bytes=' . $start . '-' . $end, | |
)); | |
$content = curl_exec($ch); | |
curl_close($ch); | |
return $content; | |
} | |
/** | |
* 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 = $this->getFileSize($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; | |
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); | |
} | |
} | |
/** | |
* perform the streaming of calculated range | |
*/ | |
private function stream() | |
{ | |
echo $this->getRange($this->path,$this->start,$this->end); | |
} | |
/** | |
* Start streaming video content | |
*/ | |
function start() | |
{ | |
$this->setHeader(); | |
$this->stream(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment