最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I request user permission for audio on Chrome? - Stack Overflow

programmeradmin1浏览0评论

I am working on SAAS solution and I need customers to receive notification sounds from the application. Even if they just launched it without any interaction with it. Google has changed Chrome behaviour regarding this aspect and now user is required to click on webpage to get notification sounds. I have found out that it is possible to allow sounds explicitly here:

and then user should enable sounds explicitly for your websites:

Now user will not have to click to enable sound notifications. My question: is it possible to request user permission for sound the same way we do it for microphone:

I am working on SAAS solution and I need customers to receive notification sounds from the application. Even if they just launched it without any interaction with it. Google has changed Chrome behaviour regarding this aspect and now user is required to click on webpage to get notification sounds. I have found out that it is possible to allow sounds explicitly here:

and then user should enable sounds explicitly for your websites:

Now user will not have to click to enable sound notifications. My question: is it possible to request user permission for sound the same way we do it for microphone:

Share Improve this question asked Dec 7, 2019 at 15:31 Stepan YakovenkoStepan Yakovenko 9,21631 gold badges123 silver badges212 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 13 +200

Simply make your own alert modal. You can feature detect if it is required or not by trying to play your audio while muted

const audio = new Audio( 'https://dl.dropboxusercontent.com/s/h8pvqqol3ovyle8/tom.mp3' );
audio.muted = true;

const alert_elem = document.querySelector( '.alert' );

audio.play().then( () => {
  // already allowed
  alert_elem.remove();
  resetAudio();
} )
.catch( () => {
  // need user interaction
  alert_elem.addEventListener( 'click', ({ target }) => {
    if( target.matches('button') ) {
      const allowed = target.value === "1";
      if( allowed ) {
        audio.play()
          .then( resetAudio );
      }
      alert_elem.remove();
    }
  } );
} );

document.getElementById( 'btn' ).addEventListener( 'click', (e) => {
  if( audio.muted ) {
    console.log( 'silent notification' );
  }
  else {
    audio.play();
  }
} );

function resetAudio() {
  audio.pause();
  audio.currentTime = 0;
  audio.muted = false;
}
.alert {
  font: 14px Arial, sans-serif;
  position: fixed;
  top: 0;
  left: 0;
  background: white;
  border: 1px solid lightgray;
  box-shadow: 3px 3px 12px lightgray;
}
p { margin: 12px; }
.alert .buttons {
  float: right
}
<div class="alert">
  <p>This webpage would like to play sounds</p>
  <p class="buttons">
    <button value="0">Block</button>
    <button value="1">Allow</button>
  </p>
</div>
<button id="btn">trigger notification</button>


Ps: note that there is a "speaker" value in Permissions API specs, but this one is for allowing devices through HTMLMediaElement.setSinkId() method, which is yet another beast. (you can see this Q/A if you are interested in this not yet implemented feature).

A modified version of Kaiido's answer. I don't think it is necessary to check for audio playing after page load and no exception checking is required. I could be wrong though.

This seems to work just fine:

const audio = new Audio('https://vmirror.imslp.org/files/imglnks/usimg/0/06/IMSLP197806-PMLP02397-3-ClairDeLune-j.mp3');
const musicPromptWindow = document.getElementById('musicPrompt');
const playAudioBtn = document.getElementById('playAudioBtn');
audio.muted = true;

playAudioBtn.onclick = function () {
  playAudio(audio.muted);
  setPlayAudioBtnText(audio.muted);
};

musicPromptWindow.querySelectorAll('button').forEach((item) => {
  item.onclick = function () {
    playAudio(item.value === '1');
    playAudioBtn.disabled = false;
    musicPromptWindow.remove();
  };
});

function playAudio(doPlayAudio) {
  audio.muted = !doPlayAudio;
  if (doPlayAudio) {
    audio.play();
  }
  setPlayAudioBtnText(audio.muted);  
}

function setPlayAudioBtnText(isAudioMuted) {
  playAudioBtn.innerText = isAudioMuted ? 'Play audio' : 'Mute audio';
}
#page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 80vh;
}

main {
  display: flex;
  align-items: center;
  justify-content: center;
  height: calc(100vh - 20px);
  overflow: hidden;
}

#musicPrompt {
  border: 1px solid lightgray;
  box-shadow: 3px 3px 12px lightgray;
  padding: 10px;
}
<div id="page">
  <main>
    <div id="musicPrompt">
      <p>Play audio?</p>
      <p class="buttons">
        <button value="0">No</button>
        <button value="1">Yes</button>
      </p>
    </div>
  </main>
  <footer>
    <button id="playAudioBtn" disabled>Play Audio</button>
  </footer>
</div>

Codepen here: https://codepen.io/r-w-c/pen/bGyGaGv

发布评论

评论列表(0)

  1. 暂无评论