The Gizmix.org player loads a short low-weight preview first, then seamlessly switches to the full mix. This reduces waiting time, keeps the UI reactive, and gives listeners a “quick start” moment. Below is a simplified version of the flow, with explanations.
We begin by fetching a small preview MP3 using Fetch → Blob → Object URL. This keeps things fast and lets Wavesurfer load something immediately.
// Step 1 — Fetch preview audio
fetch("")
.then(res => res.blob())
.then(blob => {
const previewURL = URL.createObjectURL(blob);
wavesurfer.load(previewURL);
// Keep a reference
window.previewURL = previewURL;
});
We don’t wait for the preview to finish — the full file begins loading silently in the background. Wavesurfer handles the decoding.
wavesurfer.on("timeupdate", t => {
if (!window.fullRequested && t > 3) { // after some seconds
window.fullRequested = true;
fetch("")
.then(r => r.blob())
.then(blob => {
const fullURL = URL.createObjectURL(blob);
window.fullURL = fullURL;
});
}
});
As soon as the short preview ends, we load the full mix using the pre-created URL. This avoids “double decoding” delays and gives a smooth transition.
wavesurfer.on("finish", () => {
if (window.fullURL) {
const lastTime = wavesurfer.getDuration();
wavesurfer.load(window.fullURL);
// Resume at an equivalent position — optional puzzle:
// try mapping preview time to full time differently!
}
});
A tiny aesthetic touch: we reduce volume temporarily and fade it back.
wavesurfer.setVolume(0.1);
setTimeout(() => wavesurfer.setVolume(1.0), 900);
Want to experiment? Try swapping the transition trigger from "finish"
to "audioprocess" and create an overlap blend. The code above is ready
for modification — dive in!