2
votes

I have been trying to build a site that plays audio files that are stored remotely (and are not publicly visible). The way that I have been playing audio is:

  1. Get the audio from server via XMLHttpRequest
  2. Store this audio in a blob
  3. Play the audio using Howler.js

I accomplish this with the following code:

//Get the audio file from the API 
var request = new XMLHttpRequest();
request.addEventListener("load", loadMusic);
request.responseType = "blob";
request.open("GET", root+"getmusic/"+path);
request.send();

//Function that catches the data, and plays the audio 
function loadMusic(data) {
    var objectUrl = window.URL.createObjectURL(data.currentTarget.response);
    var howler = new Howl({
         autoplay: true,
         src: [objectUrl],
         format: ["mp3"]
         });
    howler.play();
}

This works fine on my desktop browsers Chrome, Safari, and Firefox (audio plays). However, when open the page on my phone (iPhone 6s, iOS) in either iOS Safari, or the mobile version of Chrome, the audio does not play, and I don't get any errors in the development console to give me a clue as to why. What puzzles me most is why it works in my desktop browser and not in a mobile environment.

Is there any way to fix this? Or debugging routes I should pursue?

Some extra information:

  • The user needs to press a button to load/start the audio, so they do interact with the DOM first.
  • Audio files are in mp3 format.
1
Is the mute switch flipped on your phone?James Simpson

1 Answers

1
votes

So, I eventually resolved this issue as follows:

  • The audio wasn't playing on mobile devices primarily due to me not sending the correct response headers with the data.
  • I eventually abandoned Howler.js and just put the blob as the audio element source, e.g. <audio id="audioplayer" src=<blob url here set via javascript> controls type="audio/mpeg">

The Laravel backend that I was using needed to send the following headers with the audio file (raw data) as shown below:

        $data = Storage::get("audio/".$path);

        header('Content-Transfer-Encoding: binary');
        header('Content-Type: audio/mpeg, audio/x-mpeg, audio/x-mpeg-3, audio/mpeg3');
        header('Content-Length: ' . strlen($data));
        header('Content-Disposition: attachment; filename="somefile.mp3"');
        header('X-Pad: avoid browser bug');
        header('Cache-Control: no-cache');

        echo $data;