DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
<!DOCTYPE HTML>
<html>
<head>
  <title>Test for the playbackRate property </title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
  <script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type='application/javascript'>

let manager = new MediaTestManager;

function rangeCheck(lhs, rhs, threshold) {
  var diff = Math.abs(lhs - rhs);
  if (diff < threshold) {
    return true;
  }
  return false;
}

function checkPlaybackRate(wallclock, media, expected, threshold) {
  if (rangeCheck(media / wallclock, expected, threshold)) {
    return true;
  }
  return false;
}

// Those value are expected to match those at the top of HTMLMediaElement.cpp.
let VERY_SLOW_RATE = 1 / 32,
    SLOW_RATE = 1 / 16,
    FAST_RATE = 16,
    VERY_FAST_RATE = 20,
    NULL_RATE = 0.0;

function ontimeupdate(e) {
  var t = e.target;
  // Skip short files for SoundTouch doesn't work well on small number of samples.
  if (t.gotEnded || t.duration < 2) {
    return;
  }
  t.testedForSlowdown = true;
  if (t.currentTime > t.duration / 2) {
    t.oldCurrentTime = t.currentTime;
    t.timestamp = Date.now();
    var delta = t.oldCurrentTime,
        delta_wallclock = (t.timestamp - t.startTimestamp - t.bufferingTime) / 1000;

    t.mozPreservesPitch = false;
    is(t.mozPreservesPitch, false, t.name + ": If we disable the pitch preservation, it should appear as such.");

    t.bufferingTime = 0;

    is(t.playbackRate, SLOW_RATE, t.name + ": The playback rate shoud be "+SLOW_RATE+".");
    ok(checkPlaybackRate(delta_wallclock, delta, SLOW_RATE, 0.25), t.name + ": We are effectively slowing down playback. (" + delta_wallclock + ", " + delta + ")");
    t.removeEventListener("timeupdate", ontimeupdate);
    t.addEventListener("pause", onpaused);
    t.playbackRate = NULL_RATE;
    t.oldCurrentTime = t.currentTime;
    setTimeout(function() {
      afterNullPlaybackRate(e);
    }, 100);
  }
}

function onpaused(e) {
  var t = e.target;
  t.pausedReceived = true;
}

function afterNullPlaybackRate(e) {
  var t = e.target;

  // skip if we have received 'ended' event or 'ended' event is pending.
  if (t.gotEnded || t.ended) {
    return;
  }

  t.testedForNull = true;

  ok(t.currentTime == t.oldCurrentTime, t.name + ": Current time should not change when playbackRate is null (" + t.currentTime + " " + t.oldCurrentTime + ").");
  ok(!t.paused, t.name + ": The element should not be in paused state.");
  t.removeEventListener("paused", onpaused);
  is(t.pausedReceived, undefined, t.name + ": Paused event should not have been received.");
  t.timestamp = Date.now();
  t.oldCurrentTime = t.currentTime;
  t.playbackRate = VERY_FAST_RATE;
  is(t.playbackRate, VERY_FAST_RATE, t.name + ": Playback rate should be clamped to " + VERY_FAST_RATE + ".");
}

function onended(e) {
  var t = e.target;
  t.gotEnded = true;

  t.bufferingTime = 0;
  // If we got "ended" too early, skip these tests.
  if (t.testedForSlowdown && t.testedForNull) {
    is(t.playbackRate, FAST_RATE, t.name + ": The playback rate should still be "+FAST_RATE+".");
    ok(!t.muted, t.name + ": The audio should be muted when playing at high speed, but should not appear as such.");
    is(t.currentTime, t.duration, t.name + ": Current time should be equal to the duration (not change by playback rate).");
  }
  finish_test(t);
}

function onratechange(e) {
  if (!e.target.ratechangecount) {
    e.target.ratechangecount = 0;
  }
  e.target.ratechangecount++;
}

function finish_test(element) {
  removeNodeAndSource(element);
  manager.finished(element.token);
}

// These two functions handle the case when the playback pauses for buffering. It
// adjusts the timestamps to be accurate. Despite the fact that the web servers
// is supposed to be on the same machine, buffering pauses can occur (rarely,
// but still).
function onplaying(e) {
  var t = e.target;
  if (t.bufferingTimestamp != undefined) {
    t.bufferingTime += (Date.now() - t.bufferingTimestamp);
    t.bufferingTimestamp = undefined;
  }
}

function onwaiting(e) {
  var t = e.target;
  t.bufferingTimestamp = Date.now();
}

function onvolumechange(e) {
  ok(false, e.target.name + ": We should not receive a volumechange event when changing the playback rate.");
}

function startTest(test, token) {
  let elemType = /^audio/.test(test.type) ? "audio" : "video";
  let element = document.createElement(elemType);
  element.src = test.name;
  element.name = test.name;
  element.preload = "metadata";
  element.token = token;
  element.controls = true;
  element.bufferingTime = 0;
  document.body.appendChild(element);
  element.addEventListener("ratechange", onratechange);
  element.addEventListener("timeupdate", ontimeupdate);
  element.addEventListener("ended", onended);
  element.addEventListener("waiting", onwaiting);
  element.addEventListener("playing", onplaying);
  element.addEventListener("volumechange", onvolumechange);
  manager.started(token);
  element.startTimestamp = Date.now();
  is(element.mozPreservesPitch, true, test.name + ": Pitch preservation should be enabled by default.");
  element.addEventListener("loadedmetadata", function() {
    is(element.playbackRate, 1.0, test.name + ": playbackRate should be initially 1.0");
    is(element.defaultPlaybackRate, 1.0, test.name + ": defaultPlaybackRate should be initially 1.0");
    element.playbackRate = VERY_SLOW_RATE;
    is(element.playbackRate, VERY_SLOW_RATE, test.name + ": PlaybackRate should be " + VERY_SLOW_RATE + ".");
    element.play();
    element.playbackRate = SLOW_RATE;
  });
}

manager.runTests(gPlayedTests, startTest);

</script>
</pre>
<div id="elements">
</div>
</body>
</html>