For some reason in Safari (and no other major browser), when I serve an MP3 via PHP through an Audio
context in JavaScript, th
After much investigation like yourself I finally figured it out.
The first request Safari sends has the header:
Range: bytes=0-1
It's your job to respond "correctly" so that Safari will send additional requests to fetch the rest of the file.
Here is my example of the "correct" headers:
Content-Length: 2
Accept-Ranges: bytes
Content-Range: bytes 0-1/8469
(Make sure you set response status to 206!)
(8469 is the Content-Length of the entire file)
What happens after that is somewhat magical - Safari sends a follow up request that has this header:
Range: bytes=0-8468
And you should respond "correctly" like with these headers:
Content-Length: 8469
Accept-Ranges: bytes
Content-Range: bytes 0-8468/8469
(Again, status 206!)
I hope this solves it for you, since I spent many hours searching to no avail. I eventually realized I needed to adjust my server to handle requests where the Range header is present.
I used this commit to help me understand what the "correct" response is: https://github.com/jooby-project/jooby/commit/142a933a31b9d8742714ecd38475d90e563314f7
As this thread is popping up first in google, allow me to share my experience.
Like many, I'm generating the mp3 through a php page, mostly in order to "hide" the real link of the mp3. And for this, Safari is quite annoying. To make it short, Safari considers the sound as a "live broadcast", ending up having this "infinite" duration. For the details, this post explained quite well why.
So what to do ? You have to put conditions on the headers of your php page that generate the sound (as mentioned by @brianarpie). Here is my php-generating-mp3 page :
<?php
// first, you need this function :
function serveFilePartial($fileName, $fileTitle = null, $contentType = 'application/octet-stream'){
// the code of this can be found here : https://github.com/pomle/php-serveFilePartial/blob/master/ServeFilePartial.inc.php
}
$link_of_your_mp3 = "var/my_folder/my_music.mp3"; // this is not an URL, but an absolute path
// and we call the function :
serveFilePartial($link_of_your_mp3, null, 'audio/mpeg');
?>
.. and that's it ! this function will generate the right headers depending on what the web-browser is asking for.
Of course you've done all your checking on link, vars, etc to protect the page. Note that my example is mp3, so I have to call the function with 'audio/mpeg'. If you output a different fileformat, you will have to adapt the content Type of the function.