PHP Website not responding while streaming a video - php

My website is developed using pure PHP with MySQL
while streaming a video "Please try this link"
Here
If you click on any button called "مشاهدة", the website will not respond to any other request like navigating to any other page.
Here is the code of my Stream.php file
<?php
session_start();
require("includes/connect.php");
set_time_limit(0);
if(isset($_GET["file"])){
if(!isset($_GET["start"])) $_GET["start"] = 0;
$seekPos = $_GET["start"];
$file = htmlspecialchars($_GET["file"]);
$fileName = basename($file);
$file = $config["videoFilesPath"]."/".$fileName;
if(!file_exists($file)) die("file does not exist: $file");
$fh = fopen($file, "rb") or die("failed to open file");
fseek($fh, 0, SEEK_END); $seek_end = ftell($fh);
fseek($fh, $seekPos); $seek_start = ftell($fh);
$fileSize = $seek_end - $seek_start;
session_cache_limiter('nocache');
header("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
header("Content-Type: video/x-flv");
//header("Content-Disposition: attachment; filename=\"" . $fileName . "\"");
header('Content-Length: ' . $fileSize);
if($seekPos != 0){
print("FLV");
print(pack('C', 1 ));
print(pack('C', 1 ));
print(pack('N', 9 ));
print(pack('N', 9 ));
}
fseek($fh, $seekPos);
$i=1;
while (true){
$var = fread($fh, 1024);
if($var==false) break;
echo $var;
if(++$i%(1<<20)) ob_flush();
}
fclose($fh);
}

session_start() opens and locks the session file, therefore you must call session_write_close() before any long running process:
session_start();
require("includes/connect.php");
session_write_close();

Related

ERR_CONTENT_LENGTH_MISMATCH when loading video in chrome

So I get this error when some of the video plays. When Chrome completely downloads the video, it stops playing with this error. Also the status of the request changes from 206 to (failed) and then Chrome sends some other requests with Range:bytes=2990775- and the server response is:
Accept-Ranges:bytes
Cache-Control:private
Connection:keep-alive
Content-Disposition:attachment; filename="About The Author.mp4"
Content-Length:0
Content-Range:bytes 2990775-2990775/2990776
Content-Transfer-Encoding:binary
Content-Type:video/mp4
Date:Tue, 14 Feb 2017 13:46:24 GMT
Last-Modified:Wed, 08 Feb 2017 05:43:27 GMT
Pragma:public
Server:Apache/2
Vary:User-Agent
X-Powered-By:PHP/5.4.45
I have another website on the same server and it works fine there.
Here is my PHP code:
$filesize = filesize($resource->path);
$matches = explode("-", substr($_SERVER['HTTP_RANGE'],6));
if (empty($matches[1]))
{
$matches[1] = $filesize - 1;
}
$offset = intval($matches[0]);
$length = intval($matches[1]) - $offset;
$file = fopen($resource->path, 'r');
fseek($file, $offset);
$data = fread($file, $length);
fclose($file);
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $filesize);
header('Pragma: public');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($resource->path)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: ' . $mime);
header('Content-Length: ' . ($length + 1));
header('Content-Disposition: attachment; filename="' . $resource->filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
print($data);
Sorry for my bad english.
I've found the problem.
I changed $data = fread($file, $length); to $data = fread($file, $length + 1);.
I don't know why the requested length should be plus one but it solve'd the problem.

How to download big files in PHP

I use this code to download/read files from a server.
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-type: application/file");
header('Content-length: '.filesize($file_to_download));
header('Content-disposition: attachment; filename='.basename($file_to_download));
readfile($file_to_download);
exit;
it's working fine to download files but when the file is big it's showing an error "File not found, problem file loading". Please tell me what I could change on this code for big file downloads.
Try like this:
$chunkSize = 1024 * 1024;
$fd = fopen($file_to_download, 'rb');
while (!feof($fd)) {
$buffer = fread($fd, $chunkSize);
echo $buffer;
ob_flush();
flush();
}
fclose($fd);

X-Sendfile notification after finish download

I would need to set the download status to 0 when download has finished. I am using x-sendfile, but after finish download, dont set status.
My code:
header("X-Sendfile: $file");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $name . '"');
mysql_query("UPDATE `downloads` SET `download_status` = '1' WHERE `id` = '" . $last_down . "'");
Thanks for help
You can't detect when the client finished downloading the file if you using X-Sendfile.
Simplest way is stream file by script.
$handle = fopen($filepath, 'rb');
if ($handle !== false) {
#flock($handle, LOCK_SH);
$size = filesize($filepath);
$filename = basename($filepath);
$old_max_execution_time = ini_get('max_execution_time');
ini_set('max_execution_time', 0);
$old_cache_limiter = session_cache_limiter();
session_cache_limiter(false);
if (ob_get_length()) ob_clean();
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-disposition: attachment; filename="'. $filename .'"');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
set_time_limit(0);
while (! feof($handle) && (connection_status() === 0)) {
if (! $buffer = #fread($handle, $interval)) {
// Error
exit;
}
print($buffer);
flush();
}
#flock($handle, LOCK_UN);
#fclose($handle);
ini_set('max_execution_time', $old_max_execution_time);
session_cache_limiter($old_cache_limiter);
// ----------------------------------------------------
// Downloading complete!
// Here you can update your table row in DB...
// ----------------------------------------------------
exit;
}

