2012-03-09 55 views
5

所以,我有一個php腳本,它將mp3文件發送到html5的音頻標籤。問題是,在Safari中,audio.duration標記不起作用並返回無窮大。如果我將音頻的src直接設置爲文件,那麼一切正常。但我不希望我的用戶看到文件的路徑。audio.duration在從PHP提供mp3時返回Infinity on Safari

無論如何,這就是我從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"; 
} 

回答

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 = $文件大小-1 ...在Safari 5.1.4和新的iPad進行測試......

1

您的服務器必須允許範圍請求。通過 可以很容易地檢查您的服務器的響應中是否包含 標頭中的Accept-Ranges。大多數HTML5瀏覽器可以在下載過程中尋找新的文件位置 ,因此服務器必須允許請求的新範圍爲 。

未能接受字節範圍請求將導致某些 HTML5瀏覽器出現問題。通常無法從文件中讀取持續時間爲 某些格式要求將文件的開始和結束讀取到 瞭解其持續時間。如果服務器上未啓用Range請求,則Chrome往往會成爲最有 問題的瀏覽器,但所有 瀏覽器都會遇到問題,即使只是必須等待 才能在跳躍關閉之前加載所有介質到最後。

請參閱this post瞭解如何啓用範圍請求服務媒體的PHP示例。

而且,我注意到你正在使用No-Cache ..

使用服務器響應禁用的媒體的本地緩存可以 事業問題與一些HTML5的瀏覽器。這可能導致媒體的持續時間 未知。

1
  • 今天我浪費了我大部分時間研究這個問題,最後 出來瞭解決方案。 Safari瀏覽器返回 持續時間的原因非常有趣:看起來Safari 請求服務器兩次播放文件。首先它向範圍標題發送一個範圍 請求,如下所示:(bytes:0-1)。
  • 如果服務器沒有將響應作爲部分內容返回,並且如果它返回整個流,那麼Safari瀏覽器將不會設置 audio.duration標記,以及哪個結果只播放一次文件,而且它可以「再次播放。
  • 我做了一個快速修復,在服務器端只檢查 標題,如果它包含rangeHeader然後返回它。

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

+0

嗨@smurf我也看到了第一次調用音頻鏈接的範圍標頭「字節0-1」。但是,你能更具體地表達「回報它」的含義嗎?這是什麼,在這種情況下?我可以通過在響應中使用Content-Range標題返回一個字節。你是這個意思嗎? – Hewins 2017-10-05 04:18:17