I am trying to play audio without any user interaction and getting error:
Uncaught (in promise) DOMException: The play method is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.`
Here is my code:
<audio id="beep">
<source src="~/Content/Sounds/beep.mp3" type="audio/mp3">
</audio>
<script>
var playAudio = $("#beep")[0];
playAudio.play();
</script>
As I understand its denied by current browsers to play audio without explicit user interaction. Is it possible somehow when the page is loaded ask user for permission to play audio and only after user’s explicit permission load the page, then call this code in JS whenever I need it?
3
User interaction basically means when the user clicks anywhere on the page. The following example features a <dialog>
prompting the user to either permit the audio to play or deny it. Details are commented in the example. Responsively it’s decent but it looks great if viewed in Full page mode.
// Reference <dialog>
const modal = document.querySelector("dialog");
// Reference <form>
const io = document.forms[0];
// Load the audio object
const mp3 = new Audio("https://glsbx.s3.amazonaws.com/-/dd.mp3");
// If it's an <audio> reference like normal.
// const mp3 = document.querySelector("audio");
// Open <dialog>
modal.showModal();
// Pre-adjust audio volume
mp3.volume = 0.5;
/**
* This event handler determines if the audio will be played
* depending on which <button> the user clicked.
* @param {object} event - Event object
*/
const player = event => {
// Determine which element the user clicked
const clk = event.target;
// If the user clicked button#no...
if (clk.id === "no") {
// close the <dialog> and...
modal.close();
// end the function
return;
}
// If the user clicked button#yes...
if (clk.id === "yes") {
// close the <dialog>...
modal.close();
// play the audio and...
mp3.play();
// end the function
return;
}
};
/*
Register the <form> to listen for any "click" events fired on
itself or any of it's children. When the "click" event is
triggered function player() will be called.
*/
io.addEventListener("click", player);
:root {
font: 2ch/1.2 "Segoe UI";
}
dialog {
width: 50vw;
padding: 0.75rem 1rem 1.25rem;
border: 1.51515px outset rgb(240, 240, 240);
border-radius: 8px;
box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
}
dialog::backdrop {
background: rgba(38, 57, 77, 0.4)
}
fieldset {
padding: 0 1.25rem;
border-radius: 8px;
box-shadow: rgba(0, 0, 0, 0.25) 0px 14px 28px, rgba(0, 0, 0, 0.22) 0px 10px 10px;
}
legend {
margin-bottom: -0.25rem;
}
sup {
position: relative;
top: -0.2em;
vertical-align: top;
font-size: smaller;
}
button {
float: right;
width: 4rem;
padding: 4px;
font: inherit;
cursor: pointer;
}
details {
font-size: smaller;
interpolate-size: allow-keywords;
}
details::details-content {
transition: block-size 1s, content-visibility 1s allow-discrete;
overflow: hidden;
block-size: 0;
}
details[open]::details-content {
block-size: auto;
}
summary {
display: block;
cursor: pointer;
}
summary::before {
content: '✤';
display: inline-block;
margin-right: 1ch;
transition: 0.2s;
}
details[open] summary::before {
transform: rotate(405deg);
}
footer {
clear: both;
padding: 1rem 0;
}
#yes {
margin-left: 0.25rem;
}
<dialog>
<form>
<fieldset>
<legend>Autoplay Policy</legend>
<p>In compliance with autoplay policy of your browser<sup>✤</sup> this site will only play audio with your explicit permission. Please choose your preference.</p>
<button id="yes" type="button">Permit</button>
<button id="no" type="button">Deny</button>
<footer>
<details>
<summary>More on autoplay policies</summary>
<ul>
<li><a href="https://developer.chrome.com/blog/autoplay" target="_blank">Chrome</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide" target="_blank">Firefox</a></li>
<li><a href="https://webkit.org/blog/6784/new-video-policies-for-ios/" target="_blank">iOS</a></li>
</ul>
</details>
</footer>
</fieldset>
</form>
</dialog>