constructor(video, onSeek, onStarted, getStartTime) {
    /** @private {HTMLMediaElement} */
    this.video_ = video;

    /** @private {function()} */
    this.onSeek_ = onSeek;

    /** @private {function(number)} */
    this.onStarted_ = onStarted;

    /** @private {?number} */
    this.startTime_ = null;

    /** @private {function():number} */
    this.getStartTime_ = () => {
      if (this.startTime_ == null) {
        this.startTime_ = getStartTime();
      }
      return this.startTime_;
    };

    /** @private {boolean} */
    this.started_ = false;

    /** @private {shaka.util.EventManager} */
    this.eventManager_ = new shaka.util.EventManager();

    /** @private {shaka.media.VideoWrapper.PlayheadMover} */
    this.mover_ = new shaka.media.VideoWrapper.PlayheadMover(
        /* mediaElement= */ video,
        /* maxAttempts= */ 10);

    // Before we can set the start time, we must check if the video element is
    // ready. If the video element is not ready, we cannot set the time. To work
    // around this, we will wait for the "loadedmetadata" event which tells us
    // that the media element is now ready.
    shaka.util.MediaReadyState.waitForReadyState(this.video_,
        HTMLMediaElement.HAVE_METADATA,
        this.eventManager_,
        () => {
          this.setStartTime_(this.getStartTime_());
        });
  }
@param {!HTMLMediaElement} video
@param {function()} onSeek Called when the video seeks.
@param {function(number)} onStarted Called when the video has started.
@param {function():number} getStartTime Called to get the time to start at.