2012-03-09 9 views
5

Quindi, ho uno script php che invia il mio file mp3 al tag audio di html5. Il problema è che in Safari, il tag audio.duration non funziona e restituisce infinito. Se imposto il src dell'audio direttamente nel file, tutto funziona correttamente. Ma non voglio che i miei utenti vedano il percorso del file.audio.duration restituisce Infinity su Safari quando viene fornito mp3 da PHP

Ad ogni modo, questo è il modo in cui sto inviando le mie intestazioni da PHP.

Ho già provato ad avere gli intervalli di contenuti. Questo non ha aiutato.

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"; 
} 

risposta

4

Avevo lo stesso problema e ho aggiunto un paio di intestazioni. Sembra funzionare per me -

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 è la dimensione del file e $ shortlen = $ dimensione del file-1 ... testato su Safari 5.1.4 e sul nuovo iPad ...

1

Il server deve consentire le richieste di intervallo. Questo è facile da verificare per , se la risposta del tuo server include gli Accept-Ranges nell'intestazione . La maggior parte dei browser HTML5 abilita la ricerca di nuove posizioni di file durante il download, pertanto il server deve consentire che il nuovo intervallo sia richiesto.

La mancata accettazione delle richieste di intervallo di byte causerà problemi su alcuni browser HTML5 . Spesso la durata non può essere letta dal file come alcuni formati richiedono che l'inizio e la fine del file vengano letti su ne conosca la durata. Chrome tende ad essere il browser che presenta la maggior parte dei problemi se la richiesta Intervallo non è abilitata sul server, ma tutti i browser avranno qualche problema anche se è solo necessario attendere per tutti i file multimediali da caricare prima di saltare vicino all'estremità.

Vedi this post per esempio PHP di come servire i media con le richieste di intervallo abilitati.

Inoltre, ho notato che si sta utilizzando No-Cache ..

Utilizzando la risposta del server per disabilitare la cache locale dei media può causare problemi con alcuni browser HTML5. Ciò può causare la durata dello del supporto per essere sconosciuto.

1
  • Oggi i ho perso la maggior parte del mio tempo esaminando questo problema e finalmente è uscito con una soluzione. Il motivo per cui safari restituisce la durata di come infinito è piuttosto interessante: sembra che Safari richieda al server due volte di riprodurre i file. Innanzitutto invia una richiesta di intervallo al numero al server con un'intestazione di intervallo come questa: (byte: 0-1).
  • Se il server non restituisce la risposta come un contenuto parziale e se restituisce l'intero flusso poi il browser Safari non sarà impostato tag audio.duration e che si traducono in riproduzione del file solo una volta e Può' t essere giocato di nuovo.
  • Ho fatto una soluzione rapida, sul lato server basta controllare l'intestazione e se contiene un rangeHeader, quindi restituirlo.

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

+0

Hi @smurf vedo anche la prima chiamata al collegamento audio con "byte 0-1" nell'intestazione Range. Ma puoi essere più specifico di cosa intendi con "il ritorno"? Cosa c'è, in questo caso? Posso restituire un byte usando l'intestazione Content-Range nella risposta. È questo che vuoi dire? – Hewins