PHP readfile无法正常使用Safari

时间:2016-12-28 16:34:57

标签: php audio safari http-headers readfile

我正在将mp3加载到html <audio>标记中。该标记的来源实际上是一个PHP脚本,它返回一个不在公共目录中托管的歌曲。

省略大部分验证和其他代码,用于输出mp3的标题是:

    header( 'Content-type: {$mime_type}' );
    header( 'Content-length: ' . filesize( $file ));
    header( 'Content-Disposition: inline;filename="'.$filename.'"' );
    header( 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0' );
    header( 'Pragma: no-cache' );
    header( 'Content-Transfer-Encoding: binary'); 
    header( 'Expires: 0');


    readfile( $file );  

适用于Firefox,Chrome(和移动设备),Edge(和移动设备)和Opera。但是我似乎无法让Safari使用生成的url作为音频源。事实上,在呈现页面后,DOM中不会出现音频源:

enter image description here

网址可能如www.website.com/song.php?sid=234234234234

我尝试过多次调整此文件,但无法弄清楚为什么会在Safari上发生这种情况。我的直觉是浏览器处理mp3等的方式,应该在标题中处理。

任何指导,提示或帮助将不胜感激。

感谢。

更新: 添加了网络,显示它加载了mp3,但第二个请求没有? Description

响应标题:

Name    Value
Server  Apache
Content-Type    audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3
Date    Wed, 28 Dec 2016 17:24:48 GMT
Cache-Control   no-cache
X-Powered-By    PHP/5.3.29
Content-Disposition inline;filename="148_2793d1c49976a3689147634359577ec1aa5619f1.mp3"
Content-Length  834312
Expires 0
Connection  Keep-Alive
Content-Transfer-Encoding   binary
Accept-Ranges   bytes
Keep-Alive  timeout=5, max=100
Pragma  no-cache

2 个答案:

答案 0 :(得分:1)

您需要传递多个范围标题,因为它是部分内容:http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2

header("Accept-Ranges: 0-filesize( $file )");

修改

看看这里: http://www.techstruggles.com/mp3-streaming-for-apple-iphone-with-php-readfile-file_get_contents-fail/

您需要为safari定义一些标头,即使是移动版本。

答案 1 :(得分:1)

我之前有过这个问题,很抱歉,如果我不记得我是如何解决这个问题的,那就是标题问题(它是我记忆中的主要部分,我不会使用评论添加答案因为它太长了)

试试这个..

  header( 'Accept-Ranges: bytes'); 
  header("Pragma: public");
  header("Expires: 0");
  header('Cache-Control: no-cache, no-store');
  header('Content-Transfer-Encoding: binary');
  header('Content-Disposition: inline; filename="'.$filename.'"');      
  header('Content-Length: '.$fsize);
  header('Content-Type: audio/'.$t);
  header('Accept-Ranges: bytes');
  header('Connection: Keep-Alive');
  header('Content-Range: bytes 0-'.$shortlen.'/'.$fsize); 
  header('X-Pad: avoid browser bug');
  header('Etag: '.$etag);

其中:

  $filename = "myaudio.mp3";
  $path = 'music/'.$filename;
  $fsize = filesize($path);
  $shortlen = $fsize - 1;

  $fp = fopen($path, 'r');
  $etag = md5(serialize(fstat($fp)));
  fclose($fp);
  $t = "mpeg";

希望这会有所帮助,但您需要的两个主要标题是&#34; Etag&#34;和&#34;接受范围&#34;如果我没错。