Preload Multiple Audio Files

Preload multiple audio files

var audioFiles = [

"http://www.teanglann.ie/CanC/nua.mp3",

"http://www.teanglann.ie/CanC/ag.mp3",

"http://www.teanglann.ie/CanC/dul.mp3",

"http://www.teanglann.ie/CanC/freisin.mp3"

];



function preloadAudio(url) {

var audio = new Audio();

// once this file loads, it will call loadedAudio()

// the file will be kept by the browser as cache

audio.addEventListener('canplaythrough', loadedAudio, false);

audio.src = url;

}



var loaded = 0;

function loadedAudio() {

// this will be called every time an audio file is loaded

// we keep track of the loaded files vs the requested files

loaded++;

if (loaded == audioFiles.length){

// all have loaded

init();

}

}



var player = document.getElementById('player');

function play(index) {

player.src = audioFiles[index];

player.play();

}



function init() {

// do your stuff here, audio has been loaded

// for example, play all files one after the other

var i = 0;

// once the player ends, play the next one

player.onended = function() {

i++;

if (i >= audioFiles.length) {

// end

return;

}

play(i);

};

// play the first file

play(i);

}



// we start preloading all the audio files

for (var i in audioFiles) {

preloadAudio(audioFiles[i]);

}
<audio id="player"></audio>

Can I preload audio files in javascript/html and play it also after network loss?

I think as long as you don't change audio.src after the connection's lost you should be OK. So you'll need one audio element for each file you want to preload. Perhaps:

var audioPlayers = audioFiles.map( file => {
var audio = new Audio();
audio.src = file;
return audio;
})

Preload multiple (798) audio files in Chrome

This isn't really a code problem. It's a general architecture problem.

Depending not only on the number, but also the size of the samples, it's going to be unlikely you can get them all loaded at once. Even if you can, it'll run very poorly because of the high memory use and likely crash the tab after a certain amount of time.

Since it's offline, I would say you could even get away with not pre-loading them at all, since the read speed is going to be nearly instantaneous.

If you find that isn't suitable, or you may need like 5 at once and it might be too slow, I'd say you'll need to architect your game in a way that you can determine which sounds you'll need for a certain game state, and just load those (and remove references to ones you don't need so they can be garbage collected).

This is exactly what all games do when they show you a loading screen, and for the same reasons.

If you want to avoid "loading screens", you can get clever by working out a way to know what is coming up and load it just ahead of time.

Most sensible way of preloading a batch of audio files

You can use fetch() and Promise.all() with .map() or a for..of loop and Promise constructor to request the media resources as Blob or ArrayBuffer and render playback at a single <audio> node using MediaSource or simply setting src of <audio> node to next Blob representation of file by passing Blob to URL.createObjectURL() to create a Blob URL.

Use XMLHttpRequest to load multiple audio files and append them to play in Web Audio API

Well I figured out one solution myself. When I connected each buffer to the audioContext.destination, I can simply specify the time when the second audio play, which is the current time plus the duration of the first AudioBuffer.

Playing audio broken into multiple files in webpage

I'd take a look at this answer on another Stack Overflow question however I have made some modifications in order to match your question:

var audioFileURLs= [];

function preloadAudio(url) {
var audio = new Audio();
// once this file loads, it will call loadedAudio()
// the file will be kept by the browser as cache
audio.addEventListener('canplaythrough', loadedAudio, false);
audio.src = url;
}

var loaded = 0;
function loadedAudio() {
// this will be called every time an audio file is loaded
// we keep track of the loaded files vs the requested files
loaded++;
if (loaded == audioFileURLs.length){
// all have loaded
init();
}
}

var player = document.getElementById('player');
function play(index) {
player.src = audioFiles[index];
player.play();
}

function init() {
// do your stuff here, audio has been loaded
// for example, play all files one after the other
var i = 0;
// once the player ends, play the next one
player.onended = function() {
i++;
if (i >= audioFiles.length) {
// end
return;
}
play(i);
};
// play the first file
play(i);
}

// call node/express server to get a list of links we can hit to retrieve each audio file
fetch('/getAudioUrls/#BookNameOrIdHere#')
.then(r => r.json())
.then(arrayOfURLs => {
audioFileURLs = arrayOfURLs
arrayOfURLs.map(url => preloadAudio(URL))
})

And then just have an audio element on the screen with the id of "player" like <audio id="player"></audio>

With this answer though, the arrayOfURLs array must contain URLs to an API on your server that will open the zip file and return the specified mp3 data. You may also just want to take this answer as a general reference, and not a complete solution because there is optimization to be done. You should probably only load the first audio file at first, and 5 minutes or so before the first file ends you may want to start pre-loading the next and then repeat this process for the entire thing... That all will be up to you but this should hopefully put you on your feet.

You may also run into an issue with the audio element though because it will only show the length of the current audio segment it is on, and not the full length of the audiobook. I would choose to believe this zip file has the book separated by chapter correct? If so you could create a chapter selector, that pretty much allows you to jump to a specific chapter aka getAudioUrls URL.

I hope this helps!


One other note for you... reading your comment on a potential answer down below, you could combine all the audio files into one using some sort of node module (audioconcat is one I found after a quick google search) and return that one file to the client. However, I would not personally take this route because the entire audiobook will be in the server's memory while it combines them, and until it returns it to the client. This could cause some memory issues down the road, so I would avoid it if I could. However, I will admit that this option could be potentially nice because the full length of the audiobook will display in the audio elements timeline.


The best option perhaps is to store the books full length and chapter lengths in a details.json file in the zip file and send that to the client in the first API call along with the URLs to each audio file. This would enable you to build a nice UI.



Related Topics



Leave a reply



Submit