I need to play some sounds in howler.js the thing is that I don't know how to chain it.
For example, at string BCG
would need to play b.ogg then c.ogg and finally g.ogg
If I just use (after loading):
sound.play('b');
sound.play('c');
sound.play('g');
All of them start and overlap which isn't what I need.
I see there's a onend property, however can't figure out how to use it properly.
Regards.
I need to play some sounds in howler.js the thing is that I don't know how to chain it.
For example, at string BCG
would need to play b.ogg then c.ogg and finally g.ogg
If I just use (after loading):
sound.play('b');
sound.play('c');
sound.play('g');
All of them start and overlap which isn't what I need.
I see there's a onend property, however can't figure out how to use it properly.
Regards.
Share Improve this question edited Sep 29, 2014 at 19:10 James Simpson 13.7k26 gold badges85 silver badges111 bronze badges asked Sep 29, 2014 at 17:25 Javier SJavier S 1151 gold badge2 silver badges13 bronze badges4 Answers
Reset to default 7Here is my simple solution, I am using tiny files so download delay is not an issue. sound is global in this case
function play_audio(file_names) {
sound = new Howl({
src: [audio_url+file_names[0]],
volume: 0.5,
onend: function() {
file_names.shift();
if (file_names.length > 0) {
play_audio(file_names);
}
}
});
sound.play();
}
You could use this code whic doesn't require sprites (jsfiddle, Github issue) :
var playlist = function(e) {
// initialisation:
pCount = 0;
playlistUrls = [
"https://upload.wikimedia.org/wikipedia/commons/8/8a/Zh-Beijing.ogg",
"https://upload.wikimedia.org/wikipedia/commons/8/8a/Zh-Beijing.ogg",
"./audio/a.mp3",
"./audio/b.mp3",
"./audio/c.mp3",
"./audio/d.mp3"
], // audio list
howlerBank = [],
loop = true;
// playing i+1 audio (= chaining audio files)
var onEnd = function(e) {
if (loop === true ) { pCount = (pCount + 1 !== howlerBank.length)? pCount + 1 : 0; }
else { pCount = pCount + 1; }
howlerBank[pCount].play();
};
// build up howlerBank:
playlistUrls.forEach(function(current, i) {
howlerBank.push(new Howl({ urls: [playlistUrls[i]], onend: onEnd, buffer: true }))
});
// initiate the whole :
howlerBank[0].play();
}
Please share back your variation if you do one.
You could create a function playString(yourString)
that will read each character and dynamically set the onend
property of your sound. The following example should play B C G A C:
var sound = new Howl({
urls: ['http://shrt.tf/abcdefg.mp3'],
volume: 1,
sprite: {
a: [0, 600],
b: [700, 500],
c: [1200, 600],
d: [1900, 500],
e: [2400, 500],
f: [2900, 500],
g: [3400, 500],
}
});
Howl.prototype.playString = function(str){
if(str.length>1){
this._onend[0] = function(){this.playString(str.substring(1,str.length));};
} else {
this._onend[0] = function(){};
}
if(str.length>0){
this.play(str.substring(0,1));
}
};
sound.playString('bcgac');
<script src="http://shrt.tf/howler.js"></script>
Note that you could also tweak this function to work when a character is not in the sprite, or to use an array of names instead of a string.
Simple solution to chain audio one after another. Code also does not create a new instance of Howl for every audio file in the list. I use audio sprites here.
const playSounds = (_audioList) => {
let sound = new Howl({
src: ["/effects/effects.webm", "/effects/effects.mp3"],
sprite: {
a: [5000, 3648.004535147393],
b: [14000, 2832.0181405895682],
c: [57000, 2712.0181405895705],
},
});
sound.play(_audioList.shift());
sound.on("end", () => {
_audioList.length > 0 && sound.play(_audioList.shift());
});
playSounds(["a", "b", "c"];