简体   繁体   中英

How can I wrap the HTML5 video element's currentTime property?

I'm developing a video player as part of a learning module system. Certain modules require that the user not be able to (easily) skip ahead in the video. I understand that this would normally be considered a bad user experience, but it's essential in this case.

I've been able to override the video.currentTime property by doing the following. It prevents skipping, but I need to be able to turn it on and off conditionally.

Object.defineProperty(videoElement, 'currentTime', {
  enumerable: true,
  configurable: true,
  get: function() {
    // return from original currentTime
  },
  set: function(newValue) {
    // intercept values here
  }
});

how I can reference the original video.currentTime property in my getter and setter? Unfortunately, Object.getOwnPropertyDescriptor(videoElement, 'currentTime'); returns undefined .

There may be a more elegant way to do this, but calling the currentTime getter of the prototype (in this case the HTMLMediaElement prototype) on your object will give you the actual currentTime. So this will prevent setting but allow getting:

  Object.defineProperty(videoElement, 'currentTime', {
      enumerable: true,
      configurable: true,
      get: function() {
        var ct = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype,
           'currentTime').get.call(this);
        return ct;
      },
      set: function(newValue) {
        // intercept values here
      }
    });

If disabling seeking (skipping) is what you want to do then here is my solution:

var video = document.getElementById('video');
var supposedCurrentTime = 0;
video.addEventListener('timeupdate', function() {
  if (!video.seeking) {
        supposedCurrentTime = video.currentTime;
  }
});
// prevent user from seeking
video.addEventListener('seeking', function() {
  // guard agains infinite recursion:
  // user seeks, seeking is fired, currentTime is modified, seeking is fired, current time is modified, ....
  var delta = video.currentTime - supposedCurrentTime;
  if (Math.abs(delta) > 0.01) {
    console.log("Seeking is disabled");
    video.currentTime = supposedCurrentTime;
  }
});
// delete the following event handler if rewind is not required
video.addEventListener('ended', function() {
  // reset state in order to allow for rewind
    supposedCurrentTime = 0;
});

This code simply restores video.currentTime to its last known value when seeking. This effectively cancels the seeking process. There is no need to override/wrap currentTime.

The problem with wrapping currentTime is that if a user is smart enough to select the video element and set its currentTime property then may be the user is smart enough to call:

Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype,
       'currentTime').set.call(videoElement, videoElement.duration);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM