UNPKG

sound-manager

Version:
93 lines (79 loc) 2.12 kB
import { getFrozenObject, } from '../functions/getFrozenObject'; import { ICreateSoundOptions, } from './ICreateSoundOptions'; import { ISound, } from './ISound'; import { Sound, } from './Sound'; import { assertValid, } from 'ts-assertions'; export const strings = { GET_MANAGER_VOLUME_INVALID: 'The getManagerVolume argument property was not provided to ' + 'createHtmlAudioSound.', OPTIONS_INVALID: 'The options argument was not provided to createHtmlAudioSound.', URL_INVALID: 'The url argument property was not provided to createHtmlAudioSound.', }; export const createHtmlAudioSound = ( options: ICreateSoundOptions, preloadDirective: keyof GlobalEventHandlersEventMap = 'canplay', ): Promise<ISound> => { const { fade, getManagerVolume: getManagerVol, loop, trackPosition, url, volume, } = assertValid<ICreateSoundOptions>( options, strings.OPTIONS_INVALID, ); const safeUrl = assertValid<string>( url, strings.URL_INVALID, ); const audioElement = new Audio(safeUrl); audioElement.preload = preloadDirective === 'canplay' ? 'auto' : 'metadata'; const getManagerVolume = assertValid<() => number>( getManagerVol, strings.GET_MANAGER_VOLUME_INVALID, ); const sound = new Sound( getFrozenObject({ ...options, audioElement, fade, getManagerVolume, loop, trackPosition, volume, }), ); const playthroughListener = (resolver: (sound: ISound) => void) => { resolver(sound); }; const errorListener = (rejector: (err: Error) => void, { error }: ErrorEvent) => { rejector(error); }; return new Promise((resolve, reject) => { const boundPlayListener = playthroughListener.bind(null, resolve); const boundErrListener = errorListener.bind(null, reject); audioElement.addEventListener( preloadDirective, boundPlayListener, ); audioElement.addEventListener( 'error', boundErrListener, ); }); };