Jack Pope
Jack Pope

Reputation: 33

How do I load an audio source from memory?

I currently have some logic that sends some text to the backend and I get back an audio file representing the speech for that text. The URL is set as the 'src' attribute of the 'audio' element.

The specified endpoint is slow (~3s), so I want to make an HTTP call that fetches the audio data and keep it in memory for a few seconds so that I can use it as the source of the audio element. The audio files can have a size between 300KB and 5MB.

What APIs can I use to store the audio data and how can I then provide that data to the audio element?

Thank you in advance!

Upvotes: 1

Views: 1637

Answers (1)

apsillers
apsillers

Reputation: 115910

For starters, you could probably just use the URL as the src as you do now, but simply wait to play it until the audio is finished loading. However, some environments will not load <audio> sources until the user initiates playing of the audio, so this won't work universally.

Your proposed idea is a good approach. Specifically, you'll want to:

  1. Use fetch or XMLHttpRequest to fetch the audio data
  2. After the load is compelte, place the data in a Blob object
  3. use URL.createObjectURL to create a URL from the Blob
  4. use that URL as the src attribute on your <audio>

One implementation this would look like

fetch("someaudio.ogg")
  .then(response=>response.blob())
  .then(blob=>myAudioElem.src = URL.createObjectURL(blob))

Or with XHR:

var xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.open("GET", "someaudio.ogg");
xhr.send();
xhr.addEventListener("load", function() {
    myAudioElem.src = URL.createObjectURL(xhr.response);
});

Once the fetch completes, myAudioElem will be ready with a fully-loaded blob-URL as its src attribute. Play should happen immediately, since the network fetch has already been done and the blob URL references locally-cached data.

Upvotes: 4

Related Questions