Java Script -All Audio Plays at Once When Attempting to Play Audio One by One in a Sequence (Through a for Loop)

Why are all the sounds playing at once instead of playing one at a time?

You can create a promise and start the next sound when the previous one resolves.

const audios = [
'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3',
'https://dl.dropboxusercontent.com/s/h2j6vm17r07jf03/snare.mp3',
'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3',
'https://dl.dropboxusercontent.com/s/h2j6vm17r07jf03/snare.mp3'
];

async function playSounds(arr) {
for (let i = 0; i < arr.length; i++) {
await new Promise((resolve) => {
sound = new Audio(arr[i]);
sound.onended = resolve;
sound.play();
});
}
}
<button onclick="playSounds(audios);">play</button>

How to loop through multiple audio files and play them sequentially using javascript?

You shouldn't use setTimeout inside a loop , it acts differently all other programming languages. Your solution should be something like this.
In previous code your variable inx only run for the last item.

$(document).on('click', ' .audioImg', function () {    var ParentID = '#' + $(this).parents('.parent').attr('id');    audioFileName = 'audio/' + $(this).attr('id') + '.mp3';    var audioElmnt = {};    var audioFileName1 = {};
$(PID + ' .item').each(function (inx, i) { if (inx >= 1) { audioElmnt[inx - 1].pause(); audioElmnt[inx - 1].currentTime = 0; }
audioElmnt[inx] = document.createElement('audio'); audioElmnt[inx].setAttribute('autoplay', 'false'); audioFileName1[inx] = 'audio/' + $(this).children('h2').attr('id') + '.mp3'; audioElmnt[inx].setAttribute('src', audioFileName1[inx]);
audioElmnt[inx].load();
//in previous code your inx only run for the last item. playAudio(audioElmnt[inx], 150); // here the object will be sent to the function and will be used inside the timer.
}); var playAudio = function(audioElmnt, delay){ setTimeout(function () { audioElmnt.play(); }, delay); } setTimeout(function () { audioElement.currentTime = 0; audioElement.pause(); audioElement.setAttribute('src', audioFileName); audioElement.load(); audioElement.play(); }, 500);});

Play sounds one after another with loop

There can also be a solution without mutation of 'order' array, for example using Symbol.iterator called for each ended event:

var a1 = new Audio('http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg'); a1.id = "1"; // id helps to see console.log is finevar a2 = new Audio('http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg'); a2.id = "2";var a3 = new Audio('http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg'); a3.id = "3";var a4 = new Audio('http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg'); a4.id = "4";
var order = [2, 1, 4, 3, 2, 1];
rotateAudio(order); // main function; pass order array here
function rotateAudio(order) { var orderMap = {1: a1, 2: a2, 3: a3, 4: a4}; var iterator = order[Symbol.iterator](); var value, done; function rotate({value, done}) { // get next iteration function next(e) { e.target.removeEventListener('ended', next); // helps for garbage removal I guess rotate(iterator.next()) }; if (done) { console.log('done!'); return }; var current = orderMap[value]; console.log('current: ', current); current.play(); current.addEventListener('ended', next) // listen to 'ended' on audio, start next one } rotate(iterator.next()); // first call}

Set interval play audio only loop audio once?

I think that you're trying to do that. Store in a variable, the "last sound" reproduced and only plays a new one when it has changed. The listener over "ended" event is unnecessary because you only play once per change.

var swoosh = document.getElementById("swoosh");
var lastPlay = "00";

setInterval(function () {
var cValue = $('.c').text();
if (lastPlay != "01" && cValue.indexOf("01") >= 0) {
$(".links #abt").attr("href", "about.html");
swoosh.play();
lastPlay = "01";
}
else if (lastPlay != "02" && cValue.indexOf("02") >= 0) {
$(".links #work").attr("href", "work.html");
swoosh.play();
lastPlay = "02";
}
}, 10);

Other better way was to add a listener to the change event of the ".c" element, it avoids the "query" every 10ms. But I don't have enough code to show you.

Playing array of audio in sequence not working even if I have ended function

The first error is in this line:

audioElement.addEventListener("ended", playAudio(playList));

Here the function playAudio() is called and the result from it (undefined in this case) is handed to the addEventListener() as argument, which of course won't work. If the playList is global simply change it to:

audioElement.addEventListener("ended", playAudio);  // function is now referenced

In addition, the handler is called every time the play button is clicked. Only add it once when the element is created.

There is also an error in the setTimeout() call, as shown in the post, as it misses a time argument and contains invalid statements inside the function block.

However, it shouldn't be necessary to use this call as calling play() on the element will, in newer browsers, cue up the call. For older browsers you may need to use the canplay event. setTimeout() is not recommended here in either case.

You should also call load() before play() to reset and cleanup the element, and to start loading the new source.

And finally, if the intention is to play the list in a loop the list will fail when last track has been played as i is reset in a separate else-block which does not invoke play.

You might want to consider how the play button behaves in order to prevent it from loading samples while playing (ie. toggle pause/play). I wrapped up the fixes above except from the play-button (I rewired it to share the playAudio() function) here using random short samples:

var playList = [{  "duration": 1000,  "value": "http://sampleswap.org/samples-ghost/SFX%20and%20UNUSUAL%20SOUNDS/ELECTRO%20and%20SYNTHETIC/257[kb]50s_space_telemetry.aif.mp3"}, {  "duration": 4000,  "value": "http://sampleswap.org/samples-ghost/SFX%20and%20UNUSUAL%20SOUNDS/ELECTRO%20and%20SYNTHETIC/85[kb]analog_alarm_up.aif.mp3"}, {  "duration": 6000,  "value": "http://sampleswap.org/samples-ghost/SFX%20and%20UNUSUAL%20SOUNDS/ELECTRO%20and%20SYNTHETIC/42[kb]alien_alarm.aif.mp3"}];
$(document).ready(function() { var audioElement = document.createElement('audio'); // reference function instead of calling it. Also, only set it once. audioElement.addEventListener("ended", playAudio); var i = 0; $("#play").on("click", playAudio); // rewired to share playAudio() function playAudio() { var entry = playList[i++]; // get current entry, increment i if (i >= playList.length) i = 0; // if i=> length, reset
audioElement.src = entry.value; // <- for demo samples only. 'sound/' + entry.value + '.wav'; audioElement.load(); // cleanup old fun, invoke loading of new audioElement.play(); // cue up play }});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><button id=play>Play</button>

play multiple sounds simultaneously in javascript

You can use the Audio constructor

const music = new Audio('myPathTo/music.mp3')
const soundEffects = new Audio('myPathTo/effects.mp3')

and then

music.play()
soundEffects.play()


Related Topics



Leave a reply



Submit