Skip to content

Instantly share code, notes, and snippets.

@reececomo
Created June 19, 2024 11:16
Show Gist options
  • Select an option

  • Save reececomo/c7d7c34589dd2473049608789811512d to your computer and use it in GitHub Desktop.

Select an option

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.
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