summaryrefslogtreecommitdiffstats
path: root/dom/media/test/test_playback_rate.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/media/test/test_playback_rate.html175
1 files changed, 175 insertions, 0 deletions
diff --git a/dom/media/test/test_playback_rate.html b/dom/media/test/test_playback_rate.html
new file mode 100644
index 0000000000..b44ebe27ee
--- /dev/null
+++ b/dom/media/test/test_playback_rate.html
@@ -0,0 +1,175 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for the playbackRate property </title>
+ <script 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.preservesPitch = false;
+ is(t.preservesPitch, 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.preservesPitch, 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>