【问题标题】:Autoplay sound in chrome background tabchrome背景选项卡中的自动播放声音
【发布时间】:2016-06-02 05:54:05
【问题描述】:

我有一个使用音频通知的 HTML5 游戏。

当用户通过匹配来搜索其他玩家时,他们经常更改标签来做其他事情,并依靠音频通知知道何时回来。在 Chrome(桌面版)更改为禁止音频通知后,这不再有效。

如何确保音频通知仍在后台运行?

【问题讨论】:

  • 我有 Chrome 49.0.2623.75 m,从 2016 年 3 月 3 日开始,this 在后台选项卡中使用 setTimeout 为我工作。
  • 这里有两个概念,我需要了解您需要哪些:首先​​是 Notification API,它允许网站即使未打开并且有声音选项也可以向您发送通知,然后是背景选项卡发出声音的概念。你需要哪些?
  • @SideriteZackwehdex 是后者。
  • 您使用的是桌面还是 Android... 我的假设是桌面,因为没有 Android 标签或提及 Android。

标签: javascript html google-chrome audio


【解决方案1】:

对我有用的解决方案是在页面加载后播放一个小的空白声音(0.1 秒就足够了)。之后,即使您切换到另一个选项卡,后台的选项卡仍然可以播放某些外部或内部事件的声音。

【讨论】:

  • 是的,我也是这样做的。
  • 这在 2019 年仍然有效吗?我刚刚尝试过,但它在 Chrome 71 中没有。
【解决方案2】:

示例 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>';
}
&lt;button onclick="setTimeout(playCoinDrop, 3000)"&gt;play sound&lt;/button&gt;

您可以根据需要替换音频文件。


示例 2 - 本地存储

这是一种更高级的方法,它利用了localStorage,这可能是您的最佳选择。这允许您通过将通知声音作为 Base64 下载到 localStorage 来预加载通知声音,然后您可以在选项卡在后台时调用播放它,而不会导致额外的网络传输。

这种方法的一个主要好处是只下载一次通知文件,然后从浏览器 localStorage 本地播放。

downloadCoin() 函数将文件作为 base64 存储在 localStoarge
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>

demo on github

【讨论】:

    【解决方案3】:

    在这里,后台标签仍然可以播放来自&lt;audio&gt; 元素的声音(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 库并使用本地存储在打开的选项卡之间进行通信。

    试试这个

    等等。

    注入&lt;audio&gt; 元素的代码和更多代码可以包装在用户脚本中,这样它就可以在碰巧在前面的任何站点上运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      • 2013-01-24
      相关资源
      最近更新 更多