I made a webpage for Thai alphabet learning and I want to voice over letters and sounds. Clicking on these tiles plays a really short mp3 file and there is about 200 things to click and listen which is 1mb in total.
I have difficulties:
To play audio I tried something like this:
const audio = new Audio('path/to/audio.mp3');
audio.play();
...
And to let browser cache files I tried to address each one like so:
playlist.forEach(function(item) {
fetch('path/to/audio.mp3');
...
});
But this is just a draft. What will be the best approach to code it? Where do I look to improve it? Can I create an mp3 sprite? Or could it be <audio>
tag with inlined base64 with preload attribute? Or maybe I could try <link rel="preload">
for some kind of mp3 sprite? Can I rely on browser's cache or I should try JavaScript library to control all the media manually? Will it works without delay if I store these files in local storage?
My current solution is to create some sort of a sprite as a JS collection where data is encoded as base64 strings:
const playlist = new Map([
['consonant-bo-baimai', 'SUQzAw...AAAAAAKl'],
['consonant-cho-chang', 'AMVRJV...DIAAAAUA'],
['consonant-cho-ching', 'AUAAAA...Y29uYW50'],
]);
Store it in the separated file away from main page and link it at the end of the page. Then I play audio using a single audio container, like so:
let voiceover = new Audio();
$('[data-audio]').on('click', function (event) {
voiceover.src = 'data:audio/mpeg;base64,' + playlist.get($(this).data('audio'));
voiceover.play();
});
In this case performance and downloading data seem okey.
What didn't work:
<audio>
tags on the pages with encoded base64 files into them. Desktop Safari and mobile browsers were freezing processing 200 of them.<audio>
tags with direct path to mp3 files and preload attribute. Desktop Safari wasn't really preloading files. There was an http code saying "partially loaded". And mobile browsers were freezing again..fetch()
done in JavaScript hoping browsers will cache it. Running 200 fetches was freezing page in Safari again.