我想创建一个.php
文件,用于流式传输视频!
现在,问题是,只有当我使用普通的readfile()时才有效,但是,你不能在视频中前后移动,所以我在google上搜索,找到这段代码:
(基本上,HTTP_RANGE
不起作用,从来没有,我不知道为什么,在测试它时,它总是触发我的die("lol?")
;所以它显然不支持它出于某种原因)
(die()函数是故意保留的,如果它可以工作,它将被取出。)
(请注意,我已将" $size = filesize($file);
"更改为" $size = filesize(".".$file);
",因为有人提到这是必需的,并且"文件大小($ file);"无论如何都不适用于我,它总会触发错误)!
(并且,$ file,显示我的文件的实际路径,没有替换,它在我原来的php中看起来如何!)
<?php
// Clears the cache and prevent unwanted output
ob_clean();
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 'Off');
$file = "/cdn4-e663/zw4su8jiy8skgvizihsjehj/2038tkusi9u848sui7zh/2q3z6hjk97ujduz/a1-cdn/9zw35jbmhkk47wi63uu7.mp4"; // The media file's location
$mime = "application/octet-stream"; // The MIME type of the file, this should be replaced with your own.
$size = filesize(".".$file); // 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
$ranges = array_map(
'intval', // Parse the parts into integer
explode(
'-', // 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
header(
sprintf(
'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($file, 'rb'); // Open the file in binary mode
$chunkSize = 8192; // The size of each chunk to output
// Seek to the requested start range
fseek($f, $ranges[0]);
die("working?");
// 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
ob_flush();
flush();
}
}
else {
die("lol?");
header('Content-Length: ' . $size);
// Read the file
readfile($file);
// and flush the buffer
ob_flush();
flush();
}
?>
所以,die("lol?")
;我加入了,看看是否
if(isset($_SERVER['HTTP_RANGE'])){
/*function fires or not, and no, as it seems it returns FALSE every time..8/
}
所以我想问你们所有人,我该如何解决这个问题?我真的想用php来播放我的视频,因为安全原因,而且因为我喜欢它,我已经将这种方法用于图像,但它的代码不同(并且正在工作)!
我正在使用Apache 2.4 (Windows 10 - 64bit PC)
和最新版本的PHP7,但似乎apache不支持HTTP_RANGE
?我错过了什么,我需要在php.ini或httpd.conf中启用吗
提前谢谢你,我希望有人可以告诉我该怎么做,因为我真的被困在这里,我尝试了所有mp4视频流的例子,我可以在google上找到,但没有一个对我有用:/
答案 0 :(得分:1)
这有两个部分:
当您尝试流式传输视频时(或任何内容),请在浏览器中打开“网络”标签。
查看请求标题(在Chrome中,它位于“网络”标签下)。我在下面发布了截图。请注意,在请求中有一个Range:
参数。 如果请求中没有这个,那么你就会遇到问题。这就是告诉服务器上的PHP脚本你首先要做的范围请求。如果服务器在请求中没有看到此标头,那么它将绕过if
语句并进入die
。
请注意,默认情况下,Range:
请求标头通常不包含在请求中,因此除非您指定此标题,否则它将永远不会起作用。如果您在“网络”标签上的“请求标题”中看不到它,则表示该标题不存在,您需要修复此问题。
您可能还想检查与请求标头完全不同的响应标头 - 。同样,这些可以在浏览器的“网络”选项卡中看到。请参阅下文,了解必须设置的相应标头:
回到最初的问题,它与回应没有任何关系(这就是你所描述的)。您遇到的最初问题与您如何制作请求以及它不包含Range:
标头的事实有关,必须这样做。