javascripthtmlhtml5-audiocreateobjecturl

Setting audio element source from blob


I have an audio control on my page that looks something like:

<audio id="myAudio" controls>
    <source id="myAudioSource" src="https://my-site/mp3/123456" type="audio/mp3">
</audio>

This works and the mp3 gets loaded and played. However I need more control over the mp3 request so I have some javascript that fetches the mp3 and then tries to set the source that looks something like:

fetch("https://my-site/mp3/123456", { method: "GET", headers: { "my-header": "my-header-value" }})
    .then(response => response.blob())
    .then(blob => {
        const audioUrl = window.URL.createObjectURL(blob);
        myAudioSource.src = audioUrl;
        myAudio[0].load();
     })
     .catch(console.error);

I've seen examples of people doing this elsewhere so I believe it should work. I'm not getting any errors and I can step through the code so I can see every line being hit. The blob looks correct in that it's got the correct type (audio/mp3) and it's the right size but the audio control never becomes playable. What am I missing?


Solution

  • Given https://my-site/mp3/123456 resolves to an actual MP3 file. Also (since it's your server) why not use a relative path: /mp3/

    <audio id="myAudio" controls></audio>
    
    <script>
    const EL_audio = document.querySelector("#myAudio");
    fetch("/mp3/123456")
        .then(response => response.blob())
        .then(blob => {
            EL_audio.src = URL.createObjectURL(blob);
            EL_audio.load();
         })
         .catch(console.error);
    </script>