@pixi/sound
Version:
WebAudio API playback library with filters
1 lines • 32.9 kB
Source Map (JSON)
{"version":3,"file":"Sound.mjs","sources":["../src/Sound.ts"],"sourcesContent":["import { path } from 'pixi.js';\nimport { Filter } from './filters/Filter';\nimport { HTMLAudioMedia } from './htmlaudio/HTMLAudioMedia';\nimport { getInstance } from './instance';\nimport { IMedia, IMediaContext, IMediaInstance } from './interfaces';\nimport { SoundSprite, SoundSpriteData, SoundSprites } from './SoundSprite';\nimport { extensions, supported } from './utils/supported';\nimport { WebAudioMedia } from './webaudio/WebAudioMedia';\n\n/**\n * Options to use for creating sounds.\n */\ninterface Options\n{\n /**\n * `true` to immediately start preloading.\n * @default false\n */\n autoPlay?: boolean;\n /**\n * `true` to disallow playing multiple layered instances at once.\n * @default false\n */\n singleInstance?: boolean;\n /**\n * The amount of volume 1 = 100%.\n * @default 1\n */\n volume?: number;\n /**\n * The playback rate where 1 is 100% speed.\n * @default 1\n */\n speed?: number;\n /**\n * Global complete callback when play is finished.\n * @type {Function}\n */\n complete?: CompleteCallback;\n /**\n * Call when finished loading.\n * @type {Function}\n */\n loaded?: LoadedCallback;\n /**\n * `true` to immediately start preloading if loading from `url`.\n */\n preload?: boolean;\n /**\n * Initial loop value, `true` is loop infinitely\n * @default false\n */\n loop?: boolean;\n /**\n * The source of the file being loaded\n */\n url?: string | string[];\n /**\n * If sound is already preloaded, available.\n */\n source?: ArrayBuffer | AudioBuffer | HTMLAudioElement;\n /**\n * The map of sprite data. Where a sprite is an object\n * with a `start` and `end`, which are the times in seconds. Optionally, can include\n * a `speed` amount where 1 is 100% speed.\n */\n sprites?: Record<string, SoundSpriteData>;\n}\n\n/**\n * Options used for sound playback.\n */\ninterface PlayOptions\n{\n /**\n * Start time offset in seconds.\n * @default 0\n */\n start?: number;\n /**\n * End time in seconds.\n */\n end?: number;\n /**\n * Override default speed, default to the Sound's speed setting.\n */\n speed?: number;\n /**\n * Override default loop, default to the Sound's loop setting.\n */\n loop?: boolean;\n /**\n * Override default volume, default to the Sound's volume setting.\n */\n volume?: number;\n /**\n * The sprite to play.\n */\n sprite?: string;\n /**\n * If sound instance is muted by default.\n * @default false\n */\n muted?: boolean;\n /**\n * Filters that apply to play.\n * Only supported with WebAudio.\n */\n filters?: Filter[];\n /**\n * When completed.\n * @type {Function}\n */\n complete?: CompleteCallback;\n /**\n * If not already preloaded, callback when finishes load.\n * @type {Function}\n */\n loaded?: LoadedCallback;\n /**\n * Setting `true` will stop any playing instances. This is the same as\n * the singleInstance property on Sound, but is play-specific.\n */\n singleInstance?: boolean;\n}\n\n/**\n * Callback when sound is loaded.\n * @ignore\n * @param {Error} err - The callback error.\n * @param {Sound} sound - The instance of new sound.\n * @param {IMediaInstance} instance - The instance of auto-played sound.\n */\ntype LoadedCallback = (err: Error, sound?: Sound, instance?: IMediaInstance) => void;\n\n/**\n * Callback when sound is completed.\n * @ignore\n * @param {Sound} sound - The instance of sound.\n */\ntype CompleteCallback = (sound: Sound) => void;\n\ntype SoundSpriteDataMap = Record<string, SoundSpriteData>;\n\n/**\n * Sound represents a single piece of loaded media. When playing a sound {@link IMediaInstance} objects\n * are created. Properties such a `volume`, `pause`, `mute`, `speed`, etc will have an effect on all instances.\n */\nclass Sound\n{\n /** Pool of instances */\n private static _pool: IMediaInstance[] = [];\n\n /**\n * `true` if the buffer is loaded.\n * @default false\n */\n public isLoaded: boolean;\n\n /**\n * `true` if the sound is currently being played.\n * @default false\n * @readonly\n */\n public isPlaying: boolean;\n\n /**\n * true to start playing immediate after load.\n * @default false\n * @readonly\n */\n public autoPlay: boolean;\n\n /**\n * `true` to disallow playing multiple layered instances at once.\n * @default false\n */\n public singleInstance: boolean;\n\n /**\n * `true` to immediately start preloading.\n * @default false\n * @readonly\n */\n public preload: boolean;\n\n /**\n * The file source to load.\n * @readonly\n */\n public url: string;\n\n /**\n * The constructor options.\n * @readonly\n */\n public options: Options;\n\n /** The audio source */\n public media: IMedia;\n\n /** The list of play calls while waiting to preload the sound. */\n private _preloadQueue: (() => void)[] | null;\n\n /** The collection of instances being played. */\n private _instances: IMediaInstance[];\n\n /** The user defined sound sprites. */\n private _sprites: SoundSprites;\n\n /** The options when auto-playing. */\n private _autoPlayOptions: PlayOptions;\n\n /** The internal volume. */\n private _volume: number;\n\n /** The internal paused state. */\n private _paused: boolean;\n\n /** The internal muted state. */\n private _muted: boolean;\n\n /** The internal volume. */\n private _loop: boolean;\n\n /** The internal playbackRate */\n private _speed: number;\n\n /**\n * Create a new sound instance from source.\n * @param source - Either the path or url to the source file.\n * or the object of options to use.\n * @return Created sound instance.\n */\n public static from(source: string | string[] | Options | ArrayBuffer | HTMLAudioElement | AudioBuffer): Sound\n {\n let options: Options = {};\n\n if (typeof source === 'string')\n {\n options.url = source as string;\n }\n else if (source instanceof ArrayBuffer || source instanceof AudioBuffer || source instanceof HTMLAudioElement)\n {\n options.source = source;\n }\n else if (Array.isArray(source))\n {\n options.url = source;\n }\n else\n {\n options = source;\n }\n\n // Default settings\n options = {\n autoPlay: false,\n singleInstance: false,\n url: null,\n source: null,\n preload: false,\n volume: 1,\n speed: 1,\n complete: null,\n loaded: null,\n loop: false, ...options\n };\n\n Object.freeze(options);\n\n const media: IMedia = getInstance().useLegacy\n ? new HTMLAudioMedia()\n : new WebAudioMedia();\n\n return new Sound(media, options);\n }\n\n /**\n * Use `Sound.from`\n * @ignore\n */\n constructor(media: IMedia, options: Options)\n {\n this.media = media;\n this.options = options;\n this._instances = [];\n this._sprites = {};\n\n this.media.init(this);\n\n const complete = options.complete;\n\n this._autoPlayOptions = complete ? { complete } : null;\n this.isLoaded = false;\n this._preloadQueue = null;\n this.isPlaying = false;\n this.autoPlay = options.autoPlay;\n this.singleInstance = options.singleInstance;\n this.preload = options.preload || this.autoPlay;\n\n this.url = Array.isArray(options.url)\n ? this.preferUrl(options.url)\n : options.url;\n this.speed = options.speed;\n this.volume = options.volume;\n this.loop = options.loop;\n\n if (options.sprites)\n {\n this.addSprites(options.sprites);\n }\n\n if (this.preload)\n {\n this._preload(options.loaded);\n }\n }\n\n /**\n * Internal help for resolving which file to use if there are multiple provide\n * this is especially helpful for working with bundlers (non Assets loading).\n */\n private preferUrl(urls: string[]): string\n {\n const [file] = urls\n .map((url) => ({ url, ext: path.extname(url).slice(1) }))\n .filter(({ ext }) => supported[ext])\n .sort((a, b) => extensions.indexOf(a.ext) - extensions.indexOf(b.ext));\n\n if (!file)\n {\n throw new Error('No supported file type found');\n }\n\n return file.url;\n }\n\n /** Instance of the media context. */\n public get context(): IMediaContext\n {\n return getInstance().context;\n }\n\n /** Stops all the instances of this sound from playing. */\n public pause(): this\n {\n this.isPlaying = false;\n this.paused = true;\n\n return this;\n }\n\n /** Resuming all the instances of this sound from playing */\n public resume(): this\n {\n this.isPlaying = this._instances.length > 0;\n this.paused = false;\n\n return this;\n }\n\n /** Stops all the instances of this sound from playing. */\n public get paused(): boolean\n {\n return this._paused;\n }\n public set paused(paused: boolean)\n {\n this._paused = paused;\n this.refreshPaused();\n }\n\n /** The playback rate. */\n public get speed(): number\n {\n return this._speed;\n }\n public set speed(speed: number)\n {\n this._speed = speed;\n this.refresh();\n }\n\n /** Set the filters. Only supported with WebAudio. */\n public get filters(): Filter[]\n {\n return this.media.filters;\n }\n public set filters(filters: Filter[])\n {\n this.media.filters = filters;\n }\n\n /**\n * Add a sound sprite, which is a saved instance of a longer sound.\n * Similar to an image spritesheet.\n * @param alias - The unique name of the sound sprite.\n * @param data - Either completed function or play options.\n */\n public addSprites(alias: string, data: SoundSpriteData): SoundSprite;\n\n /**\n * Convenience method to add more than one sprite add a time.\n * @param data - Map of sounds to add where the key is the alias,\n * and the data are configuration options.\n * @return The map of sound sprites added.\n */\n public addSprites(data: SoundSpriteDataMap): SoundSprites;\n\n /**\n * @ignore\n */\n public addSprites(source: string | SoundSpriteDataMap, data?: SoundSpriteData): any\n {\n if (typeof source === 'object')\n {\n const results: SoundSprites = {};\n\n for (const alias in source)\n {\n results[alias] = this.addSprites(alias, source[alias]);\n }\n\n return results;\n }\n\n // eslint-disable-next-line no-console\n console.assert(!this._sprites[source], `Alias ${source} is already taken`);\n const sprite = new SoundSprite(this, data);\n\n this._sprites[source] = sprite;\n\n return sprite;\n }\n\n /** Destructor, safer to use `SoundLibrary.remove(alias)` to remove this sound. */\n public destroy(): void\n {\n this._removeInstances();\n this.removeSprites();\n this.media.destroy();\n this.media = null;\n this._sprites = null;\n this._instances = null;\n }\n\n /**\n * Remove a sound sprite.\n * @param alias - The unique name of the sound sprite, if alias is omitted, removes all sprites.\n */\n public removeSprites(alias?: string): Sound\n {\n if (!alias)\n {\n for (const name in this._sprites)\n {\n this.removeSprites(name);\n }\n }\n else\n {\n const sprite: SoundSprite = this._sprites[alias];\n\n if (sprite !== undefined)\n {\n sprite.destroy();\n delete this._sprites[alias];\n }\n }\n\n return this;\n }\n\n /** If the current sound is playable (loaded). */\n public get isPlayable(): boolean\n {\n return this.isLoaded && this.media && this.media.isPlayable;\n }\n\n /** Stops all the instances of this sound from playing. */\n public stop(): this\n {\n if (!this.isPlayable)\n {\n this.autoPlay = false;\n this._autoPlayOptions = null;\n\n return this;\n }\n this.isPlaying = false;\n\n // Go in reverse order so we don't skip items\n for (let i = this._instances.length - 1; i >= 0; i--)\n {\n this._instances[i].stop();\n }\n\n return this;\n }\n\n /**\n * Play a sound sprite, which is a saved instance of a longer sound.\n * Similar to an image spritesheet.\n * @method play\n * @instance\n * @param alias - The unique name of the sound sprite.\n * @param {Function} callback - Callback when completed.\n * @return The sound instance,\n * this cannot be reused after it is done playing. Returns a Promise if the sound\n * has not yet loaded.\n */\n public play(alias: string, callback?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>;\n\n /**\n * Plays the sound.\n * @method play\n * @instance\n * @param {Function|PlayOptions} source - Either completed function or play options.\n * @param {Function} callback - Callback when completed.\n * @return The sound instance,\n * this cannot be reused after it is done playing. Returns a Promise if the sound\n * has not yet loaded.\n */\n public play(source?: string | PlayOptions | CompleteCallback,\n callback?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>;\n\n // Overloaded function\n public play(source?: string | PlayOptions | CompleteCallback,\n complete?: CompleteCallback): IMediaInstance | Promise<IMediaInstance>\n {\n let options: PlayOptions;\n\n if (typeof source === 'string')\n {\n const sprite: string = source as string;\n\n options = { sprite, loop: this.loop, complete };\n }\n else if (typeof source === 'function')\n {\n options = {};\n options.complete = source as CompleteCallback;\n }\n else\n {\n options = source as PlayOptions;\n }\n\n options = {\n complete: null,\n loaded: null,\n sprite: null,\n end: null,\n start: 0,\n volume: 1,\n speed: 1,\n muted: false,\n loop: false, ...(options || {})\n };\n\n // A sprite is specified, add the options\n if (options.sprite)\n {\n const alias: string = options.sprite;\n\n // eslint-disable-next-line no-console\n console.assert(!!this._sprites[alias], `Alias ${alias} is not available`);\n const sprite: SoundSprite = this._sprites[alias];\n\n options.start = sprite.start + (options.start || 0);\n options.end = sprite.end;\n options.speed = sprite.speed || 1;\n options.loop = sprite.loop || options.loop;\n delete options.sprite;\n }\n\n // @deprecated offset option\n if ((options as any).offset)\n {\n options.start = (options as any).offset as number;\n }\n\n // if not yet playable, ignore\n // - usefull when the sound download isnt yet completed\n if (!this.isLoaded)\n {\n // Handle the case when trying to play a sound that is not yet loaded\n // We'll add it to a queue to play after initial load finishes\n if (this._preloadQueue)\n {\n return new Promise<IMediaInstance>((resolve) =>\n {\n this._preloadQueue.push(() =>\n {\n resolve(this.play(options));\n });\n });\n }\n\n this._preloadQueue = [];\n this.autoPlay = true;\n this._autoPlayOptions = options;\n\n return new Promise<IMediaInstance>((resolve, reject) =>\n {\n this._preload((err: Error, sound: Sound, media: IMediaInstance) =>\n {\n this._preloadQueue.forEach((resolve) => resolve());\n this._preloadQueue = null;\n\n if (err)\n {\n reject(err);\n }\n else\n {\n if (options.loaded)\n {\n options.loaded(err, sound, media);\n }\n resolve(media);\n }\n });\n });\n }\n\n // Stop all sounds\n if (this.singleInstance || options.singleInstance)\n {\n this._removeInstances();\n }\n\n // clone the bufferSource\n const instance = this._createInstance();\n\n this._instances.push(instance);\n this.isPlaying = true;\n instance.once('end', () =>\n {\n if (options.complete)\n {\n options.complete(this);\n }\n this._onComplete(instance);\n });\n instance.once('stop', () =>\n {\n this._onComplete(instance);\n });\n\n instance.play(options);\n\n return instance;\n }\n\n /** Internal only, speed, loop, volume change occured. */\n public refresh(): void\n {\n const len = this._instances.length;\n\n for (let i = 0; i < len; i++)\n {\n this._instances[i].refresh();\n }\n }\n\n /** Handle changes in paused state. Internal only. */\n public refreshPaused(): void\n {\n const len = this._instances.length;\n\n for (let i = 0; i < len; i++)\n {\n this._instances[i].refreshPaused();\n }\n }\n\n /** Gets and sets the volume. */\n public get volume(): number\n {\n return this._volume;\n }\n public set volume(volume: number)\n {\n this._volume = volume;\n this.refresh();\n }\n\n /** Gets and sets the muted flag. */\n public get muted(): boolean\n {\n return this._muted;\n }\n public set muted(muted: boolean)\n {\n this._muted = muted;\n this.refresh();\n }\n\n /** Gets and sets the looping. */\n public get loop(): boolean\n {\n return this._loop;\n }\n public set loop(loop: boolean)\n {\n this._loop = loop;\n this.refresh();\n }\n\n /** Starts the preloading of sound. */\n private _preload(callback?: LoadedCallback): void\n {\n this.media.load(callback);\n }\n\n /** Gets the list of instances that are currently being played of this sound. */\n public get instances(): IMediaInstance[]\n {\n return this._instances;\n }\n\n /** Get the map of sprites. */\n public get sprites(): SoundSprites\n {\n return this._sprites;\n }\n\n /** Get the duration of the audio in seconds. */\n public get duration(): number\n {\n return this.media.duration;\n }\n\n /** Auto play the first instance. */\n public autoPlayStart(): IMediaInstance\n {\n let instance: IMediaInstance;\n\n if (this.autoPlay)\n {\n instance = this.play(this._autoPlayOptions) as IMediaInstance;\n }\n\n return instance;\n }\n\n /** Removes all instances. */\n private _removeInstances(): void\n {\n // destroying also stops\n for (let i = this._instances.length - 1; i >= 0; i--)\n {\n this._poolInstance(this._instances[i]);\n }\n this._instances.length = 0;\n }\n\n /**\n * Sound instance completed.\n * @param instance\n */\n private _onComplete(instance: IMediaInstance): void\n {\n if (this._instances)\n {\n const index = this._instances.indexOf(instance);\n\n if (index > -1)\n {\n this._instances.splice(index, 1);\n }\n this.isPlaying = this._instances.length > 0;\n }\n this._poolInstance(instance);\n }\n\n /** Create a new instance. */\n private _createInstance(): IMediaInstance\n {\n if (Sound._pool.length > 0)\n {\n const instance: IMediaInstance = Sound._pool.pop();\n\n instance.init(this.media);\n\n return instance;\n }\n\n return this.media.create();\n }\n\n /**\n * Destroy/recycling the instance object.\n * @param instance - Instance to recycle\n */\n private _poolInstance(instance: IMediaInstance): void\n {\n instance.destroy();\n // Add it if it isn't already added\n if (Sound._pool.indexOf(instance) < 0)\n {\n Sound._pool.push(instance);\n }\n }\n}\n\nexport { Sound };\nexport type {\n CompleteCallback,\n LoadedCallback,\n Options,\n PlayOptions,\n SoundSpriteDataMap\n};\n"],"names":["resolve"],"mappings":"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"}