Play MP3 file stored as blob

29,333

Solution 1

This seems to work fine for me, although I'm using audio/mpeg as the MIME Type:

$scope.player = new window.Audio();

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        $scope.player.src = window.URL.createObjectURL(this.response);
        $scope.player.play();
    }
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();

Solution 2

I realize this question has been answered already and that my findings are for a different browser (Chrome), but I thought I'd leave this here just in case someone in the future is having the same problem I did. I was having trouble playing a blob file through the audio player, but found that removing the source tag fixed things. So this wouldn't work:

<audio controls="controls">
    <source src="[blobURL]" type="audio/mp3">
</audio>

But this worked fine:

<audio controls="controls" src="[blobURL]" type="audio/mp3" />

I'm not sure why one would work and the other would not, but there it is. Hopefully this is useful to someone else down the line.

Solution 3

Had a similar challenge trying to play uploaded mp3s in React. Was able to get it working based on the previously provided XHR solution here, but then adapted it to work with React refs:

import {useState, useRef, useEffect} from 'react'

function FileUploadPage(){
  const [selectedFile, setSelectedFile] = useState();
  const [isFilePicked, setIsFilePicked] = useState(false);
  const myRef = useRef(null)

  const changeHandler = (event) => {
    setSelectedFile(event.target.files[0]);
    setIsFilePicked(true);
  };

  const playAudio = () => {
    myRef.current.src = window.URL.createObjectURL(selectedFile)
    myRef.current.play()
  }

  return(
    <div>
      <input type="file" name="file" onChange={changeHandler} />
        {isFilePicked ? (
          <div>
                <p>Filename: {selectedFile.name}</p>
                <p>Filetype: {selectedFile.type}</p>
                <p>Size in bytes: {selectedFile.size}</p>
                <p>
                    lastModifiedDate:{' '}
                    {selectedFile.lastModifiedDate.toLocaleDateString()}
                </p>
                <div>
                <button onClick={playAudio}>
                    <span>Play Audio</span>
                </button>
                <audio ref={myRef} id="audio-element" src="" type="audio/mp3" />
            </div>
            </div>
        ) : (
            <p>Select a file to show details</p>
        )}
    </div>
)

}

Share:
29,333
Axel
Author by

Axel

Updated on February 07, 2021

Comments

  • Axel
    Axel over 3 years

    Put simply, I'd like to play a blob MP3 file in Firefox.

    I have access to both the blob itself: blob (sliced with mime type audio/mpeg3), and its URL: blobURL = window.URL.createObjectURL(blob).

    I have tried with:

    1. an HTML5 audio player:

      <audio controls="controls">
          <source src="[blobURL]" type="audio/mp3">
      </audio>
      

      but I get a warning in Firebug telling me that Firefox cannot read files of type audio/mpeg3.

    2. multiple audio player libraries (SoundManager, JPlayer, etc.), but none seem to allow blob URLs as input.

    Am I doing it wrong? Or does anyone know a workaround or a library that can play MP3 files from blobs?

    • Axel
      Axel over 11 years
      Thanks. Do you know of any existing audio player that would be based on either of your solutions?
    • Tjorriemorrie
      Tjorriemorrie over 11 years
      What was the solution?
    • Scott
      Scott over 10 years
      It's 2014... Who were you, DenverCoder9!? xkcd.com/979
    • Axel
      Axel over 10 years
      This was quite a long time ago! Fortunately, Firefox can now play MP3 files by relying on the OS's MP3 decoder. I haven't tested it again since then, but I assume providing the blob URL in the src attribute of the HTML5 source element now works perfectly (at least on Windows 7).
  • Axel
    Axel over 10 years
    This is pretty much the same as using the HTML5 audio player and passing it the blob's URL. So it still relies on the browser/OS combination supporting MP3s.
  • Axel
    Axel over 10 years
    Nice and clean Vanilla JavaScript, though! Anyway, thanks to Firefox 24, I guess my question is not really relevant any more.
  • Jan Míšek
    Jan Míšek almost 9 years
    Thank you for this nice solution, there is small mistake in code. response => this.response
  • Allen Rufolo
    Allen Rufolo almost 4 years
    Definitely helped me! Was pulling may hair trying to figure out why source wouldnt work after converting to using blobs (for auth purposes). Tried switching to this format and it solved my issue!