Skip to content

Instantly share code, notes, and snippets.

@emelent
Last active January 24, 2017 09:56
Show Gist options
  • Save emelent/a985d8da58d2afeb756c83570a59593a to your computer and use it in GitHub Desktop.
Save emelent/a985d8da58d2afeb756c83570a59593a to your computer and use it in GitHub Desktop.
///Singleton audio manager
class AudioManager{
constructor(){
this.sounds = {};
this.queue = [];
this.currentlyPlaying = null;
this.currentAudio = null;
this.paused = false;
}
//param object represents either a playlist or a single audio
__play(object){
let {playlist, delay, name, onEnded} = object;
delay = (delay)? delay: 0;
let audio = playlist[object.index++];
this.currentlyPlaying = object;
this.currentAudio = audio;
audio.onended = () => {
//current object done playing
if(playlist.length >= object.index){
//run onEnded callback when done playing object
if(onEnded)
onEnded();
//reset index so you can play it again later
object.index = 0;
this.play(); //play next enqueued sound
return ;
}
//play after delay
setTimeout(() => {
this.__play(object);
}, delay);
};
audio.play();
this.paused = false;
}
__getObject(data, onEnded){
let {name, delay, playlist} = data;
let obj;
if(this.sounds.hasOwnProperty(name)){
//fetch and update object
obj = this.sounds[name];
obj.delay = (delay)? delay: obj.delay;
obj.onEnded = (onEnded)? onEnded: obj.onEnded;
obj.playlist = (playlist)? playlist.map(src => new Audio(src)): obj.playlist;
} else{
//create new object
obj = {
name,
delay,
onEnded,
playlist: playlist.map(src => new Audio(src))
};
this.sounds[name] = obj;
}
return obj;
}
enqueue(data, onEnded=null){
if(typeof data === 'string'){
if(this.sounds.hasOwnProperty(data)){
this.queue.push(this.sounds[data]);
}else{
this.enqueue({
name: data,
delay: 0,
playlist: [data],
onEnded
});
}
return;
}
let obj = this.__getObject(data, onEnded);
this.queue.push(obj);
};
clearQueue(){
this.queue = [];
}
pause(){
this.paused = true;
this.currentAudio.pause();
}
play(data=null, onEnded = null){
if(data === null){
//play paused audio
if(this.paused && this.currentAudio)
this.currentAudio.play();
//play next enqueued object
else if(this.queue.length > 0){
let obj = this.queue[0];
this.queue = this.queue.slice(1);
this.__play(obj);
}
return;
}
this.stop(); //stop playing what's playing
this.clearQueue(); //clear queue
//play sound
if(typeof data === 'string'){
// if data is name of stored sound
if(this.sounds.hasOwnProperty(data)){
//replace onEnded
if(onEnded)
this.sounds[data].onEnded = onEnded;
this.__play(this.sounds[data]);
}else{
// if data is path to file
this.play({
name: data,
playlist: [data],
delay: 0,
}, onEnded);
}
return;
}
let obj = this.__getObject(data, onEnded);
this.enqueue(obj);
this.play();
}
stop(){
this.paused = false;
this.currentAudio.stop();
this.currentAudio = null;
this.currentlyPlaying.index = 0;
this.currentlyPlaying = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment