'How to pre-download items from a JSON list array in React JS?
Here the Codesandbox example.
I have a list array of songs:
const tracks = [
{
name: "Sunny",
src: "https://www.bensound.com/bensound-music/bensound-sunny.mp3"
},
...
From that list I would like to know how to start download automatically in background the next song (not all the list, only the next) once the current has been completely downloaded.
Why?
Because it is the user's intention to listen to the next song in a selected playlist (We are talking about small files of less than 10MB).
My question is very similar to this one excepted for I'm in React JS and I'm using react-h5-audio-player.
Solution 1:[1]
You can do it in two ways,
Try the following code snippets to preload the audio in your app.
const tracks = [
{
name: "Sunny",
src: "https://www.bensound.com/bensound-music/bensound-sunny.mp3"
},
{
name: "Sunny2",
src: "https://www.bensound.com/bensound-music/bensound-sunny2.mp3"
},
{
name: "Sunny3",
src: "https://www.bensound.com/bensound-music/bensound-sunny3.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 = tracks[index].src;
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 >= tracks.length) {
// end
return;
}
play(i);
};
// play the first file
play(i);
}
// we start preloading all the audio files
for (var i in tracks) {
preloadAudio(tracks[i].src);
}
<audio id="player"></audio>
If you would like to embed your audio clips into a webpage, you can use the preload attribute to load the audio on the web page load:
<audio src="audioclip.mp3" controls autoplay preload >
<p>This web browser does not support mp3 format</p>
</audio>
Solution 2:[2]
You can insert <link rel="prefetch"> elements into the <head> of the page. This will tell the browser to go ahead and download the thing that it finds in the src property of that element so that it can be served from the cache if something else on the page (in this case, the audio player) requests it in the future (see docs).
Here's some code that should work:
const alreadyPreloaded = new Set();
export function preloadTrack({ src } = {}) {
// We make sure not to insert duplicate <link rel="prefetch> elements
// in case this function gets called multiple times with the same track.
if (typeof src === "string" && !alreadyPreloaded.has(src)) {
const head = document.getElementsByTagName("HEAD")[0];
const link = document.createElement("link");
link.rel = "prefetch";
link.href = src;
head.appendChild(link);
alreadyPreloaded.add(src);
}
}
Then, in your react component, you could call preloadTrack as a side-effect of when the track changes:
useEffect(() => {
preloadTrack(tracks[trackIndex]); // Also preload the current track
preloadTrack(tracks[trackIndex + 1]); // tracks[trackIndex + 1] might be undefined, but we wrote the preloadTracks function to safely handle that.
}, [trackIndex]);
See this fork of your codesandbox
You can see that it's working by checking the "network" tab in debug tools. This is what I see on a fresh page reload after clearing the cache, and before clicking on anything.
Another way to be sure that it is working, is to hit the "next" button once - you should see that track #2 (bensoud-tenderness.mp3) is being served from the cache with a 206 status code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Codemaker |
| Solution 2 |


