我有一个使用音频通知的HTML5游戏。
当用户搜索匹配的其他玩家时,他们经常更改标签以执行其他操作,并依赖音频通知来知道何时返回。 Chrome(桌面)更改为禁止音频通知后,此功能不再有效。
如何确保音频通知仍然在后台运行?
我有一个使用音频通知的HTML5游戏。
当用户搜索匹配的其他玩家时,他们经常更改标签以执行其他操作,并依赖音频通知来知道何时返回。 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()
function存储文件 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屏蔽此功能,解决此问题的方法是通知事件的前面标签,让它播放声音而不是背景标签。
以下内容需要作为用户脚本扩展来实现,以便它可以在任何选项卡上工作 - 作为演示,它只在具有相同JSBin URL的两个选项卡之间工作:
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();
}
它依赖于 intercom.js 库并使用localstorage在打开的选项卡之间进行通信。
试试吧
等等。
代码和一些注入的代码 <audio>
元素可以包装在用户脚本中,因此它可以在碰巧在前面的任何站点上运行。