我正在尝试使用HTML5音频标记通过浏览器提供音频文件:
<audio preload="auto">
<source src="<?php echo $song->getUrl('mp3'); ?>" type="audio/mpeg">
<source src="<?php echo $song->getUrl('ogg'); ?>" type="audio/ogg">
Please update your browser.
</audio>
我需要节省流量,所以我考虑以这种方式发送部分内容:
$contentType = ($format == 'mp3') ? 'audio/mpeg' : 'audio/ogg';
$filePath = $song->getPath($format);
$fileLength = filesize($filePath);
$start = 0;
if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])) {
$http_range = explode('-', substr($_SERVER['HTTP_RANGE'], strlen('bytes=')));
$start = $http_range[0];
}
$remainingBytes = $fileLength - $start;
$length = min((512*1024), $remainingBytes);
$final = $start + $length;
header('HTTP/1.1 206 Partial Content');
header('Status: 206 Partial Content');
header('Content-Type: ' . $contentType);
header('Content-Disposition: inline;filename="listen.' . $format . '"');
header('Content-length: ' . $length);
header('Content-Transfer-Encoding: bytes');
header('Accept-Ranges: bytes');
header('Cache-Control: no-cache');
header('Content-Range: bytes ' . $start . '-' . $final . '/' . $fileLength);
echo file_get_contents($filePath, false, null, $start, $length);
这样做的结果是,在Chrome中,几乎完全播放的歌曲(9.1MB文件的3.47秒中的3.41)。在Firefox中,前39秒播放(我想512KB)。在歌剧中,一种永无止境的“加载”状态。
答案 0 :(得分:1)
Per RFC2616,206 Partial Content
响应仅在响应HTTP范围请求时有效:
10.2.7 206部分内容
服务器已完成资源的部分GET请求。请求必须包含一个Range头字段(第14.35节),表示所需的范围,并且可能包含一个If-Range头字段(第14.27节),以使请求成为条件。
您的脚本正在为请求生成206响应,这可能非常不是针对部分内容(或者可能是针对不同于您返回的范围),这会使Web浏览器感到困惑。在大多数浏览器中,很可能没有逻辑来提供额外的请求来获取其他内容,因为这种情况永远不会出现。
您的脚本也无法正确处理范围请求!范围包括长度,并且请求中可以存在多个范围。再次,see RFC2616 for details。
答案 1 :(得分:0)
我认为你错误地计算了文件的大小
$contentType = ($format == 'mp3') ? 'audio/mpeg' : 'audio/ogg';
$filePath = $song->getPath($format);
$fileLength = filesize($filePath);
<强> EDITED 强>
$format
是文件扩展名而不是文件路径
和
filesize($filePath); // Do not returns file size