Skip to content

Instantly share code, notes, and snippets.

@visionarylab
Forked from BackFront/HTML5_player.html
Created September 25, 2020 15:37
Show Gist options
  • Save visionarylab/5ad82b720aadb6d034c7a2ce85a5c568 to your computer and use it in GitHub Desktop.
Save visionarylab/5ad82b720aadb6d034c7a2ce85a5c568 to your computer and use it in GitHub Desktop.
Pseudo Streaming MP4’s with PHP

So I’ve been working on a video hosting project for most of the year and ran into issues while trying to push all storage files thru a PHP script. For proper tracking of embedded videos this was/is a must. If you’re having this problem and can’t find a solution, maybe this will help…

The below code will pseudo stream any MP4 file on any browser (including iPads/tablets) with all functionality working properly (seek forward, seek backwards and displays correct time). This code has also been tested with Longtail JWPlayer 6 and HTML5 players.

If you’re interested in an advanced version of this script, I currently have an unreleased version which includes automatic rate limiting (buffer rate). I’m also playing with other ideas to further enhance it. If you have any suggestions or questions either contact us or leave a comment at the bottom.

I have added the script to GITHub so everyone can contribute to ehance this code. Please feel free to contact me if you have any questions. https://github.com/tuxxin/MP4Streaming

<video controls="" width="400">
<source src="http://66.128.61.175/reel/1cc976948e74aa62f7a7fde16e64fb6b/360p" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<?php
$file = 'video360p.mp4';
$fp = @fopen($file, 'rb');
$size = filesize($file); // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte
header('Content-type: video/mp4');
//header("Accept-Ranges: 0-$length");
header("Accept-Ranges: bytes");
if (isset($_SERVER['HTTP_RANGE'])) {
$c_start = $start;
$c_end = $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 $start-$end/$size");
exit;
}
if ($range == '-') {
$c_start = $size - substr($range, 1);
}else{
$range = explode('-', $range);
$c_start = $range[0];
$c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
}
$c_end = ($c_end > $end) ? $end : $c_end;
if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
header('HTTP/1.1 416 Requested Range Not Satisfiable');
header("Content-Range: bytes $start-$end/$size");
exit;
}
$start = $c_start;
$end = $c_end;
$length = $end - $start + 1;
fseek($fp, $start);
header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);
$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {
if ($p + $buffer > $end) {
$buffer = $end - $p + 1;
}
set_time_limit(0);
echo fread($fp, $buffer);
flush();
}
fclose($fp);
exit();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment