Video.js 博客

Pat O'Neill2018-04-17

Video.js 自动播放最佳实践

简而言之

  • 永远不要认为自动播放会成功。
  • 使用 muted 属性/选项将提高自动播放成功的几率。
  • 优先使用 player.play() 方法进行程序化自动播放,避免使用 autoplay 属性/选项。

引言

最近关于自动播放的讨论很多,我们想花几分钟时间分享一些在使用 Video.js 进行自动播放时的最佳实践。

本文旨在提供信息——而不是关于视频自动播放的社论或立场声明。许多用户讨厌自动播放,因为它令人烦恼或消耗宝贵的带宽。而许多免费提供内容的发布商则依赖自动播放的前贴片广告来为其业务提供资金。浏览器供应商(以及开源库作者)必须根据用户的利益、网络上的发布商以及他们自己的业务来权衡这些问题。用户则必须选择最符合他们偏好的浏览器。

本文不探讨规避自动播放策略的方法。这是不可能的,也没有人应该浪费时间尝试这样做。我们认为,积极规避浏览器内置用户体验或用户偏好是有害的,这一点是毋庸置疑的。

主要浏览器中的自动播放策略

我不会详细阐述每个浏览器具体的算法,因为它们可能会发生变化,而且这样做会偏离本文的核心观点:永远不要认为自动播放会成功。

Safari

自 2017 年 9 月发布的 Safari 11 起,Apple 更新了其自动播放策略,以阻止大多数网站上带声音的自动播放。

Chrome

早在 2017 年 9 月,Google 就宣布 Chrome 的自动播放策略将在 2018 年 4 月随 Chrome 66 发生变化,具体规则可在链接文章中查阅。

Firefox

对于 Firefox,Mozilla 暂时采取了不制定严格自动播放策略的立场。未来可能会有所改变。话虽如此,今天的 Firefox 确实允许用户通过一些配置更改来禁用自动播放

IE11 和 Edge

微软的浏览器没有特定的/已知的自动播放策略——在撰写本文时,自动播放在 IE11 和 Edge 中仍然有效。

Video.js 中如何请求自动播放的回顾

请注意,本节标题中使用了“请求”一词。这是故意的,因为它应该被视为一个请求。请记住,永远不要认为自动播放会成功。

Video.js 的优势之一是它围绕原生 <video> 元素接口设计;因此,它会遵从底层播放技术(在大多数情况下是 HTML5 视频)和浏览器。换句话说,如果浏览器允许,Video.js 就允许

使用 Video.js 启用自动播放有两种方法:

  1. <video> 元素或新的 <video-js> 元素上使用 autoplay 属性。

    <video autoplay src="https://path/to/source.mp4"></video>
    <video-js autoplay src="https://path/to/source.mp4"></video-js>
  2. 使用 autoplay 选项

    videojs('player', {autoplay: true});

默认情况下,您可以遵循 Video.js 的默认行为。如果自动播放成功,Video.js 播放器将开始播放。如果自动播放失败,Video.js 播放器将表现得如同自动播放已关闭——即它会在海报图像(或黑色框)上显示“大播放按钮”组件。

如果这适用于您,您的任务就完成了!

提示:如果您想使用自动播放并提高其成功几率,请使用 muted 属性(或 Video.js 中的 muted 选项)。

除此之外,在处理自动播放时还有一些通用的实用做法:检测是否支持自动播放,或检测自动播放是成功还是失败。

检测自动播放支持

类似于检测自动播放请求的成功或失败,在创建播放器之前对浏览器执行自动播放特性检测可能很有用。在这些情况下,can-autoplay 库是最佳解决方案。它提供了一个与原生 player.play() 方法类似的基于 Promise 的 API。

canAutoplay.video().then(function(obj) {
  if (obj.result === true) {
    // Can autoplay
  } else {
    // Can not autoplay
  }
});

程序化自动播放及成功/失败检测

对于关心自动播放请求是否成功的人来说,Google 和 Apple 都推荐了相同的实践来检测自动播放的成功或拒绝:监听 player.play() 方法(在支持的浏览器中)返回的 Promise,以确定自动播放是否成功。

这可以与 autoplay 属性/选项结合使用,或者通过调用 player.play() 以程序化方式执行,但我们建议完全避免使用 autoplay 属性/选项,并以程序化方式请求自动播放

<video-js id="player" src="https://path/to/source.mp4"></video-js>
var player = videojs('player');

player.ready(function() {
  var promise = player.play();

  if (promise !== undefined) {
    promise.then(function() {
      // Autoplay started!
    }).catch(function(error) {
      // Autoplay was prevented.
    });
  }
});

注意:重要的是要理解,使用这种方法时,Video.js 的 player.autoplay() 方法将返回 undefinedfalse。如果您期望您的用户或集成者依赖此方法,请考虑下一节。

使用 autoplay 属性/选项进行程序化自动播放

当为他人构建播放器时,您可能无法总是控制用户是否在其播放器实例中包含 autoplay 属性/选项。幸运的是,将其与程序化自动播放结合使用似乎不会对播放行为产生显著影响。

根据我们的实验,即使浏览器处理实际的自动播放操作,在播放开始(或播放失败)后调用 player.play() 似乎也不会导致当前的 Chrome 或 Firefox 浏览器触发额外的 "play" 事件。然而,Safari 11.1 似乎会在每次调用 player.play() 且自动播放失败时触发 "playing""pause" 事件。

尽管如此,如果您拥有完全的控制权,我们建议完全避免使用 autoplay 属性/选项,并以程序化方式请求自动播放

注意:即使使用 autoplay 属性/选项程序化自动播放结合,player.autoplay() 方法在播放器准备就绪之前也将返回 undefined

示例用例

在 Brightcove,我们为改善基于 Video.js 播放器的用户体验所做的一件事是,对于请求自动播放的播放器,隐藏“大播放按钮”,直到自动播放成功或失败。这避免了“大播放按钮”在自动播放启动前瞬间闪烁的情况。

尽管我们的实际实现由于播放器的具体情况而更为复杂,但其核心思想与这个功能性 JSBin 演示相同。

总结

您的代码中可能存在与自动播放是否成功相关的决策点;然而,实际情况是,在此之前的所有段落都归结为一个单一而重要的概念:

永远不要假设您的自动播放请求会成功。

请牢记这一点,您就会成功。即使浏览器完全停止允许自动播放,我们希望推荐这种方法在某种程度上仍然是面向未来的。