Search code examples
javascripthtmlreactjsbase64

How to convert base64 mp3 coming from backend to playable audio on browser in Javascript/ React?


I am trying to get .mp3 file from backend and displaying playable audio. So backend is converting .mp3 file to base64 and sending me. Tried to send .mp3 directly, but it doesn't work.

I am getting a mp3 converted to base64 from backend like this

axios
        .post(`abcEndPoint`, {
          text: textValue
        })
        .then((res) => {
         
          setAudio(res.data)
          console.log(res.data)
        });

The res.data is as follows

enter image description here

Now I am converting this base64 response to audio tag readable Url with function.

function base64ToImageUrl(base64String) {
  return `data:audio/mpeg;base64,${base64String}`;
}

I have tried to change format to audio/wav, .mp3 , audio/mp3

And lastly, here is my jsx for audio

<>
                  <audio controls>
                    <source src={base64ToImageUrl(audio)} />
                    Your browser does not support the audio element.
                  </audio>
                </>

What is that I'm doing wrong, or is it even doable in react/JavaScript


Solution

  • testing your live endpoint, i can see that you're returning binary data (RIFF audio format), so you're not using base64 (maybe just internally..., idk).

    based on that, probably you're trying to play some audio downloaded from your API. check the solution on this answer, but instead of creating an <a> tag, it will be a <source> tag (inside <audio>).

    example:

    axios
      .post('http://localhost:8080/tts',
        { text: textValue }, // data
        { responseType: 'blob' }, // config options
      )
      .then((response) => {
        // create file link in browser's memory
        const audioObjectUrl = URL.createObjectURL(response.data);
        setAudio(audioObjectUrl);
      });
    

    when you're done using it, remember to revoke with URL.revokeObjectURL(audio);:

    React.useEffect(() => {
      // note that the return function of useEffect is the cleanup function
      return () => URL.revokeObjectURL(audio);
    }, [])
    

    finally, remove calls to base64ToImageUrl:

    <>
      <audio controls>
        <source src={audio} />
        Your browser does not support the audio element.
      </audio>
    </>