Audio Sprite Support Added To SoundJS

SoundJS has added support for Audio Sprites, available immediately in the NEXT version of SoundJS on GitHub. For those unfamiliar with audio sprites, they are much like CSS sprites or sprite sheets: multiple audio assets grouped into a single file.

Benefits of Audio Sprites

  1. More robust support for older browsers and devices that only allow a single audio instance, such as iOS 5.
  2. They provide a work around for the Internet Explorer 9 audio tag limit, which until now restricted how many different sounds we could load at once.
  3. Faster loading by only requiring a single network request for several sounds, especially on mobile devices where the network round trip for each file can add significant latency.
  4. Potentially smaller file sizes, again leading to faster loading. In a simple test, I was able to take 3 .ogg files of a combined 30KB and turn them into a single 21KB file. A test with the same 3 files in .mp3 format was less successful, growing from combined 33KB to single 45KB.  I suspect that with proper optimizations and smart compression the results could be improved, making this an area worth further exploration.

Drawbacks of Audio Sprites

  1. No guarantee of smooth looping when using HTML or Flash audio.  If you have a track that needs to loop smoothly and you are supporting non-web audio browsers, do not use audio sprites for that sound if you can avoid it.
  2. No guarantee that HTML audio will play back immediately, especially the first time. In some browsers (Chrome!), HTML audio will only load enough to play through – so we rely on the “canplaythrough” event to determine if the audio is loaded. Since audio sprites must jump ahead to play specific sounds, the audio may not yet have downloaded.
  3. They add work. Specifically you’ll need to track starting time and duration – and combining and managing audio files will require extra work.
  4. Audio sprites share the same core source, so if you have a sprite with 5 sounds and are limited to 2 concurrently playing instances, that means you can only play 2 of the sounds at the same time.

How to Make an Audio Sprite

Step 1: Combine several audio files into a single larger audio file.  We recommend at least 300ms of silence between audio clips to deal with some HTML audio tag inaccuracy issues, and to prevent accidentally playing bits of the neighbouring clips.

Step 2: Write some code:

createjs.Sound.initializeDefaultPlugins();
var assetsPath = "./assets/";
var manifest = [{
  src:"MyAudioSprite.ogg", data: {
    audioSprite: [
      {id:"sound1", startTime:0, duration:500},
      {id:"sound2", startTime:1000, duration:400},
      {id:"sound3", startTime:1700, duration: 1000}
    ]}
  }
];
createjs.Sound.alternateExtensions = ["mp3"];
createjs.Sound.addEventListener("fileload", loadSound);
createjs.Sound.registerManifest(manifest, assetsPath);
// after load is complete
createjs.Sound.play("sound2");

Step 3: Adding support to SoundJS for audio sprites has another awesome benefit. Any sound can now be played using a start time and duration, making the soundInstance behave like an audio sprite.

createjs.Sound.play("MyAudioSprite", {startTime: 1000, duration: 400});

Conclusion

It has been an interesting experience adding audio sprites to SoundJS, and we hope you will get good use out of them.  Please share your thoughts and experiences in the comments below, and as always you can ask questions and report issues in the Community forums.

25 thoughts on Audio Sprite Support Added To SoundJS

