【发布时间】:2019-03-27 02:50:06
【问题描述】:
好吧,我放弃了...发生了一些非常奇怪的事情,在搞砸了几天之后,我不得不寻求帮助。我有一个 PHP 脚本,它从文档根目录之外提供一个 MP4 文件。这个脚本效果很好,除了一个非常重要的(至少对我来说)细节:它不会让我选择投射内容。在同一台服务器上,当我访问文档根目录内的 MP4 文件时,我加载页面,当我单击 Chrome 视频播放器右下角的三个点时,我可以选择下载或投射到我的铬铸。使用我的脚本,我只能选择下载,而且我真的需要投射!我已经对此进行了如此多的调整,以至于任何一种方法的标题输出几乎都是相同的。这是我的代码...
<?php
$file=$_GET['file'];
//validate
if($file=="." || $file==".."){$file="";}
$mediaRoot="../../../hostMedia";
$file=$mediaRoot . DIRECTORY_SEPARATOR . $file;
$file=str_replace('\\',"/",$file);
$filesize = filesize($file);
$offset = 0;
$length = $filesize;
// find the requested range
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = (($matches[2]) ? intval($matches[2]) : $filesize) - $offset;
// output the right headers for partial content
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length-1) . '/' . $filesize);
header('Content-Type: video/mp4');
header('Content-Length: ' . $filesize);
header('Accept-Ranges: bytes');
header('Cache-Control: max-age=0');
// open file for reading
$file = fopen($file, 'r');
// seek to the requested offset, this is 0 if it's not a partial content request
fseek($file, $offset);
// populate $data with all except the last byte of the file
$numBytes=($filesize-1);
$dataLen=0;
while($dataLen<$numBytes){
$lenGrab=($numBytes-$dataLen);
if($lenGrab>(1024*2700)){$lenGrab=(1024*2700);}
$data=fread($file, $lenGrab);
print($data);
$dataLen+=strlen($data);
}
// close file
fclose($file);
?>
感谢解决这个问题的人!
更新
好的,听从@Brian Heward 的建议,我花了无数时间确保标题完全一致!!!我非常确定它会起作用,但可惜,它仍然无法让我选择投射。这是我更新的 PHP...
<?php
session_start();
$accessCode=$_SESSION['accessCode'];
$file=$_GET['file'];
//handle injection
if($file=="." || $file==".."){$file="";}
if($accessCode=="blahblahblah8"){
$mediaRoot="../../../hostMedia";
$file=$mediaRoot . DIRECTORY_SEPARATOR . $file;
$file=str_replace('\\',"/",$file);
$filesize = filesize($file);
$offset = 0;
$length = $filesize;
$lastMod=filemtime($file);
if ( isset($_SERVER['HTTP_RANGE']) ) {
// if the HTTP_RANGE header is set we're dealing with partial content
$partialContent = true;
// find the requested range
preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches);
$offset = intval($matches[1]);
$length = (($matches[2]) ? intval($matches[2]) : $filesize) - $offset;
} else {
$partialContent = false;
}
if ( $partialContent ) {
// output the right headers for partial content
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes ' . $offset . '-' . ($offset + $length-1) . '/' . $filesize);
}else{
header('HTTP/1.1 200 OK');
}
// output the regular HTTP headers
header('Content-Type: video/mp4');
header('Content-Length: ' . $length);
header('Accept-Ranges: bytes');
header('ETag: "3410d79f-576de84c004aa"');
header('Last-Modified: '.gmdate('D, d M Y H:i:s \G\M\T', $lastMod));
// don't forget to send the data too
$file = fopen($file, 'r');
// seek to the requested offset, this is 0 if it's not a partial content request
fseek($file, $offset);
//populate $data with all except the last byte of the file
$numBytes=($length);
$dataLen=0;
while($dataLen<$numBytes){
$lenGrab=($numBytes-$dataLen);
if($lenGrab>(1024*2700)){$lenGrab=(1024*2700);}
$data=fread($file, $lenGrab);
print($data);
$dataLen+=strlen($data);
}
fclose($file);
}else{
echo "You are not authorized to view this media.";
}
?>
如果有人能让这件事发挥作用,那么你就是个超级英雄!
最终更新(暂时...)
好吧,在经历了很多很多小时的挫折之后,我不得不放弃这种方法并尝试不同的方法。幸运的是,通常有不止一种方法可以完成某事,而我找到了另一种方法。我将 .mp4 文件托管在使用 HTTP Basic Auth 保护的文件夹中的 doc 根目录中。与我试图实现的目标非常相似,它对我有用。感谢您的建议和指导!
【问题讨论】:
标签: php video-streaming chromecast