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

Posted

技术标签:

【中文标题】在 Safari 和 Mobile Chrome 上以编程方式播放有声视频【英文标题】:Programmatically play video with sound on Safari and Mobile Chrome 【发布时间】:2018-03-11 00:21:53 【问题描述】:

随着 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:here is the list of trusted events as defined by the specs,我不确定 Safari 是否仅限于这些,也不知道是否包含所有这些。


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

Chrome 有一个long-standing bug,由每个主机的最大同时请求数引起,这确实会影响页面中的 MediaElement 播放,将其数量限制为 6 个。

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

但至少存在两种​​解决方法:

似乎一旦 MediaElement 被标记为用户批准,即使您更改了它的 src,它也会保持这种状态。因此,您可以准备最多的 MediaElement,然后在需要时更改它们的 src。 Web 音频 API,同时也受到此用户手势要求的关注,一旦允许,就可以播放任意数量的音频源。因此,感谢decodeAudioData() 方法,可以将他们所有的音频资源加载为AudioBuffers,甚至是来自视频媒体的音频资源,这些图像流可以只显示在与AudioBuffer 并行的静音&lt;video&gt; 元素中。李>

【讨论】:

啊,这正是我想要的 :-) 一旦游戏加载完成,我可以按照你的建议向玩家展示一个启动画面。 如果你播放然后暂停:用户会听到它的声音还是太快了? @Marimba 似乎您可以在调用play 之前将视频静音,并在pause 之后在返回的承诺中取消静音。此外,它似乎也适用于文档的点击。但请注意,我仅在 OS X 10.12.6 上的 Safari 11.0.1 上进行了测试。其他操作系统/版本中可能还有其他行为,我实际上开始怀疑我的浏览器的行为是否已经随着上次更新而改变...... 确认这在我禁用 Safari 中的自动播放后也适用于音频。 (我和你在同一个 macOS 版本上)不过我还不知道如何同时玩多个实例。 (我会看看我是否会提出一个新问题) @Marimba 在同一事件的多个媒体元素上调用播放也应该有效。

以上是关于在 Safari 和 Mobile Chrome 上以编程方式播放有声视频的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Safari Mobile 中无法播放网络音频 api 振荡器?

带有剪切路径的动画:插入在Safari中不起作用

Mobile Safari 和 iFrame src 属性

Safari 和 Mobile Safari 需要刷新页面才能播放 Howler Audio

Safari 和 Mobile Safari 中的内联 SVG 中断

mobile-safari javascript:多个 setTimeouts 或 setIntervals