Comments are closed.

  1. Is createjs thinking of making an audio sprite generator? something that stitches audio files together and outputs a json file. a little like Zoe

    Jonny

  2. That would be awesome, but we don’t have time at the moment. I’m hoping someone in the community might be able to come up with a solution in the meantime.

  3. Hi Alex, thanks for sharing. This looks like a useful tool.

    I liked the howler format, but felt it didn’t match the style we are using in SoundJS. I prefer internal consistency and predictability, with the hope that anyone already using SoundJS would be able to guess the format of audio sprites.

    The conversion from howler to soundjs format should be straight forward. It would be awesome if your project either output both howler.json and soundjs.json or had an initial setting that lets you switch the output style. Hopefully someone in the community will submit a pull request. =)

  4. Mh… was this feature really tested? Until now I have used my own, very ugly implementation of sprites with SoundJS (with timeouts…)! I was thrilled to hear about the new approach and tried testing it. If I try to play a sprite, I get a “playFailed” and if I try to play the the orginial sound “as an audio sprite”, the startTime attribute is not evaluated. Instead the duration is taken for both start time and duration. All very strange …

  5. Hi bekay, yes this was tested in all major browsers. However a fix was pushed just today, so you will want to grab the latest [NEXT build from github](https://github.com/CreateJS/SoundJS/).

    If that does not work for you, please let me know what os and browser version you are testing in.

    Hope that helps.

  6. Well, it did not work for me, because you guys have already changed the api :D

    Your blog post states, I can configure the audio sprites in the data object with the key “sprite” … but it is “audioSprite”. I would recommend you update the code examples above, because it is the only documentation for this great feature to date.

  7. Nice catch, I’ve updated the code in the blog post. I guess its all part of the exciteing adventure of working with live under development libraries. =)

  8. Hey everyone- piggying back off the suggestions to use Tonistiigi’s audiosprite generator:

    Here’s a simple snippet on JSFiddle I made that takes exported .json from the audiosprite tool and reformats it in usable format for audioSprite in this NEXT version of SoundJS.

    My snippet: http://jsfiddle.net/bharat_battu/g8fFP/12/
    the audiosprite tool: https://github.com/tonistiigi/audiosprite

    The Audiosprite generator tool and this snippet allowed me to convert projects using tons of discrete audio files for every sound asset into single audio-sprite projects in mere minutes!

    The new audioSprite support in this NEXT version of SoundJS is great, as I’ve found it does reduce load times SIGNIFICANTLY to pack all of my sound assets into a single audioSprite compared to loading tons of discrete audio files in my loadQueue.

    Enjoy!
    @bharat_battu

  9. Awesome work Bharat, thanks for the feedback.

    I also came across your blog post which I thought was informative.

    I just wanted to quote the informal testing results noted in your blog:
    Martha’s Steaks:
    SoundJS discrete files (121 .mp3 files for narrator): 42-46 seconds
    SoundJS audioSprite (single .mp3 file for narrator): 30-32 seconds

    Night Light:
    SoundJS discrete files (48 .mp3 files for narrator): 45 seconds
    SoundJS audioSprite (single .mp3 file for narrator): 22-30 seconds

    I’ve been wanting to run some tests to show the difference in download speeds on various devices, so if you have any further device specific numbers from your projects showing the difference I would be really interested.

  10. Whatever you do to generate sprites, I highly recommend using Variable Bit Rate (VBR) encoding parameters with ffmpeg so the silence gaps are free.

  11. Hi, at the top of the article it mentions the NEXT version is available on Github ([https://github.com/CreateJS/SoundJS/]https://github.com/CreateJS/SoundJS/), which is the latest version. You can find a compiled version in the Lib folder.

    Hope that helps.

  12. yes, playing back empty parts of the file does work and can be used to force loading but unless you prevent playback until that is done, you could still run into the problem.

    • Sound has no id-based control of elements (although the first version in 2010 did!). When you play a sound, you get back a reference to the SoundInstance. Store that off, and then call pause() on it.

      var sound = createjs.Sound.play("src", etc);
      $(‘#btnAudio1′).click(function() {
      sound.pause();
      });

  13. I am unable to find any example or instructions on how to load audio sprites using preloadjs. I tried declaring the json as a type=”spritesheet”, the we do for image spies, but that did not help. Can you please show me the way.

    • There is not currently a way to use external JSON for audio sprites. It requires you to pass the sprite definition (data.audioSprite) in the LoadItem in JavaScript, which may not work in a JSON manifest.

      It might make sense to add audiosprite JSON support in SoundJS/PreloadJS as a totally separate type (Maybe `type:audiosprite`?).

      I opened an issue: https://github.com/CreateJS/SoundJS/issues/272

© Copyright 2024