content/media/test/test_playback_rate.html

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

michael@0 1 <!DOCTYPE HTML>
michael@0 2 <html>
michael@0 3 <head>
michael@0 4 <title>Test for the playbackRate property </title>
michael@0 5 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
michael@0 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
michael@0 7 <script type="text/javascript" src="manifest.js"></script>
michael@0 8 </head>
michael@0 9 <body>
michael@0 10 <pre id="test">
michael@0 11 <script class="testbody" type='application/javascript;version=1.8'>
michael@0 12
michael@0 13 SimpleTest.expectAssertions(0, 2);
michael@0 14
michael@0 15 if (navigator.platform.startsWith("Win")) {
michael@0 16 SimpleTest.expectAssertions(0, 1);
michael@0 17 } else if (navigator.platform.startsWith("Mac")) {
michael@0 18 SimpleTest.expectAssertions(0, 2);
michael@0 19 }
michael@0 20
michael@0 21 let manager = new MediaTestManager;
michael@0 22
michael@0 23 function rangeCheck(lhs, rhs, threshold) {
michael@0 24 var diff = Math.abs(lhs - rhs);
michael@0 25 if (diff < threshold) {
michael@0 26 return true;
michael@0 27 }
michael@0 28 return false;
michael@0 29 }
michael@0 30
michael@0 31 function checkPlaybackRate(wallclock, media, expected, threshold) {
michael@0 32 if (rangeCheck(media / wallclock, expected, threshold)) {
michael@0 33 return true;
michael@0 34 }
michael@0 35 return false;
michael@0 36 }
michael@0 37
michael@0 38 // Those value are expected to match those at the top of HTMLMediaElement.cpp.
michael@0 39 let VERY_SLOW_RATE = 0.1,
michael@0 40 SLOW_RATE = 0.25,
michael@0 41 FAST_RATE = 5,
michael@0 42 VERY_FAST_RATE = 20,
michael@0 43 NULL_RATE = 0.0;
michael@0 44
michael@0 45 function ontimeupdate(e) {
michael@0 46 var t = e.target;
michael@0 47 if (t.gotEnded) {
michael@0 48 return;
michael@0 49 }
michael@0 50 t.testedForSlowdown = true;
michael@0 51 if (t.currentTime > t.duration / 2) {
michael@0 52 t.oldCurrentTime = t.currentTime;
michael@0 53 t.timestamp = Date.now();
michael@0 54 var delta = t.oldCurrentTime,
michael@0 55 delta_wallclock = (t.timestamp - t.startTimestamp - t.bufferingTime) / 1000;
michael@0 56
michael@0 57 t.mozPreservesPitch = false;
michael@0 58 is(t.mozPreservesPitch, false, "If we disable the pitch preservation, it should appear as such.");
michael@0 59
michael@0 60 t.bufferingTime = 0;
michael@0 61
michael@0 62 is(t.playbackRate, SLOW_RATE,
michael@0 63 "The playback rate shoud be "+SLOW_RATE+"." + t.token);
michael@0 64 ok(checkPlaybackRate(delta_wallclock, delta, SLOW_RATE, 0.25), "We are effectively slowing down playback. (" + delta_wallclock + ", " + delta + ") for " + t.token);
michael@0 65 t.removeEventListener("timeupdate", ontimeupdate);
michael@0 66 t.addEventListener("pause", onpaused);
michael@0 67 t.playbackRate = NULL_RATE;
michael@0 68 t.oldCurrentTime = t.currentTime;
michael@0 69 setTimeout(function() {
michael@0 70 afterNullPlaybackRate(e);
michael@0 71 }, 100);
michael@0 72 }
michael@0 73 }
michael@0 74
michael@0 75 function onpaused(e) {
michael@0 76 var t = e.target;
michael@0 77 t.pausedReceived = true;
michael@0 78 }
michael@0 79
michael@0 80 function afterNullPlaybackRate(e) {
michael@0 81 var t = e.target;
michael@0 82
michael@0 83 t.testedForNull = true;
michael@0 84
michael@0 85 if (t.gotEnded) {
michael@0 86 return;
michael@0 87 }
michael@0 88 // The currentTime won't be perfectly equal because of the latency
michael@0 89 // compensation. We expect no more that 300ms difference.
michael@0 90 let THRESHOLD = 0.3;
michael@0 91 ok(rangeCheck(t.currentTime, t.oldCurrentTime, THRESHOLD), "Current time should not change when playbackRate is null (" + t.currentTime + " " + t.oldCurrentTime + ").");
michael@0 92 ok(!t.paused, "The element should not be in paused state.");
michael@0 93 t.removeEventListener("paused", onpaused);
michael@0 94 is(t.pausedReceived, undefined, "Paused event should not have been received.");
michael@0 95 t.timestamp = Date.now();
michael@0 96 t.oldCurrentTime = t.currentTime;
michael@0 97 t.playbackRate = VERY_FAST_RATE;
michael@0 98 is(t.playbackRate, FAST_RATE, "Playback rate should be clamped to " + FAST_RATE + ".");
michael@0 99 }
michael@0 100
michael@0 101 function onended(e) {
michael@0 102 var t = e.target,
michael@0 103 playtime = (Date.now() - t.timestamp - t.bufferingTime) / 1000,
michael@0 104 mediaTime = t.duration - t.oldCurrentTime;
michael@0 105
michael@0 106 if (!(t.testedForSlowdown && t.testedForNull)) {
michael@0 107 t.gotEnded = true;
michael@0 108 t.skippedFastPart = true;
michael@0 109 }
michael@0 110
michael@0 111 t.bufferingTime = 0;
michael@0 112 // We got "ended" too early, skip these tests.
michael@0 113 if (t.testedForSlowdown && t.testedForNull) {
michael@0 114 is(t.playbackRate, FAST_RATE, "The playback rate should still be "+FAST_RATE+".");
michael@0 115 ok(!t.muted, "The audio should be muted when playing at high speed, but should not appear as such.");
michael@0 116 is(t.currentTime, t.duration, "Current time should be equal to the duration (not change by playback rate).");
michael@0 117 }
michael@0 118 finish_test(t);
michael@0 119 }
michael@0 120
michael@0 121 function onratechange(e) {
michael@0 122 if (!e.target.ratechangecount) {
michael@0 123 e.target.ratechangecount = 0;
michael@0 124 }
michael@0 125 e.target.ratechangecount++;
michael@0 126 }
michael@0 127
michael@0 128 function finish_test(element) {
michael@0 129 if (element.parentNode)
michael@0 130 element.parentNode.removeChild(element);
michael@0 131 element.src="";
michael@0 132 manager.finished(element.token);
michael@0 133 }
michael@0 134
michael@0 135 // These two functions handle the case when the playback pauses for buffering. It
michael@0 136 // adjusts the timestamps to be accurate. Despite the fact that the web servers
michael@0 137 // is supposed to be on the same machine, buffering pauses can occur (rarely,
michael@0 138 // but still).
michael@0 139 function onplaying(e) {
michael@0 140 var t = e.target;
michael@0 141 if (t.bufferingTimestamp != undefined) {
michael@0 142 t.bufferingTime += (Date.now() - t.bufferingTimestamp);
michael@0 143 t.bufferingTimestamp = undefined;
michael@0 144 }
michael@0 145 }
michael@0 146
michael@0 147 function onwaiting(e) {
michael@0 148 var t = e.target;
michael@0 149 t.bufferingTimestamp = Date.now();
michael@0 150 }
michael@0 151
michael@0 152 function onvolumechange(e) {
michael@0 153 ok(false, "We should not receive a volumechange event when changing the playback rate.");
michael@0 154 }
michael@0 155
michael@0 156 function startTest(test, token) {
michael@0 157 let elemType = /^audio/.test(test.type) ? "audio" : "video";
michael@0 158 let element = document.createElement(elemType);
michael@0 159 element.src = test.name;
michael@0 160 element.preload = "metadata";
michael@0 161 element.token = token;
michael@0 162 element.controls = true;
michael@0 163 element.bufferingTime = 0;
michael@0 164 document.body.appendChild(element);
michael@0 165 element.addEventListener("ratechange", onratechange);
michael@0 166 element.addEventListener("timeupdate", ontimeupdate);
michael@0 167 element.addEventListener("ended", onended);
michael@0 168 element.addEventListener("waiting", onwaiting);
michael@0 169 element.addEventListener("playing", onplaying);
michael@0 170 element.addEventListener("volumechange", onvolumechange);
michael@0 171 manager.started(token);
michael@0 172 element.startTimestamp = Date.now();
michael@0 173 is(element.mozPreservesPitch, true, "Pitch preservation should be enabled by default.");
michael@0 174 element.addEventListener("loadedmetadata", function() {
michael@0 175 is(element.playbackRate, 1.0, "playbackRate should be initially 1.0");
michael@0 176 is(element.defaultPlaybackRate, 1.0, "defaultPlaybackRate should be initially 1.0");
michael@0 177 element.playbackRate = VERY_SLOW_RATE;
michael@0 178 is(element.playbackRate, SLOW_RATE, "PlaybackRate should be clamped to " + SLOW_RATE + ".");
michael@0 179 element.play();
michael@0 180 element.playbackRate = SLOW_RATE;
michael@0 181 });
michael@0 182 }
michael@0 183
michael@0 184 manager.runTests(gPlayedTests, startTest);
michael@0 185
michael@0 186 </script>
michael@0 187 </pre>
michael@0 188 <div id="elements">
michael@0 189 </div>
michael@0 190 </body>
michael@0 191 </html>

mercurial