chromium/chrome/test/data/media/html/media_scrub.html

<!-- Used by media_scrub_perf to record scrubbing perf metrics. -->
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>Scrubbing Tests</title>
    <script src="utils.js" type="text/javascript"></script>
  </head>
  <body>
    <label for="src">Video src (direct link to media file):</label>
    <input id="src" type="text" size="64">
    <button onclick="startTest(document.querySelector('input').value);">
      Start
    </button>
    <p>
      <video controls></video><br>
      Forward scrubbing time: <span id="forwardScrub"></span><br>
      Backward scrubbing time: <span id="backwardScrub"></span><br>
      Mixed scrubbing time: <span id="mixedScrub"></span><br>
      <span id="logs"></span>
    </p>
  <script type="text/javascript">
    // Number of seeks per scrub.
    var SCRUBS = 100;
    // The delta between 2 scrubs in secs.
    var SCRUB_DELTA = 0.1;
    // Used by pyauto tests to store the scrubbing times.
    var forwardScrubTime = backwardScrubTime = mixedScrubTime = 0;
    // Used for each scrub test based on buffered area.
    var startTime = endTime = 0;
    // Used by PyAuto to log any error message.
    var errorMsg = '';
    // Used by PyAuto to indicate when the test is done.
    var testDone = false;
    // Timer used to measure scrubbing performance.
    var timer = new Timer();
    // Indicates the current scrubbing direction performed.
    var currentDirection = null;
    // Indicates the expected time of video when each scrub ends.  This is the
    // final seek time each test performs.
    // Make sure none of the scrubs overlap this time.
    var EXPECTED_SCRUB_END_TIME = 0.01;
    // Seek is not 100% accurate so we need delta in secs where currentTime of
    // video can vary from its expected time.
    var DELTA = 0.0001;

    var Direction = {
      FORWARD: 0,
      BACKWARD: 1,
      MIXED: 2,
      NO_DIRECTION: 3
    };

    function log(text) {
      logs.innerText += text + '\n';
    }

    function getAndClearElement(id) {
      var elem = document.getElementById(id);
      elem.innerText = '';
      return elem;
    }

    function onCanplaythrough() {
      startTime = video.buffered.start(0) + SCRUB_DELTA;
      endTime = startTime + SCRUBS * SCRUB_DELTA;
      log('Video duration: ' + video.duration + ' secs');
      log('Scrubbing area: (' + startTime + ', ' + endTime + ')');
      currentDirection = Direction.FORWARD;
      startScrubTest();
    }

    function startScrubTest() {
      timer.start();
      switch (currentDirection) {
        case Direction.FORWARD:
          video.currentTime = startTime;
          scrub(Direction.FORWARD, SCRUBS);
          break;
        case Direction.BACKWARD:
          video.currentTime = endTime;
          scrub(Direction.BACKWARD, SCRUBS);
          break;
        case Direction.MIXED:
          video.currentTime = (startTime + endTime) / 2;
          var shortScrubs = 6;
          for (t = 0; t < shortScrubs; ++t) {
            if (t % 2)
              scrub(Direction.BACKWARD, SCRUBS / shortScrubs);
            else
              scrub(Direction.FORWARD, SCRUBS / shortScrubs);
          }
          break;
        case Direction.NO_DIRECTION:
          endTest();
          video.removeEventListener('seeked', seeked, false);
          return;
      }
      // After each scrub, seek to the expected end time.
      video.currentTime = EXPECTED_SCRUB_END_TIME;
    }

    function scrub(direction, scrubs) {
      for (var t = 0; t < scrubs; ++t) {
        if (direction == Direction.BACKWARD)
          video.currentTime -= SCRUB_DELTA;
        else if (direction == Direction.FORWARD)
          video.currentTime += SCRUB_DELTA;
      }
    }

    function seeked() {
      if (Math.abs(video.currentTime - EXPECTED_SCRUB_END_TIME) < DELTA) {
        logScrubTime();
        // Update to next scrubbing direction.
        currentDirection++;
        startScrubTest();
      }
    }

    function logScrubTime() {
      delta = Math.round(timer.stop(), 0);
      var scrubElem = null;
      if (currentDirection == Direction.FORWARD) {
        scrubElem = getAndClearElement('forwardScrub');
        forwardScrubTime = delta;
      } else if (currentDirection == Direction.BACKWARD) {
        scrubElem = getAndClearElement('backwardScrub');
        backwardScrubTime = delta;
      } else {
        scrubElem = getAndClearElement('mixedScrub');
        mixedScrubTime = delta;
      }
      scrubElem.innerText = delta + ' ms';
    }

    function end(msg) {
      errorMsg = msg;
      log(msg);
      endTest();
    }

    function endTest() {
      testDone = true;
    }

    // Called by the PyAuto controller to initiate testing.
    function startTest(src) {
      video = document.querySelector('video');
      logs = getAndClearElement('logs');
      errorMsg = '';
      testDone = false;
      forwardScrubTime = backwardScrubTime = mixedScrubTime = 0;

      video.addEventListener('seeked', seeked);
      video.addEventListener('canplaythrough', onCanplaythrough);
      video.addEventListener('error', function() {
        end('Error loading media: ' + video.error.code);
      });
      video.src = src;

      if (window.domAutomationController)
        window.domAutomationController.send(true);
    }
  </script>
  </body>
</html>