我有一个使用音频通知的HTML5游戏。
当用户在匹配其他玩家时,他们经常切换标签并依靠音频通知来知道何时回来。但是,Chrome(桌面版)更改为禁止音频通知后,这不再起作用。
如何确保背景中仍然可以使用音频通知?
当用户在匹配其他玩家时,他们经常切换标签并依靠音频通知来知道何时回来。但是,Chrome(桌面版)更改为禁止音频通知后,这不再起作用。
如何确保背景中仍然可以使用音频通知?
对我有效的解决方案是在页面加载后播放一个小的空白声音(0.1秒就足够了)。之后,即使您切换到另一个选项卡,后台选项卡仍然可以在某些外部或内部事件上播放声音。
这是一个示例,创建了一个 div 并使用 HTML5 <audio>
标签,如果不支持则回退到 <embed>
,在点击按钮后 3 秒钟播放音频文件。
为了测试它,运行样例并点击按钮,然后切换标签并计数 3 秒钟。 即使此标签不是当前标签,您也应该在此标签上看到扬声器图标并在 3 秒钟后听到硬币掉落的声音。
function playCoinDrop() {
soundDiv = document.createElement("div");
soundDiv.innerHTML = '<audio autoplay="autoplay"><source src="http://themushroomkingdom.net/sounds/wav/smw/smw_coin.wav" type="audio/wav" /><embed hidden="true" autostart="true" loop="false" src="http://themushroomkingdom.net/sounds/wav/smw/smw_coin.wav" /></audio>';
}
<button onclick="setTimeout(playCoinDrop, 3000)">play sound</button>
这里是一种更高级的方法,利用了localStorage
,这可能是您最好的选择。这允许您通过将其下载为Base64并将其下载到localStorage中来预加载通知声音,然后可以在选项卡处于后台时调用播放它而不会导致额外的网络传输。
这种方法的一个主要优点是只有一个通知文件的下载,之后它就会从浏览器的localStorage本地播放。
downloadCoin()
函数将文件存储在localStoarge
中作为base64
playCoinDrop()
动态创建一个div并播放base64数据
playCoinDropJS()
播放base64数据而不创建任何div
function downloadCoin() {
var coin = 'smw_coin.wav';
var xhr = new XMLHttpRequest();
xhr.open('GET', coin, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = new Blob([this.response], {
type: 'audio/wav'
});
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var coinB64 = reader.result;
var myStorage = localStorage.setItem('coin_base64', coinB64)
}
}
};
xhr.send();
}
function playCoinDrop() {
var coinB64 = localStorage.getItem('coin_base64');
var soundDiv = document.createElement('div');
soundDiv.innerHTML = '<audio autoplay="autoplay"><source src="' + coinB64 + '" type="audio/wav" />';
}
function playCoinDropJS(){
var coinB64 = localStorage.getItem("coin_base64");
var snd = new Audio(coinB64);
snd.play();
}
<button onclick="downloadCoin()">download</button>
<button onclick="setTimeout(playCoinDrop, 3000)">play sound</button>
<button onclick="setTimeout(playCoinDropJS, 3000)">play sound JS</button>
<audio>
元素的声音(Chrome 49.0.2623.87)。然而,如果Chrome阻止了这一点,解决方法是通知前台标签发生事件,并让它代替后台标签播放声音。var intercom = Intercom.getInstance();
document.addEventListener("visibilitychange", getVisible);
function getVisible (evt) {
document.getElementById("fg-indicate").style.visibility = document.visibilityState;
if (document.visibilityState == "visible") {
// tab comes to front => listen to intercom
intercom.on('notice', play);
} else {
// kill callback
intercom.off('notice', play);
// call intercom with delay
window.setTimeout(function f() {
intercom.emit('notice', {message: 'Hello, all windows!'});
}, 3000);
}
}
function play() {
document.getElementsByTagName("audio")[0].play();
}
<audio>
元素可以被包装在用户脚本中,因此它可以运行在任何位于前台的网站上。
localStorage
将音频文件存储为 base64,然后播放嵌入的数据。 - Tim Penner