I wanted to add a new ability that will play sound when piece moved for Chess -- https://chess.aiursoft.cn/

I was suppose it is a very simple ability, but finally I found that is not easy as I thought. Becuase the Autopay policy in browser, I could not play the sound as I like.

(Autoplay policy)[https://developer.chrome.com/blog/autoplay/]

Autoplay policy on order to improve the user experience, Chrome's autoplay policies are simple:

  • Muted autoplay is always allowed.
  • Autoplay with sound is allowed if:
    • The user has interacted with the domain (click, tap, etc.).
    • On desktop, the user's Media Engagement Index threshold has been crossed, meaning the user has previously played video with sound.
    • The user has added the site to their home screen on mobile or installed the PWA on desktop.
  • Top frames can delegate autoplay permission to their iframes to allow autoplay with sound.

So I could not play the sound before user interact with page, and could not play the sound while user stoped interact with page.

For example, we start a chess, and waiting opponent moving, when opponent moved, the page will play the piese moving sound. But if we switch another browser's tab or switch another App, then the user stoping interact with page, for the Autoplay policy, browser not allowed play the piece moving sound.

But lucky, browser autoplay policy will not stop the playing sound, if we playing a song and switch to another tab or App, it will still playing. So I found a way to bypass restriction: We can loop the sound and regulate the volume! regulate the volume to 1 while piece moving, and regulate the volume to 0.0001 when piece moved.

But why 0.0001 instead of 0 or mute?

Because if set it mute or volume 0 (volume means mute), will trigger the Autoplay policy restriction, set volume to 1 or set unmute will be prevent while user stop interacting with page. But if set a sufficiently low volume, it would not trigger the Autoplay policy, because the sound are still playing.

sound.volume = 1;
setTimeout(() => {
	sound.currentTime = 0;
	sound.volume = 0.0001;
}, 500);

User cannot hear the sound while volume 0.0001.

Notice!

set volume = 1 is not allowed in mobile! So can set to mute while Mobile.

sound.muted = false;
setTimeout(() => {
	sound.currentTime = 0;
	sound.muted = true;
}, 500);