【发布时间】:2018-05-05 21:16:46
【问题描述】:
我想创建一个.php 文件,用于播放视频!
现在,问题是,它只有在我使用普通的 readfile() 时才有效,但是,你不能在视频中来回前进,所以我在谷歌上搜索,找到这段代码:
(基本上,HTTP_RANGE 不起作用,从来没有,我不知道为什么,在测试它时,它总是触发我的die("lol?");,所以它显然不支持它出于某种原因)
(die() 函数是故意留在那里的,如果它可以工作,它将被取出..)
(请注意,我将“$size = filesize($file);”更改为“$size = filesize(".".$file);”,因为有人提到这是必需的,而“filesize($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 视频流示例,但没有一个对我有用:/
【问题讨论】:
-
所以它可能进入
die部分的唯一原因是因为$_SERVER['HTTP_RANGE']没有设置。但这来自用户代理的请求,因此不能保证。 stackoverflow.com/questions/35337958/… -
@Andy soo?我对 php、apache 等非常缺乏经验,有什么办法可以解决这个问题?我在 google chrome 和 Internet Explorer 中测试过!
-
如果您对 Apache/PHP 没有经验,那么恐怕您几乎没有机会使用它。这里有一个很好的概述:stackoverflow.com/questions/157318/…。您需要了解它不仅基于服务器给出的 response,还非常基于客户端发送的 request 标头。您没有在代码中的任何地方显示您是如何提出请求的,我怀疑这可能是问题所在。
-
@Andy 好吧,我可以向你保证,我知道如何设置内容标题,但它无法正常工作,我尝试设置接受范围、内容类型、内容长度等等,但由于所有这些方法对我也不起作用,我认为这不会有什么不同,因此为什么在我的这篇文章中显示的代码中不包含它们
-
试试这个:stackoverflow.com/questions/10189811/…。如果该脚本的输出为“否”,那么您没有正确设置请求标头。请问你从中得到了什么输出?
标签: php apache http http-headers streaming