# 一、自动播放的问题是如何产生的?

  1. 应用自动运行时,程序直接调用video标签play方法(无用户手势),浏览器可能会阻止自动播放 (opens new window)
  2. 在用户点击按钮以后调用播放方法,但是可能会有一些前置的异步操作导致无法播放。例如点击播放按钮以后,需要先从后台获取视频地址,拿到结果以后才继续调用play方法。
  3. 实现列表播放使用了多个video标签。用户的点击按钮可能只能触发到第一个显示的video标签,其他待播放的video标签(可能隐藏在后端)无法获得用户点击手势。

# 二、各浏览器支持自动播放情况

浏览器 有声 静音
chrome(桌面端) 有用户交互或MEI评分通过 (opens new window) 支持
safari(桌面端) 浏览器设置 浏览器设置
firefox(桌面端) 浏览器设置 浏览器设置
qq浏览器(桌面端) 支持 支持
chrome(移动端) 用户将站点添加到首页时支持 支持
(但ios低电量模式/非playsinline不支持)
safari(移动端) 不支持 内联播放(playsinline) 并且非低电量模式时支持。
ios上的浏览器都有这个限制
x5(移动端) ? 安卓QQ浏览器允许wifi下自动播放
手机QQ允许自动播放
微信不允许自动播放(域名白名单内允许)
其他x5内核浏览器,看浏览器设置
安卓系统浏览器(小米)(移动端) 支持 支持
腾讯视频app(ios) 支持 非低电量:支持
低电量:在jsbridge接口getNetworkState回调内支持自动播放,否则不支持
腾讯视频app(安卓) 需要在页面url加上autoplay=1参数 需要在页面url加上autoplay=1参数

# 三、thumbplayer-h5中的解决方案

实际上,播放器是无法绕开浏览器自动播放限制的。但浏览器自动播放的策略我们可以分为两种情况:

  • 无声自动播放(绝大浏览器场景都可以成功)
  • 有声自动播放

如果想实现自动播放,请按下面的步骤尝试:

# 步骤1:尝试静音自动播放(不接受自动播放后是静音状态请跳过此步骤)

import SuperPlayer, { AUTO_PLAY_POLICY } from '@tencent/super-player';

const player = new SuperPlayer({
  container: '#app',
  // 传入自动播放配置参数
  autoPlayPolicy: AUTO_PLAY_POLICY.IN_MUTED,
});

其中autoPlayPolicy枚举为:

名称 说明
autoPlayInMuted 当自动播放被浏览器阻止以后,尝试静音播放
autoPlayRequireByUserGesture 自动播放一定需要用户手势

# 步骤2:使用js触发自动播放,并监听自动播放被阻止事件

我们只需要在创建播放器以后,调用play()接口直接播放即可尝试自动播放视频。

import SuperPlayer, { AUTO_PLAY_POLICY, H5_PLAY_EVENT } from '@tencent/super-player';

const player = new SuperPlayer({
  container: '#app',
  // 传入自动播放配置参数,请自行决定传入值
  autoPlayPolicy: AUTO_PLAY_POLICY.IN_MUTED,
});

player.on(H5_PLAY_EVENT.VIDEO_AUTOPLAY_BLOCKED, () => {
  console.log('自动播放被阻止,请点击播放按钮');
});

document.querySelector('#playBtn').addEventListener('click', () => {
  // 在点击事件中浏览器获得用户手势,如果之前自动播放被阻止,此时用户触发成功播放。
  // 当然,如果您使用的是带控制栏的superplayer,您无需自行创建播放按钮并监听用户点击,用户可在superplayer的控制栏播放按钮上触发播放
  player.play();
});

// 尝试用代码调用play接口,相当于触发自动播放视频
player.play({
  url: 'xxx.mp4',
});

上面的代码可以看到,当浏览器阻止了自动播放时(自动播放失败),播放器会抛出H5_PLAY_EVENT.VIDEO_AUTOPLAY_BLOCKED事件,播放器处于播放被block的状态。此时唯一的处理办法即等待用户点击播放按钮(触发clicktouchstart等交互事件),并在播放按钮的监听函数中,同步的调用播放器play方法。

也就是说,如果浏览器允许我们自动播放,那么这一步以后,视频即开始成功播放了。如果不能自动播放,那么我们需要等待用户触发播放。

# 步骤3:异步场景下无法获得用户手势导致的播放失败的解决方案

有一种更特殊的情况,浏览器不允许我们自动播放,并且我们在播放按钮的监听回调中,仍然无法同步调用播放器play接口!此时浏览器也不会给video标签传递用户手势,请看下面例子:

import SuperPlayer from '@tencent/super-player';

const player = new SuperPlayer({
  container: '#app',
});

document.querySelector('#playBtn').addEventListener('click', () => {
  // setTimeout模拟了一个异步操作,例如从网络拉取视频地址等
  // 在异步操作中调用play接口,video的play无法在事件回调中同步触发,也就是点击按钮事件无法直接触及play方法,而是隔了一些异步操作
  window.setTimeout(() => {
    player.play({
      url: 'xxx.mp4',
    });
  }, 2000);
});

这种情况由于浏览器没有获得用户手势,播放器仍然无法成功触发播放。我们需要调用播放器的triggerAutoplay方法来解决这个问题:

import SuperPlayer from '@tencent/super-player';

const player = new SuperPlayer({
  container: '#app',
});
document.querySelector('#playBtn').addEventListener('click', () => {
  // 先调用triggerAutoplay接口在事件回调中同步触发video的play方法,然后在then中继续异步操作
  player.triggerAutoplay().then(() => {
    window.setTimeout(() => {
      player.play({
        url: 'xxx.mp4',
      });
    }, 2000);
  });
});
上次更新: 2/14/2022, 7:46:15 PM