当从PHP提供mp3时,audio.duration在Safari上返回Infinity

时间:2012-03-09 05:11:41

标签: php safari mp3 html5-audio

所以,我有一个PHP脚本将我的mp3文件发送到html5的音频标签。问题是在Safari中,audio.duration标签不起作用并返回无穷大。如果我将音频的src直接设置到文件,一切正常。但我不希望我的用户看到该文件的路径。

无论如何,这就是我从PHP发送标题的方式。

我已经尝试过了内容范围。这没有用。

if (file_exists($filename)) {
  $fp = fopen($filename, 'r');
  $etag = md5(serialize(fstat($fp)));
  fclose($fp);
  header("Content-Transfer-Encoding: binary"); 
  header("Content-Type: audio/mpeg");
  header('Content-Length: ' . (string)(filesize($filename)));
  header('Content-Disposition: inline; filename="' . $filename . '"');
  header('X-Pad: avoid browser bug');
  header('Cache-Control: no-cache');
  header('Etag: ' . $etag);

  //GetContentRange($filelength);

  readfile($filename);
  exit;
}
else {
  header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found', true, 404);
  echo "no file";
}

3 个答案:

答案 0 :(得分:4)

我遇到了同样的问题并添加了几个标题。似乎为我工作 -

 header("Pragma: public");
 header("Expires: 0"); 
 header("Content-Type: audio/mpeg");
 header('Content-Length: ' . $fsize);
 header('Content-Disposition: inline; filename="' . $track2play . '"');
 header( 'Content-Range: bytes 0-'.$shortlen.'/'.$fsize); 
 header( 'Accept-Ranges: bytes');
 header('X-Pad: avoid browser bug');
 header('Cache-Control: no-cache');
 header('Etag: ' . $etag);

$ fsize是文件大小,$ shortlen = $ filesize-1 ...在Safari 5.1.4和新iPad上测试......

答案 1 :(得分:3)

  

您的服务器必须启用范围请求。这很容易检查   查看服务器的响应是否包含其中的Accept-Ranges   头。大多数HTML5浏览器都可以寻找新的文件位置   在下载过程中,服务器必须允许新的Range   请求。

     

无法接受字节范围请求会导致某些问题   HTML5浏览器。通常不能从文件中读取持续时间   某些格式要求读取文件的开头和结尾   知道它的持续时间Chrome往往是最具浏览功能的浏览器   如果未在服务器上启用Range请求,则会出现问题   浏览器会有一些问题,即使只是你必须等待   在接近结尾之前加载所有媒体。

有关如何在启用范围请求的情况下提供媒体服务的PHP示例,请参阅this post

另外,我注意到您正在使用No-Cache ..

  

使用服务器响应禁用媒体的本地缓存即可   导致某些HTML5浏览器出现问题。这可能会导致持续时间   媒体是未知的。

答案 2 :(得分:1)

  • 今天我浪费了大部分时间来研究这个问题 出来了一个解决方案。为什么safari返回的原因 无限期的持续时间非常有趣:看来Safari 请求服务器两次播放文件。首先它发送一个范围 请求服务器使用这样的范围标头:(字节:0-1)。
  • 如果服务器未将响应作为部分内容返回,如果是 返回整个流,然后将不设置Safari浏览器 audio.duration标签,导致只播放一次文件 它不能再玩了。
  • 我快速修复了它,在服务器端只需检查一下 标题,如果它包含rangeHeader,则返回它。

    String rangeHeader = request.getHeader("Range"); if(rangeHeader != null) { //just return it }

相关问题