Video.js 博客

Steve Heffernan2013-08-09

隐藏和显示视频播放器控制

上周,我决定解决一些关于控制栏的突出问题,然后开始深入研究相关的播放器更新。我很高兴现在重新出现,并且想写一些关于由此产生的更新。d写一些关于由此产生的更新。

播放器控制栏的一个预期行为是,当用户在观看视频时处于非活动状态时,它会在几秒钟后淡出。 以前,我们使用 video.js 实现这一点的方法是通过一些 CSS 技巧。当用户的鼠标移出视频播放器区域时,控制栏将被赋予类名 vjs-fade-out。 此类具有可见性转换,并添加了 2 秒的延迟。

.vjs-fade-out {
  display: block;
  visibility: hidden;
  opacity: 0;

  -webkit-transition: visibility 1.5s, opacity 1.5s;
  -moz-transition: visibility 1.5s, opacity 1.5s;
  -ms-transition: visibility 1.5s, opacity 1.5s;
  -o-transition: visibility 1.5s, opacity 1.5s;
  transition: visibility 1.5s, opacity 1.5s;

  /* Wait a moment before fading out the control bar */
  -webkit-transition-delay: 2s;
  -moz-transition-delay: 2s;
  -ms-transition-delay: 2s;
  -o-transition-delay: 2s;
  transition-delay: 2s;
}

当用户的鼠标移回播放器时,该类将被删除,从而取消任何延迟的淡出。 这提供了类似于您可能期望控件淡入淡出方式的体验,并且只需几行 javascript 即可添加/删除该类。

player.on('mouseout', function() {
  controlBar.addClass('vjs-fade-out');
});

player.on('mouseover', function() {
  controlBar.removeClass('vjs-fade-out');
});

但是有一些缺点使得有必要放弃这种方法。

  1. 控件不会在全屏模式下淡出,因为鼠标永远无法移出播放器区域。

  2. 移动设备上没有鼠标,因此需要不同的事件和交互来显示/隐藏控件。

除了这些问题之外,我们还希望任何播放器组件或插件都可以连接到隐藏控件的同一触发器。 诸如社交共享图标之类的组件应以与控件相同的方式淡出。

用户状态

首先要添加的是播放器上的 userActive 属性,该属性可以是 truefalse。 这样做会将控件隐藏抽象到我们真正关心的是,即用户当前是在与播放器交互还是只是被动地观看视频。 这还将控制栏与跟踪用户活动本身分离,并允许其他组件通过播放器级别的状态更轻松地以与控制栏相同的方式运行。

实际属性是 player.userActive(),并返回 truefalse。 当此值更改时,它会触发播放器上的事件。

player.userActive(true);
// -> 'useractive' event triggered
player.userActive(false);
// -> 'userinactive' event triggered

一个 CSS 类名 vjs-user-activevjs-user-inactive 也被添加到播放器元素。 类名现在实际上是用于隐藏和显示控制栏的名称。实际上是用于隐藏和显示控制栏的名称。

.vjs-default-skin.vjs-user-inactive .vjs-control-bar {
  display: block;
  visibility: hidden;
  opacity: 0;

  -webkit-transition: visibility 1.5s, opacity 1.5s;
  -moz-transition: visibility 1.5s, opacity 1.5s;
  -ms-transition: visibility 1.5s, opacity 1.5s;
  -o-transition: visibility 1.5s, opacity 1.5s;
  transition: visibility 1.5s, opacity 1.5s;
}

2 秒的延迟已从 CSS 中删除,而是将通过 javascript 超时构建到将 userActive 状态设置为 false 的过程中。 每当播放器上发生鼠标事件时,此超时都会重置。 例如

var resetDelay, inactivityTimeout;

resetDelay = function() {
  clearTimeout(inactivityTimeout);
  inactivityTimeout = setTimeout(function() {
    player.userActive(false);
  }, 2000);
};

player.on('mousemove', function() {
  resetDelay();
});

的鼠标移回播放器时,该类将被删除,从而取消任何延迟的淡出。 这提供了类似于您可能期望控件淡入淡出方式的体验,并且只需几行 javascript 即可添加/删除该类。鼠标移动事件在鼠标移动时会被非常迅速地调用,并且我们希望在执行此操作期间尽可能减少播放器进程的负担,因此我们

代替为每个 mousemove 重置超时, mousemove 事件将设置一个变量,该变量可以由 javascript 间隔拾取,该间隔以受控的速度运行。

var userActivity, activityCheck;

player.on('mousemove', function() {
  userActivity = true;
});

activityCheck = setInterval(function() {
  // Check to see if the mouse has been moved
  if (userActivity) {
    // Reset the activity tracker
    userActivity = false;

    // If the user state was inactive, set the state to active
    if (player.userActive() === false) {
      player.userActive(true);
    }

    // Clear any existing inactivity timeout to start the timer over
    clearTimeout(inactivityTimeout);

    // In X seconds, if no more activity has occurred
    // the user will be considered inactive
    inactivityTimeout = setTimeout(function() {
      // Protect against the case where the inactivity timeout can trigger
      // before the next user activity is picked up  by the
      // activityCheck loop.
      if (!userActivity) {
        this.userActive(false);
      }
    }, 2000);
  }
}, 250);

这可能需要关注很多内容,而且播放器中实际存在的内容简化了一些,但从本质上讲,它允许我们在鼠标移动时减轻浏览器的一些处理负担。

在全屏模式下隐藏控件

借助新的 userActive 状态和延迟的 javascript 超时,控件不再需要鼠标移出播放器区域才能隐藏,现在可以像在页面中一样在全屏模式下隐藏。 这也意味着我们现在可以以与控件相同的方式隐藏鼠标光标,这样它就不会在全屏观看时停留在播放器上方。

.vjs-fullscreen.vjs-user-inactive {
  cursor: none;
}

在触摸设备上隐藏控件

触摸设备上的预期行为与桌面浏览器略有不同。 没有 mousemove 事件来帮助确定用户是活动状态还是非活动状态,因此通常会添加更长的延迟,然后控件会淡出。 此外,虽然在桌面浏览器中单击视频本身通常会在播放和暂停之间切换,但在移动设备上点击视频会切换控件的可见性。

幸运的是,我们围绕 userActive 设置的框架使最后一部分足够容易设置。幸运的是,我们围绕 userActive 设置的框架使最后一部分足够容易设置。

video.on('tap', function() {
  if (player.userActive() === true) {
    player.userActive(false);
  } else {
    player.userActive(true);
  }
});

在 true 和 false 之间手动切换 userActive 将应用适当的类名并触发显示和隐藏控件所需的事件,就像您在移动设备上所期望的那样。

tap 事件实际上是一个自定义事件,类似于您在 jQuery mobileHammer.js 和其他移动触摸库中找到的 tap 事件。 每当触发 touchstart 事件,并且在 250 毫秒内触发相关的 touchend 事件时,就会发生点击事件。 如果 touchend 事件花费更长的时间来触发,或者如果在两者之间发生了 touchmove 事件,则不将其视为 tap如果您

结论

我希望这可以帮助您了解控件的该部分在 Video.js 中的运作方式,以及如果您正在为 Video.js 构建自己的插件,则可以模拟相同的交互。 始终欢迎反馈。

此致,

-heff