views:

762

answers:

2

Ok, I'm trying to play an HTML audio code on iPad but does not work.

I created one PHP script to send to the MP3 request to the HTML5 audio code

mp3_file_player.php?n=mp3file.mp3

The player is here: http://www.avault.com/news/podcast-news/john-romero-podcast-episode-80/

You will see that works on every HTML5 supported browser even on my iPod Touch. But does not work on iPad/iPhone, even on Safari on Mac OSX (I tried on Safari/Windows, worked fine)

This is my PHP code:

header("X-Powered-By: ");
header("Accept-Ranges: bytes");
header("Content-Length: ". (string)(filesize($episode_filename)) ."");
header("Content-type: audio/mpeg");
readfile($episode_filename);
exit();

Everything works fine, the MP3 has the same headers like reading the mp3 directly.

HTTP Headers from direct file access:

(Status-Line) HTTP/1.1 200 OK
Date Mon, 31 May 2010 20:27:31 GMT
Server Apache/2.2.9
Last-Modified Wed, 26 May 2010 13:39:19 GMT
Etag "dac0039-41d91f8-4877f669cefc0"
Accept-Ranges bytes
Content-Length 50656162
Content-Range bytes 18390614-69046775/69046776
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type audio/mpeg

HTTP Header from my PHP script:

(Status-Line) HTTP/1.1 200 OK
Date Mon, 31 May 2010 20:27:08 GMT
Server Apache/2.2.9
Accept-Ranges bytes
Content-Length 69046776
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type audio/mpeg

The only thing different it's the Content-Range, I even tried to add it, but if I use it the player will not work on my Ipod Touch. So I removed.

Thank you very much.

A: 

Content-Range is only valid with status 206.

Your code doesn't seem to support partial requests at all (you'd have to parse Range header and stitch together response body accordingly, and Content-Length = filesize($episode_filename) would be invalid in almost every case).

If you're not going to implement HTTP server within HTTP server, let Apache serve the MP3.

If you need to have access control implemented in PHP, check out the X-Sendfile extension or create symlinks with unguessable filenames and redirect clients there.

If you really want to do HTTP partial downloads the hard way, read RFC 2616 or find library that will do it all for you. Don't just blindly send whatever HTTP headers you find.

porneL
I don't have access to Apache, thanks...
saulob
+1  A: 

Try remove header("Accept-Ranges: bytes"); as your not sending a portion of the file. Remove the header("X-Powered-By: "); as Apache serves that anyway

$etag = md5(serialize(fstat($fp))); 
fclose($fp); 
header('Etag: '.$etag); 

^^ Add an Electronic Tag

And give it a go!

RobertPitt
Thanks, I changed it all, gonna try it and see the result. But your $etag is missing the $fp, I found it online:$fp = fopen($_SERVER["SCRIPT_FILENAME"], "r");Right?Thanks. I just implemented, gonna ask a friend with iPad to test it.
saulob
RobertPitt, that was it. I removed the Accept-Ranges and Add the Etag, I did not remove the X-Powered. But it worked. Everything is smooth now. Thanks.
saulob
ETag is not needed, especially when you're not implementing cache validation.
porneL
no problem, glad I could help!
RobertPitt