29

I've been experimenting with the audio and local storage features of html5 of late and have run into something that has me stumped.

I'd like to be able to cache or store the source of the audio element locally to enable speedier and offline playback. The problem is I can't see how this is possible with the current implementation.

I have tried the following using WebKit:

  1. Creating a manifest file to set up local caching but the audio file appears not to be a cacheable item maybe due to the way it is stream or something

  2. I have also attempted to use javascript to put an audio object into local storage but the size of the mp3 makes this impossible due to memory issues (i think).

  3. I have tried to use the data uri and base64 to use the html as a audio transport that can be cached but again the filesize makes this prohibitive. Also the audio element does not seem to like this in WebKit (works fine in mozilla)

  4. I have tried several methods of putting the data into the local database store. Again suffering the same issues as the other cases.

I'd love to hear any other ideas anyone may have as to how I could achieve my goal of offline playback using caching/local storage in WebKit.

Jim Puls
  • 79,175
  • 10
  • 73
  • 78
andrewdotcom
  • 683
  • 2
  • 7
  • 12
  • I've been wondering if this was possible too, and came up with many of the same approaches. – Jonathan Oct 23 '09 at 08:55
  • Do you have some examples of what you've tried so far? – robertc Oct 24 '09 at 20:35
  • Any luck on this? I'm trying to do the same thing, with audio that I can't cache via the manifest because it's dynamically generated on the server (but not streamed). – Don Werve Jun 09 '10 at 10:47

6 Answers6

7

I've been trying to do this myself, on the iOS (for iPhone / iPad) but it refuses to cache audio files in offline, even if in Cache Manifest.

It does not error, but instead simply pretends to have played the audio element if invoked via JavaScript without a control. If it's embedded with a control, it displays an alternate control that says "Cannot play audio file.". It works fine if the application is able to go online.

It seems not to cache the audio, playing another sound resource seems to cause it to clear the previous resource from memory - this is pretty worthless functionality even when online.

I have experimented with base64 encoding the audio as data URI's. This works in Safari on the desktop (at least for fairly short samples of around 20-30k that I've been using) but seems not to be supported at all on iOS - it silently does nothing, which is highly annoying.

I don't know about other vendors - Google Chrome used to not support data URI's for audio but perhaps they fixed it... - it seems like it's not possible for now though.

Update: Minor discrepancy with iPhone OS 3.x (tested with 3.1.2): If an audio element is specified in an offline web app but it doesn't have a control, it displays a non-interactive control with a non-animated spinner on it (which it definitely shouldn't do). I assume this is fixed in iOS 4.x (which should be out next week).

Iain Collins
  • 6,774
  • 3
  • 43
  • 43
  • Yes, I tested with a range including very small sound files "just in case" there was a special rule. The largest file I cache is 180 KB, wither another at 135 KB as well as some at 25-35 KB, these are all images specified in my cache manifest and all work offline (including with airplane mode turned on) on both my iPad and iPhone (3GS running 3.1.2) so I'm not sure where 15 KB limit comes from. – Iain Collins Jun 15 '10 at 08:11
  • Had a quick read up on the 15 KB limit - seems it refers to what the browser caches during normal browsing, but not to offline web apps with a cache manifest, at least as near as I can tell. – Iain Collins Jun 15 '10 at 08:17
7

So it's been a while since I asked this question and I thought i'd give some info about how we solved it. Basically we encoded the data into PNG's using a similar technique to this:

http://audioscene.org/scene-files/yury/pngencoding/sample.html

Then cached the image on the mobile device using html5 local storage and accessed it as needed. The PNG's were pretty big but this worked for us.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
andrewdotcom
  • 683
  • 2
  • 7
  • 12
  • 1
    Darn! I really need a similar solution, but this site is down. – clem Apr 20 '11 at 22:10
  • 2
    I really want to know more about this trick. Site is still down .. Anyone has another source for this info? Argh! My curiosity is killing me! – micha Aug 04 '11 at 03:33
  • Executive summary: Use the R,G,B bytes in the PNG to store the bytes of whatever data you want to transport, then on the client side load it in to an img tag, draw it to a 2d , then use canvas api to convert what's been drawn in to an array of r,g,b,a color bytes. Hey presto! And PNG comes with built in compression! (gzip or something? I forget) – Blixxy Aug 17 '13 at 02:01
  • http://web.archive.org/web/20101213163349/http://audioscene.org/scene-files/yury/pngencoding/sample.html – Markus Johnsson May 04 '14 at 18:37
5

I spent a while trying to do this for a game I'm making, and since as far as I could tell browsers (Firefox and Chrome) still don't support caching of audio elements I thought I'd post the solution I found.

There is a workaround described here: http://dougx.net/plunder/index.php#code

I can confirm it works pretty well, but is probably better suited to smaller files. As he describes here (http://dougx.net/plunder/GameSounds.txt), you encode the audio as base64 strings, and give them a data:audio/ogg;base64 (or any compatible audio format) header, which HTML5 audio can then read in. Because this is just a string, the browser will cache it.

Varun Singh
  • 1,676
  • 3
  • 18
  • 25
2

I guess it would be preferable to get the manifest approach working, since this feels like the most relevant mechanism for locally caching the file.

What happens if you alter the audio file's HTTP headers, e.g. Content-Type and Expires? Does the browser do something different if the file extension is changed?

Prem
  • 15,911
  • 11
  • 31
  • 35
  • Premasagar, thank for your answer but unfortunately neither of these approaches seems to have any effect :( – andrewdotcom Oct 23 '09 at 15:06
  • Hmmm. It seems like there has to be a way to do this. Please do post whatever solution you find, as this will be useful to know. – Prem Oct 24 '09 at 20:32
2

I see you've had no luck so far.

You might want to take a look at JAI (JavaScript Audio Interface) ("the world's first javascript interface for web <audio>"). Or get in touch with Alastair MacDonald, who wrote it.

Failing that, the HTML5 Doctor may be able to assist.

Prem
  • 15,911
  • 11
  • 31
  • 35
1

Adding video and audio files to local storage works with iOS 4.3.

I just added a video and an audio file to manifest and they both got downloaded to offline storage on iPad.

matejk
  • 798
  • 1
  • 14
  • 27
  • Could you please elaborate on what you did? I've added .mp3 files to the manifest, but they are not cached and downloads every time. – SondreB Jul 11 '12 at 19:51
  • It was a while since I was working on that. I added files to manifest and set Expires flags in the Apache config files. I'm not sure if the latter did the trick. – matejk Jul 17 '12 at 08:42