I am making a game with HTML5 and JavaScript.
How could I play game audio via JavaScript?
If you are getting the following error:
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
That means the user needs to interact with the website first (as the error message says). In this case you need to use click
or just another event listener, so the user can interact with your website.
If you want to auto load the audio and don't want the user to interact with the document first, you could use setTimeout
.
setTimeout(() => {
document.getElementById('mySound').play();
}, 500)
<audio id="mySound" src="sound.mp3"></audio>
The sound will start after 0.5 second.
If you want to be able to play the sound even when the browser-tab is currently not selected, you have to load the audio-resource on page load.
Like so:
var audio = new Audio('audio/path.mp3');
function playSound(){
audio.play();
}
See this question for more detail
Pretty simple solution if you have an HTML tag like below:
<audio id="myAudio" src="some_audio.mp3"></audio>
Just use JavaScript to play it, like so:
document.getElementById('myAudio').play();
Here is a solution for the year 2020 when you are seeing the error:
[Error] Unhandled Promise Rejection: NotSupportedError: The operation is not supported. (anonymous function) rejectPromise play (anonymous function) (testaudio.html:96) dispatch (jquery-3.4.1.min.js:2:42577)
<div onclick="new Audio('/assets/test.mp3').play()">aaa</div>
Don't be slick and think ooh that's an old school oclick
, I'll just move that down the page to my jQuery or my external JavaScript file. Nope. It needs to be an onclick
.
Add a hidden audio and play it.
function playSound(url){
var audio = document.createElement('audio');
audio.style.display = "none";
audio.src = url;
audio.autoplay = true;
audio.onended = function(){
audio.remove() //Remove when played.
};
document.body.appendChild(audio);
}
I had some issues related to audio promise object returns and some issues related to user interaction with sounds I end up using this small object,
I would recommend to implement the play sounds the closest to the interaction event user is using.
var soundPlayer = {
audio: null,
muted: false,
playing: false,
_ppromis: null,
puse: function () {
this.audio.pause();
},
play: function (file) {
if (this.muted) {
return false;
}
if (!this.audio && this.playing === false) {
this.audio = new Audio(file);
this._ppromis = this.audio.play();
this.playing = true;
if (this._ppromis !== undefined) {
this._ppromis.then(function () {
soundPlayer.playing = false;
});
}
} else if (!this.playing) {
this.playing = true;
this.audio.src = file;
this._ppromis = soundPlayer.audio.play();
this._ppromis.then(function () {
soundPlayer.playing = false;
});
}
}
};
And implement it as follow:
<button onclick="soundPlayer.play('https://interactive-examples.mdn.mozilla.net/media/examples/t-rex-roar.mp3');">Play</button>