Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 audio with PHP script does not work on iPad/Iphone

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.

like image 397
saulob Avatar asked May 31 '10 20:05

saulob


3 Answers

i was serving up mp3's to a music player.. I had similar headers. Some mp3 played on ipad. others did not.

i found this article fixed my issues. http://mobiforge.com/developing/story/content-delivery-mobile-devices Basically that Apple iPhone uses HTTP byte-ranges for requesting audio and video files.

my headers are:

header("X-Powered-By: ");
header('Content-Length: '. (string)filesize($path)); // provide file size
header('Content-type: audio/mpeg');

if(isset($_SERVER['HTTP_RANGE']))  { // any device that supports byte-ranges
 rangeDownload($path); // function from article mentioned above
}

$fp = fopen($_SERVER["SCRIPT_FILENAME"], "r");
$etag = md5(serialize(fstat($fp))); 
fclose($fp); 
header('Etag: '.$etag); 
readfile($path);
like image 82
nawlbergs Avatar answered Nov 07 '22 07:11

nawlbergs


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.

like image 24
Kornel Avatar answered Nov 07 '22 06:11

Kornel


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!

like image 2
RobertPitt Avatar answered Nov 07 '22 06:11

RobertPitt