Created
June 19, 2024 11:16
-
-
Save reececomo/c7d7c34589dd2473049608789811512d to your computer and use it in GitHub Desktop.
Import audio sprite assets with @pixi/sound. For use with audiosprite / assetpack-plugin-audiosprite.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Sound, utils, sound } from '@pixi/sound'; | |
| import { Loader, ExtensionType, LoaderParserPriority } from 'pixi.js'; | |
| /** JSON file 'jukebox' format (the default format emitted by audiosprite) */ | |
| export interface AudiospriteJson { | |
| resources: string[]; | |
| spritemap: Record<string, { start: number, end: number, loop?: boolean }>; | |
| } | |
| /** | |
| * A simple loader plugin for loading audio sprites generated by Audiosprite | |
| * as @pixi/sound Sound assets. | |
| * | |
| * @see https://www.npmjs.com/package/@pixi/sound | |
| * @see https://www.npmjs.com/package/assetpack-plugin-audiosprite | |
| * @see https://www.npmjs.com/package/audiosprite | |
| */ | |
| export const audiospriteAsset = { | |
| extension: ExtensionType.Asset, | |
| loader: { | |
| name: 'audiospriteLoader', | |
| extension: { | |
| type: ExtensionType.LoadParser, | |
| priority: LoaderParserPriority.Normal, | |
| name: 'audiospriteLoader', | |
| }, | |
| async testParse(audiosprite: AudiospriteJson, options): Promise<boolean> { | |
| return (options ?? { src: '' }).src.endsWith('.json') | |
| && (!!audiosprite.spritemap && !!audiosprite.resources); // 'jukebox' format | |
| }, | |
| async parse( | |
| audiosprite: AudiospriteJson, | |
| options: any, | |
| loader?: Loader, | |
| ): Promise<Sound> { | |
| let basePath = (options?.src ?? '').replace(/\/[^/]+$/, '/'); | |
| if (basePath && !basePath.endsWith('/')) { | |
| basePath += '/'; | |
| } | |
| // assume preferred formats are pre-sorted | |
| const urls = audiosprite.resources ?? []; | |
| let url = getSupportedUrl(urls); | |
| if (!url) throw new Error("No supported resources detected: " + urls.join(', ')); | |
| // assume relative paths | |
| url = basePath + url; | |
| // load sound sprite | |
| const soundAsset: Sound = await new Promise<Sound>((resolve, reject) => Sound.from({ | |
| url, | |
| preload: true, | |
| loaded(err, sound) { | |
| if (err) return reject(err); | |
| resolve(sound!); | |
| }, | |
| })); | |
| // register sound sprites | |
| soundAsset.addSprites(audiosprite.spritemap); | |
| // register sound sprite alias | |
| for (const alias of options?.alias ?? []) { | |
| sound.add(alias, soundAsset); | |
| } | |
| return soundAsset; | |
| }, | |
| async unload(_sound: Sound, _, loader: Loader) { | |
| _sound.removeSprites(); | |
| await loader.unload(_sound.url); | |
| }, | |
| } | |
| }; | |
| /** @returns first URL @pixi/sound detects as supported */ | |
| function getSupportedUrl(urls: string[]): string | undefined { | |
| return urls.find(url => utils.supported[url.split('.').pop() ?? '']); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment