<?php
// disable zlib so that progress bar of player shows up correctly
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); }
$folder = '.';
$filename = 'video.mp4';
$path = $folder.'/'.$filename;
// from: http://l...content-available-to-author-only...n.net/post/stream-videos-php/
// Clears the cache and prevent unwanted output
$mime = "video/mp4"; // The MIME type of the file, this should be replaced with your own.
$size = filesize($path); // The size of the file
// Send the content type header
header('Content-type: ' . $mime);
// Check if it's a HTTP range request
if(isset($_SERVER['HTTP_RANGE'])){ // Parse the range header to get the byte offset
'intval', // Parse the parts into integer
'-', // The range separator
substr($_SERVER['HTTP_RANGE'], 6) // Skip the `bytes=` part of the header )
);
// If the last range param is empty, it means the EOF (End of File)
if(!$ranges[1]){
$ranges[1] = $size - 1;
}
// Send the appropriate headers
header('HTTP/1.1 206 Partial Content'); header('Accept-Ranges: bytes'); header('Content-Length: ' . ($ranges[1] - $ranges[0])); // The size of the range
// Send the ranges we offered
'Content-Range: bytes %d-%d/%d', // The header format
$ranges[0], // The start range
$ranges[1], // The end range
$size // Total size of the file
)
);
// It's time to output the file
$f = fopen($path, 'rb'); // Open the file in binary mode $chunkSize = 8192; // The size of each chunk to output
// Seek to the requested start range
// Start outputting the data
while(true){
// Check if we have outputted all the data requested
if(ftell($f) >= $ranges[1]){ break;
}
// Output the data
echo fread($f, $chunkSize);
// Flush the buffer immediately
}
}
else {
// It's not a range request, output the file anyway
header('Content-Length: ' . $size);
// Read the file
// and flush the buffer
}
}
?>
PD9waHAKLy8gZGlzYWJsZSB6bGliIHNvIHRoYXQgcHJvZ3Jlc3MgYmFyIG9mIHBsYXllciBzaG93cyB1cCBjb3JyZWN0bHkKaWYoaW5pX2dldCgnemxpYi5vdXRwdXRfY29tcHJlc3Npb24nKSkgewoJaW5pX3NldCgnemxpYi5vdXRwdXRfY29tcHJlc3Npb24nLCAnT2ZmJyk7IAp9CgokZm9sZGVyID0gJy4nOyAKJGZpbGVuYW1lID0gJ3ZpZGVvLm1wNCc7CiRwYXRoID0gJGZvbGRlci4nLycuJGZpbGVuYW1lOwoKLy8gZnJvbTogaHR0cDovL2wuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLm4ubmV0L3Bvc3Qvc3RyZWFtLXZpZGVvcy1waHAvCmlmIChmaWxlX2V4aXN0cygkcGF0aCkpIHsKCS8vIENsZWFycyB0aGUgY2FjaGUgYW5kIHByZXZlbnQgdW53YW50ZWQgb3V0cHV0CglvYl9jbGVhbigpOwoKCSRtaW1lID0gInZpZGVvL21wNCI7IC8vIFRoZSBNSU1FIHR5cGUgb2YgdGhlIGZpbGUsIHRoaXMgc2hvdWxkIGJlIHJlcGxhY2VkIHdpdGggeW91ciBvd24uCgkkc2l6ZSA9IGZpbGVzaXplKCRwYXRoKTsgLy8gVGhlIHNpemUgb2YgdGhlIGZpbGUKCgkvLyBTZW5kIHRoZSBjb250ZW50IHR5cGUgaGVhZGVyCgloZWFkZXIoJ0NvbnRlbnQtdHlwZTogJyAuICRtaW1lKTsKCgkvLyBDaGVjayBpZiBpdCdzIGEgSFRUUCByYW5nZSByZXF1ZXN0CglpZihpc3NldCgkX1NFUlZFUlsnSFRUUF9SQU5HRSddKSl7CgkJLy8gUGFyc2UgdGhlIHJhbmdlIGhlYWRlciB0byBnZXQgdGhlIGJ5dGUgb2Zmc2V0CgkJJHJhbmdlcyA9IGFycmF5X21hcCgKCQkJJ2ludHZhbCcsIC8vIFBhcnNlIHRoZSBwYXJ0cyBpbnRvIGludGVnZXIKCQkJZXhwbG9kZSgKCQkJCSctJywgLy8gVGhlIHJhbmdlIHNlcGFyYXRvcgoJCQkJc3Vic3RyKCRfU0VSVkVSWydIVFRQX1JBTkdFJ10sIDYpIC8vIFNraXAgdGhlIGBieXRlcz1gIHBhcnQgb2YgdGhlIGhlYWRlcgoJCQkpCgkJKTsKCgkJLy8gSWYgdGhlIGxhc3QgcmFuZ2UgcGFyYW0gaXMgZW1wdHksIGl0IG1lYW5zIHRoZSBFT0YgKEVuZCBvZiBGaWxlKQoJCWlmKCEkcmFuZ2VzWzFdKXsKCQkJJHJhbmdlc1sxXSA9ICRzaXplIC0gMTsKCQl9CgoJCS8vIFNlbmQgdGhlIGFwcHJvcHJpYXRlIGhlYWRlcnMKCQloZWFkZXIoJ0hUVFAvMS4xIDIwNiBQYXJ0aWFsIENvbnRlbnQnKTsKCQloZWFkZXIoJ0FjY2VwdC1SYW5nZXM6IGJ5dGVzJyk7CgkJaGVhZGVyKCdDb250ZW50LUxlbmd0aDogJyAuICgkcmFuZ2VzWzFdIC0gJHJhbmdlc1swXSkpOyAvLyBUaGUgc2l6ZSBvZiB0aGUgcmFuZ2UKCgkJLy8gU2VuZCB0aGUgcmFuZ2VzIHdlIG9mZmVyZWQKCQloZWFkZXIoCgkJCXNwcmludGYoCgkJCQknQ29udGVudC1SYW5nZTogYnl0ZXMgJWQtJWQvJWQnLCAvLyBUaGUgaGVhZGVyIGZvcm1hdAoJCQkJJHJhbmdlc1swXSwgLy8gVGhlIHN0YXJ0IHJhbmdlCgkJCQkkcmFuZ2VzWzFdLCAvLyBUaGUgZW5kIHJhbmdlCgkJCQkkc2l6ZSAvLyBUb3RhbCBzaXplIG9mIHRoZSBmaWxlCgkJCSkKCQkpOwoKCQkvLyBJdCdzIHRpbWUgdG8gb3V0cHV0IHRoZSBmaWxlCgkJJGYgPSBmb3BlbigkcGF0aCwgJ3JiJyk7IC8vIE9wZW4gdGhlIGZpbGUgaW4gYmluYXJ5IG1vZGUKCQkkY2h1bmtTaXplID0gODE5MjsgLy8gVGhlIHNpemUgb2YgZWFjaCBjaHVuayB0byBvdXRwdXQKCgkJLy8gU2VlayB0byB0aGUgcmVxdWVzdGVkIHN0YXJ0IHJhbmdlCgkJZnNlZWsoJGYsICRyYW5nZXNbMF0pOwoKCQkvLyBTdGFydCBvdXRwdXR0aW5nIHRoZSBkYXRhCgkJd2hpbGUodHJ1ZSl7CgkJCS8vIENoZWNrIGlmIHdlIGhhdmUgb3V0cHV0dGVkIGFsbCB0aGUgZGF0YSByZXF1ZXN0ZWQKCQkJaWYoZnRlbGwoJGYpID49ICRyYW5nZXNbMV0pewoJCQkJYnJlYWs7CgkJCX0KCgkJCS8vIE91dHB1dCB0aGUgZGF0YQoJCQllY2hvIGZyZWFkKCRmLCAkY2h1bmtTaXplKTsKCgkJCS8vIEZsdXNoIHRoZSBidWZmZXIgaW1tZWRpYXRlbHkKCQkJQG9iX2ZsdXNoKCk7CgkJCWZsdXNoKCk7CgkJfQoJfQoJZWxzZSB7CgkJLy8gSXQncyBub3QgYSByYW5nZSByZXF1ZXN0LCBvdXRwdXQgdGhlIGZpbGUgYW55d2F5CgkJaGVhZGVyKCdDb250ZW50LUxlbmd0aDogJyAuICRzaXplKTsKCgkJLy8gUmVhZCB0aGUgZmlsZQoJCUByZWFkZmlsZSgkcGF0aCk7CgoJCS8vIGFuZCBmbHVzaCB0aGUgYnVmZmVyCgkJQG9iX2ZsdXNoKCk7CgkJZmx1c2goKTsKCX0KCn0KZGllKCk7Cgo/Pg==