I’m attempting to make a game, and in it I have music (like most games). However, changing the track or even looping the same one tends to come with a very slight delay. I want to remove that using pure vanilla Javascript.
I tried this:
// Sets an object with music URLs
const mus = {
'Surface': "https://codeberg.org/NerdB0I/dungeoncrawlerost/raw/branch/main/mus/Surface.wav",
'Deeper': "https://codeberg.org/NerdB0I/dungeoncrawlerost/raw/branch/main/mus/Deeper.wav"
}
// This ensures that music will play and wait for each other using Promises
function musPlay(name='') {
return new Promise(resolve => {
let audio = new Audio(mus[name]);
audio.onended = () => resolve();
audio.play();
});
}
// This runs once everytime the song ends and plays a new song based on the variable currSong
let currSong = 'Surface';
async function run() {
await musPlay(currSong);
run();
}
run();
// This allows you to press keys to change the song (and to see what key pressed)
// I do not mind that the song continues playing after keydown, I just need it to set the currSong variable for when the files end
window.addEventListener('keydown', (event) => {
if (event.key == 'a') {
currSong = 'Surface';
} else if (event.key == 'd') {
currSong = 'Deeper';
}
document.getElementById('body').innerHTML = event.key;
});
My Liveweave
If this is just a problem of Liveweave and not code, please let me know.
2
Answers
Creating a new audio element each time you play a new audio file will make a pause, because the audio is not loaded. Start the script by loading all the audio files, and then use the same audio element instead of creating ones each time.
While I agree with with @chrwahl about pre-loading and not creating a new Audio every time, it’s not the only cause of the gap. As there is still an amount of time between the
ended
event and the starting of the playback, the gap remainsEasiest is to set
.loop = true
on the audio, until a different track is required, then set.loop = false
, theended
will fire when the end is reached, and a new audio track can be startedYou’ll note this code does not "preload" the audio, yet there is no stutter, because the audio is loaded only when changed
Depending on how much audio you have, I would probably still "pre load" the audio, but that’s not important to the issue you have.