When I add my beep-23.mp3 file to the cache manifest, the sound effect no longer works on or offline. Is this a bug, or am I doing something wrong?
The audio is within
UPDATE for iOS 6:
This is all fixed in iOS 6. You can cache an audio file and play it via javascript without user input.
shaun5 Nov 7 '12 at 0:58
Even though it should work and there are no specifications (W3C, Apple) which say it shouldn't, I tested some scenarios and it seems like Safari on iOS is just refusing to cache the sound files.
Safari is loading the audio file (but not the index.html) every time I reload the page, so caching is apparently not working correct regardlessly of file size.
After some research: It looks like it's not possible to cache audio files. So you may file a bug at Apples bugtracker.
Here's my code to prove my results:
index.html:
<!DOCTYPE HTML>
<html lang="en-US" manifest="audio.appcache">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<title>Cached audio</title>
</head>
<body>
<h1>Cached audio</h1>
<audio controls autobuffer>
<source src="sample.mp3" type="audio/mpeg" />
</audio>
</body>
</html>
audio.appcache:
CACHE MANIFEST
# 2012-02-23:v1
# explicitly cached
CACHE:
index.html
sample.mp3
.htaccess:
AddType text/cache-manifest .appcache
AddType audio/mpeg .mp3
EDIT
I also tried using data URIs but, that Safari keeps refusing the audio data. So I think it's not possible to cache audio …
<?php
function data_uri( $file ) {
$contents = file_get_contents( $file );
$base64 = base64_encode( $contents );
return ( 'data:audio/mpeg;base64,'.$base64 );
}
?>
...
<audio controls autobuffer>
<source src="<?php echo data_uri('sample.mp3'); ?>" type="audio/mpeg" />
</audio>
...
EDIT 2
Great idea, but it looks like it's not working … Safari for OS X -> ok; Safari for iOS -> still the same problem as we had before.
<?php
function base_64_string( $file ) {
$contents = file_get_contents( $file );
return base64_encode( $contents );
}
?>
...
<audio controls autobuffer>
<source id="sound-src" src="sample.mp3" type="audio/mpeg" />
</audio>
...
<script>
(function(){
var sound;
if ( localStorage.getItem('cachedSound')) {
sound = localStorage.getItem('cachedSound');
}
else {
sound = "<?php echo base_64_string('sample.mp3'); ?>";
localStorage.setItem('cachedSound',sound);
}
document.getElementById("sound-src").src='data:audio/mpeg;base64,' + sound;
})();
</script>
Apple do not support playing audio via safari, this is intentional to prevent people using online domains to store you music without paying for them and using you iPod/iPhone to play them. It's apples way of trying to make you pay for music. Sorry guys.
If you haven't already you have to make sure that URL paths are absolute or relative to the .manifest and not the actual webpage.
There is also a limit to the size of the actual component that you are trying to cache currently at 4MB.
The total cache limit is 5MB.
I'm also pretty sure you can not cache audio and video files.