Skip to content

Audio Sprites — Multiple Sounds from One File ​

Audio sprites bundle multiple short sounds into one file, reducing HTTP requests. Click below to hear how it works.

Many sounds, one file.

Hear all 6 sounds played back-to-back from one file
Beep
Cannon
Whoosh
Bling
Punch
Fanfare
{
  "spritemap": {
    "beep": {
      "start": 0,
      "end": 0.47,
      "loop": false
    },
    "cannon": {
      "start": 0.67,
      "end": 2.704,
      "loop": false
    },
    "whoosh": {
      "start": 2.904,
      "end": 3.966,
      "loop": false
    },
    "bling": {
      "start": 4.166,
      "end": 6.49,
      "loop": false
    },
    "punch": {
      "start": 6.69,
      "end": 7.484,
      "loop": false
    },
    "fanfare": {
      "start": 7.684,
      "end": 11.316,
      "loop": false
    }
  }
}

Ready

What Just Happened? ​

All 6 sounds you heard — beep, cannon, whoosh, bling, punch, fanfare — are packed into a single MP3 file. Instead of 6 HTTP requests, the browser loads one file and plays named segments within it.

A manifest maps each name to a time region:

┌──────┬────────┬───────┬──────┬───────┬─────────┐
│ beep │ cannon │ whoosh│ bling│ punch │ fanfare │
│ 0.0s │ 0.67s  │ 2.9s  │ 4.2s │ 6.7s  │ 7.7s    │
└──────┴────────┴───────┴──────┴───────┴─────────┘

createSprite() loads the file once, then plays segments by name. This technique is especially useful for games and interactive apps with many short sound effects — fewer requests means faster loading.

Sprite Formats ​

EZ Web Audio accepts two popular manifest formats. Format detection is automatic based on the top-level key.

audiosprite format ​

Uses spritemap with second-based {start, end} objects:

json
{
  "spritemap": {
    "laser": { "start": 0, "end": 0.3 },
    "explosion": { "start": 1.0, "end": 2.5, "loop": false }
  }
}

Howler.js format ​

Uses sprite with millisecond-based tuples [offset_ms, duration_ms]:

json
{
  "sprite": {
    "laser": [0, 300],
    "explosion": [1000, 1500],
    "powerup": [4000, 500, true]
  }
}

Howler tuples are [offset_ms, duration_ms] with an optional third boolean for looping. EZ Web Audio detects which format you're using and normalizes internally — you don't need to convert anything.

Basic Usage ​

typescript
import { createSprite } from 'ez-web-audio'

// audiosprite format
const sprite = await createSprite('sounds.mp3', {
  spritemap: {
    laser: { start: 0, end: 0.3 },
    explosion: { start: 1.0, end: 2.5 },
  },
})

// Or Howler format — works the same way
const sprite2 = await createSprite('sounds.mp3', {
  sprite: {
    laser: [0, 300],
    explosion: [1000, 1500],
  },
})

sprite.play('laser')
sprite.play('explosion', { gain: 0.7 })

Looping and Stopping ​

Set loop: true in the sprite definition to enable seamless looping:

typescript
const sprite = await createSprite('sounds.mp3', {
  spritemap: {
    engine: { start: 0.0, end: 2.0, loop: true },
    hit: { start: 2.5, end: 2.8 },
  },
})

// Start looping engine sound
sprite.play('engine')

// Stop the loop when done
sprite.stop('engine')

// Stop all active playback
sprite.stopAll()

Creating Sprites ​

You can create sprite files manually or use tools:

  • audiosprite CLI — Concatenates audio files and generates manifest JSON automatically. Install with npm install -g audiosprite, then run audiosprite -o output -e mp3 sound1.mp3 sound2.mp3.

  • soundfx — A ready-made collection of CC-licensed sound effects, perfect for prototyping and demos.

Silence Gaps

When creating sprites manually, add ~200ms of silence between sounds to prevent bleed from MP3 encoding artifacts.

Attribution ​

Sound effects in the demo from the soundfx collection. Individual sounds by JustinBW, dersuperanton, and MC5 via FreeSound (CC-BY-3.0), and nps.gov and Vladimir via SoundBible (CC-0).

Next Steps ​