pseudo streaming

I currently test script an pseudo-streaming for read mp4 files, when I reading everything works fine, but I can not move the timeline? probleme ?
my coding (mp4 metadata) is correct because when reading without this code in the player, I can move in the timeline. I use fplayer for read the mp4.
// ----- NO CACHE -----
session_cache_limiter('nocache');
// General header for no caching
$now = gmdate('D, d M Y H:i:s') . ' GMT';
header('Expires: ' . $now); // rfc2616 - Section 14.21
header('Last-Modified: ' . $now);
header('Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0'); // HTTP/1.1
header('Pragma: no-cache'); // HTTP/1.0
// ----- Seek position -----
$seekat = 0;
if (isset($_GET["pos"])) {
$position = $_GET["pos"];
if (is_numeric ($position)) {
$seekat = $position;
}
if ($seekat < 0) $seekat = 0;
}
$filename = 'test.mp4';
$ext = strrchr($filename, ".");
$prefix = "";
$file = $prefix . $filename;
if (($filename != "") && (file_exists($file)) && ($ext==".mp4")) {
header("Content-Type: video/x-mp4");
if ($seekat > 0) header('Content-Length: ' . (filesize($file)-$seekat));
else header('Content-Length: ' . filesize($file));
if ($seekat != 0) {
print("FLV");
print(pack('C', 1 ));
print(pack('C', 1 ));
print(pack('N', 9 ));
print(pack('N', 9 ));
}
$fh = fopen($file, "rb");
fseek($fh, $seekat);
while (!feof($fh)) {
print (fread($fh, 16384));
// print (fread($fh, filesize($file)));
}
fclose($fh);
}
Can you help me thank you.
header("Content-Type: video/x-mp4");
i currently use the same code but even when i stream an mp4 i let the header content as for a flv
Content-Type: video/x-flv
hope it's will help

php ie9 automatic downloads

Hi guys I'm trying to get an automatic download box to appear when people go a page.
I've got this working on all the browsers and now ie9 has come along and although it downloads at the end it says "This download was interrupted"
this is what I'm using code wise
// set headers
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT\n");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"$download[file]\";\n\n");
header( 'Content-Description: File Transfer' );
header("Content-Type: ".$mtype);
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".(string)$size.";\n");
//get a chunk of the file
$chunksize = 1*(1024*1024); // how many bytes per chunk
$buffer = '';
//downloads file
$handle = fopen($download_file, 'rb');
if ($handle === false) {
}
//write to the browser for download
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
exit;
Any ideas?
Instead of the somewhat complicated file output you're doing, I'd just use readfile instead:
// set headers
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT\n");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"$download[file]\";\n\n");
header( 'Content-Description: File Transfer' );
header("Content-Type: ".$mtype);
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".(string)$size.";\n");
readfile($download_file);
exit;
See if that works.

Categories