【问题标题】:Latest Chrome Desktop update preventing SoundJS from playing sounds (related to autoplay)最新的 Chrome 桌面更新阻止 SoundJS 播放声音(与自动播放有关)
【发布时间】:2018-10-16 03:14:38
【问题描述】:

我在最新版本的 Chrome 桌面上收到了这个 JavaScript 警告,现在它会阻止在没有用户交互的情况下自动播放声音:http://bgr.com/2018/03/22/google-chrome-autoplay-videos-sound-block/

所以我在控制台日志中收到此错误/警告:“AudioContext 不允许启动。它必须在页面上的用户手势后恢复(或创建)”

我有什么方法可以在用户交互时恢复声音或 SoundJS 的音频上下文,例如页面上的点击或键盘事件?

我的设置是我使用 preloadJS 来加载我的 MP3,如下所示:

queue.loadManifest([
  {id: 'sndScore', src: 'sndScore.mp3'}
]);

然后我播放这样的声音:

createjs.Sound.play("sndScore");

我尝试放置一个标志 var unitInteracted= false;然后,如果用户与页面交互,我将其设置为 true,并修改我的声音播放代码,以确保在我尝试播放声音之前已经与页面进行了交互:

if (unitInteracted) {                                
  createjs.Sound.play("sndScore");
}

...但由于某种原因,我仍然收到上述错误/警告,并且页面最终仍然被静音。一旦 Chrome 说:“AudioContext 不允许启动。它必须在页面上的用户手势之后恢复(或创建)”,有什么方法可以取消静音?

谢谢!

【问题讨论】:

  • 我不知道SoundJS,也不知道他们何时创建AudioContext,但是您遇到的错误告诉您在用户手势本身中初始化上下文(即在事件处理程序中同步,或之后不到 60 毫秒的时间)。似乎它与媒体元素不同,媒体元素只需要页面曾经收到过用户手势。因此,您的标志方式将不起作用,并且取决于 SoundJS 确实创建其上下文的方式和时间,它可能很难,或者像初始启动屏幕一样简单,您将在其中绑定触发 createjs.sound.play(silence) 的点击事件

标签: javascript google-chrome audio createjs soundjs


【解决方案1】:

SoundJS的源码我没有深入阅读,但是PreloadJS似乎会触发AudioContext的创建。

因此,为避免这种情况,您可能需要仅在用户手势事件中开始获取资源:例如,您可以向用户显示启动画面,并且只有在他们单击其上的按钮时,您才会开始获取您的音频资源:

// wait for user gesture
btn.onclick = e => {
  // now we can load our resources
  var queue = new createjs.LoadQueue();
  queue.installPlugin(createjs.Sound);
  queue.on("complete", handleComplete, this);
  queue.loadFile({
    id: "sound",
    src: "https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3"
  });
  btn.disabled = true;
  // and show our user we are loading things
  btn.textContent = 'loading';
};

function handleComplete() {
  // now we can play our sounds without issue
  btn.disabled = false;
  btn.textContent = 'play';
  btn.onclick = e =>
    createjs.Sound.play("sound");
  // we don't need a user gesture anymore
  setTimeout(btn.onclick, 2000);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/SoundJS/1.0.2/soundjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/PreloadJS/1.0.1/preloadjs.min.js"></script>

<!-- make it part of a splash-screen -->
<button id="btn">Let's start the awesome</button>

【讨论】:

  • 我还没有尝试过这个解决方案,因为它可能会影响我正在处理的单元的功能,但我希望有一种方法可以在用户交互时恢复音频上下文,就像在这里的 PhaserJS 中一样:github.com/photonstorm/phaser/issues/2913SoundJS 确实根据文档为“高级用户”提供了音频上下文变量 - 我希望这里有人知道如何使用并让他们在用户交互后恢复......跨度>
  • @object404 好吧,我不知道 SoundJS,但我仍然可以了解这里发生的情况:1) PreloadJS 将获取音频文件作为 ArrayBuffer(通过 AJAX)2) 它将使用 SoundJS由于 SoundJS AudioContext 的 decodeAudioData 方法,插件将此文件解码为 AudioBuffer。 3) 一旦这个 AudioBuffer 被创建,它将把它存储在某个地方,以便 SoundJS 能够在它的play 方法中检索它,并且能够用之前创建的缓冲区创建一个 BufferSourceNode。如您所见,实际上从第 2 步开始就需要 AudioContext,这是一个异步步骤。
  • 这意味着即使您可以选择单独触发步骤 2) 和 3),SoundJS 仍然无法同步play。因此,您将赢得的只是获取时间,您可以通过执行第一个请求来赢得时间,以便文件由浏览器存储在缓存中。
猜你喜欢
  • 2015-12-20
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-04
  • 2017-10-20
相关资源
最近更新 更多