提供一个mp3 / ogg文件碎片到html5音频

时间:2013-05-13 14:36:48

标签: php html5 http audio-streaming

我正在尝试使用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)。在歌剧中,一种永无止境的“加载”状态。

2 个答案:

答案 0 :(得分:1)

Per RFC2616206 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