I'm using a class for video stream:
<?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();
}
}
I can call this class by doing:
include_once 'videostream.php';
$stream = new VideoStream("video.mp4");
$stream->start();
This code works with local videos, but the problem is: When I try to open a external video like this:
$stream = new VideoStream("https://www.w3schools.com/html/mov_bbb.ogg");
The v?�deo don't open and I don't receive any error messages? Is a fopen() problem? Is a server problem? I'm using xampp v3.3.0.
When I see Network tab in Google Chrome, I receive two headers and one of them is pending.
UPDATE 1 (Partial Solution)
After performing some tests I made some modifications to the code and I was able to open the video using an external URL, follow the corrections below:
1.The video that I wanna play has HTTPS(https://www.w3schools.com/html/mov_bbb.ogg)
and not HTTP format, so you must change all
headers that was HTTP/1.1 to HTTPS/1.1:
header('HTTPS/1.1 416 Requested Range Not Satisfiable');
header('HTTPS/1.1 206 Partial Content');
2.The commandfilesize
does not work when it comes to an external URL, so we need to create a function capable of getting the size of the file we want:
function getContentLengthFromURL($url){
$arrayHeaders = get_headers($url,true);
if(isset($arrayHeaders['Content-Length'])){
if(is_numeric($arrayHeaders['Content-Length']) && $arrayHeaders['Content-Length'] > 0){
return $arrayHeaders['Content-Length'];
}
}
return null;
}
After that we need to updatesetHeader()
function:
//$this->size = filesize($this->path);
$this->size = $this->getContentLengthFromURL($this->path);
3.We need to comment out all the lines that specify the Content-Range: and Fseek()
//header("Content-Range: bytes $this->start-$this->end/$this->size");
//fseek($this->stream, $this->start);
Amazing, now the HTML5 player is able to play the video, the only problem is that you are still unable to change the time of the video.
In this case I can't jump forward or back my video.
UPDATE 2 (THE SOLUTION)
After several attempts I finally got a solution to the code problem.
The problem was in the content-ranges and in the positioning of the headers.
By the way, I created a videoStream package using the new code, if you want an automated videoStream, just access this link.
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
HTML (English "hyper text markup language" - hypertext markup language) is a special markup language that is used to create sites on the Internet.
Browsers understand html perfectly and can interpret it in an understandable way. In general, any page on the site is html-code, which the browser translates into a user-friendly form. By the way, the code of any page is available to everyone.
https://www.w3.org/html/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.