0

I am trying to play audio automatically based on condition when I get ajax response. I receive response.code == 1 from my ajax call, but it does not play the audio.

<audio id="myAudio" >
  <source src="{{asset('Dashboard/alarm.mp3')}}" type="audio/mpeg">
</audio> 
$.ajax({
  url: '{{url('/')}}',
  type: 'POST',
  data: {
    _token: _token
  },
  dataType: 'json',
  success: function(response) {
    if (response.code == 1) {
      playAudio();
    }
  }
});

function playAudio() {
  var x = document.getElementById("myAudio");
  x.play();
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Mithun
  • 255
  • 1
  • 7
  • 17
  • is the path to the music file correct? – s.kuznetsov Jul 28 '20 at 18:14
  • Assuming the path to the file is correct, what happens when you add `console.log('playing')` to your PlayAudio function? Do you see `playing` in the console? – imvain2 Jul 28 '20 at 18:16
  • it says **Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first** – Mithun Jul 28 '20 at 18:17
  • path is correct. If I use button and onclick event then it works – Mithun Jul 28 '20 at 18:18
  • 1
    Ok, so the problem is the browser requires the user to do something with the page before it will allow audio to be played. One solution that might work is using this answer: https://stackoverflow.com/a/54379573/3684265 triggering the play via `mousemove` event listener – imvain2 Jul 28 '20 at 18:23
  • add `x.load();` before `x.play();` – s.kuznetsov Jul 28 '20 at 18:32
  • Still not working – Mithun Jul 28 '20 at 18:38

2 Answers2

0

Browsers are often blocking sounds that are not triggered by user interaction, you can start playing the audio on the mouse move for example:

let isAjaxLoaded = false;

$(document).mousemove(function(){
  if (isAjaxLoaded) {
    playAudio();
  }
});

$.ajax({
  url: '{{url('/')}}',
  type: 'POST',
  data: {
    _token: _token
  },
  dataType: 'json',
  success: function(response) {
    if (response.code == 1) {
      isAjaxLoaded = true;
    }
  }
});

function playAudio() {
  var x = document.getElementById("myAudio");
  x.play();
}
Michael
  • 1,058
  • 10
  • 17
  • 1
    Still show Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first – Mithun Jul 28 '20 at 18:36
0

As @imvain2 mention is the comment, browsers won't allow to play the audio before user interaction. There is no way to hack this. This is to prevent page from annoying users. So to achieve this, we have to wait until user interaction. User clicks can be treated as user interaction. So add a event lister to window and implement your code there.

$.ajax({
  url: '{{url('/')}}',
  type: 'POST',
  data: {
    _token: _token
  },
  dataType: 'json',
  success: function(response) {
    if (response.code == 1) {
      window.addEventListener('click', ()=> {
          playAudio();
      })
    }
  }
});

function playAudio() {
  var x = document.getElementById("myAudio");
  x.play();
}

Not that, audio will play only after user clicks anywhere in the window.

Pranavan
  • 1,287
  • 1
  • 6
  • 18