Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 audio player in Firefox is not working

HTML5 audio player in Firefox 53.0.2 (64-bit) is not playing audio file with bitrate 23 kbps but it is working fine in chrome.

download file here:https://www.sendspace.com/file/qf23ca

Audio file details :

codec: MPEG-1 Layer 3 (MP3)
channels : mono
container: wav
Bitrate: 23 kbps
sample rate: 22050 Hz

Thanks.

like image 875
harry Avatar asked Nov 15 '25 00:11

harry


1 Answers

This is a really weird bug :

Firefox is able to read this file, but only if the document points directly to it...

You should definitely report this to BugZilla.

For a workaround, you can use an <embed>, <iframe> or <object> directly pointing to this file :

document.querySelector('button').onclick = e => 
document.querySelectorAll('object,iframe,embed,audio')
.forEach(e=>{
e.src = e.data = "https://dl.dropboxusercontent.com/s/v4laq04yl1gmcef/592d0d0d65fb320c776ac305.mp3?dl=0";
if(e.play)e.play()
});
object,iframe,embed,audio{
  display: block;
  height: 50px;
  border: 1px solid;
  }
<button>Set srcs</button><br>

<p>Audio fails<audio controls></audio> </p>
<p>embeddeds work
<object data=""></object>
<iframe src=""></iframe>
<embed src="">
</p>

[edit]

Here is an ugly workaround implementation that will enable to have the <audio> element inside the main document, still playing.

NOTE : This hack will work only with same-origin data, or cross-origin accessible ones.

// we've got a problem, probably FF
function uglyFFworkaround() {
  const frame = document.createElement('iframe'); // create an iframe

  frame.onload = e => {
    const doc = frame.contentDocument;
    // grab the mediaElement (usually an <video>)
    const inner_aud = doc.querySelectorAll('audio,video')[0];
    var new_aud = doc.createElement('audio'); // create an new audio from our frame's document
    new_aud.src = inner_aud.currentSrc; // set its src to the one of the default video
    inner_aud.pause(); // pause the video
    new_aud.controls = true;
    frame.replaceWith(new_aud); // replace the frame with the audio element
    aud = new_aud; // update our variable to point to this new audio
    aud.play(); // start playing
  };

  // in case our document is not on the same origin as the media
  fetch(aud.src) // fetch the resource
    .then(r => r.blob()) // as a blob
    .then(b => { // so that we can access the frame's document
      // ( if it were on the same origin, we could avoid this fetch altogether )
      frame.src = URL.createObjectURL(b);
      aud.replaceWith(frame);
    });
}

And you can call it either from play().catch(), or from the onerror event.

Live Fiddle since stacksnippet's don't allow accessing nested iframe's docs :

like image 165
Kaiido Avatar answered Nov 17 '25 22:11

Kaiido