在 Safari 和 Mobile Chrome 上以编程方式播放带声音的视频

IT技术 javascript html video safari html5-video
2021-01-15 12:56:36

随着 OSX High-Sierra* 的发布,Safari 的一项新功能是网站上的视频不再自动播放,脚本也无法启动,就像在 iOS 上一样。作为用户,我喜欢该功能,但作为开发人员,它给我带来了一个问题:我有一个包含视频的浏览器内 HTML5 游戏。除非用户更改设置,否则视频不会再自动播放。这会打乱游戏流程。

我的问题是,我能否以某种方式使用玩家与游戏的互动作为视频自动开始播放的触发器,即使所述活动没有直接链接到视频元素?

我不能使用 jQuery 或其他框架,因为我的雇主对我们的开发施加了限制。一个例外是 pixi.js,在所有其他动画中,我们还使用它在 pixi 容器中播放我们的视频。

*同样的限制也适用于移动 Chrome。

1个回答

是的,您可以绑定不是直接在视频元素上触发的事件:

btn.onclick = e => vid.play();
<button id="btn">play</button><br>
<video id="vid" src="https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4"></video>

因此,您可以将此按钮替换为任何其他要求用户单击的启动画面,并且您将被授予播放视频的权限。

但是为了保持这种能力,您必须在事件处理程序本身至少调用一次视频play方法

不工作:

btn.onclick = e => {
  // won't work, we're not in the event handler anymore
  setTimeout(()=> vid.play().catch(console.error), 5000);
  }
<button id="btn">play</button><br>
<video id="vid" src="https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4"></video>

正确修复:

btn.onclick = e => {
  vid.play().then(()=>vid.pause()); // grants full access to the video
  setTimeout(()=> vid.play().catch(console.error), 5000);
  }
<button id="btn">play</button><br>
<video id="vid" src="https://dl.dropboxusercontent.com/s/bch2j17v6ny4ako/movie720p.mp4"></video>

Ps:这是specs 定义受信任事件列表,我不确定 Safari 是否仅限于这些,也不确定是否包含所有这些。


关于 Chrome 和准备多个 MediaElements 的重要说明

Chrome 有一个由每个主机的最大并发请求数引起的长期错误,这确实会影响页面中的 MediaElement 播放,将它们的数量限制为 6。

这意味着您不能使用上述方法在页面中准备超过 6 个不同的 MediaElement。

不过,至少存在两种​​解决方法:

  • 似乎一旦 MediaElement 被标记为user-approved,它就会保持这个状态,即使你改变了它的 src。因此,您最多可以准备 MediaElements,然后在需要时更改它们的 src。
  • Web Audio API,同时也关注这个用户手势要求,一旦允许就可以播放任意数量的音频源。因此,由于该decodeAudioData()方法,人们可以将所有音频资源加载为 AudioBuffers,甚至可以加载来自视频媒体的音频资源,这些图像流可以<video>与 AudioBuffer 并行显示在静音元素中。
如果您播放然后暂停:用户会听到它的声音还是太快了?
2021-03-28 12:56:36
在我禁用 Safari 中的自动播放后,确认这也适用于音频。(我和你在同一个 macOs 版本上)虽然我不知道如何一次播放多个实例。(我会看看我是否会问一个新问题)
2021-03-29 12:56:36
@Marimba 似乎您可以在调用之前将视频静音play,并在返回的Promise中取消静音,之后pause此外,它似乎也适用于文档的点击。但请注意,我仅在 OS X 10.12.6 上的 Safari 11.0.1 上进行了测试。在其他操作系统/版本中可能还有其他行为,我实际上开始怀疑我的浏览器的行为是否在上次更新时没有改变......
2021-04-01 12:56:36
啊,这正是我想要的 :-) 游戏加载完成后,我可以像您建议的那样向玩家显示启动画面。
2021-04-06 12:56:36
@Marimba 在同一事件的多个媒体元素上调用播放也应该有效。
2021-04-07 12:56:36