1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/test/test_playback_rate.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,191 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<head> 1.7 + <title>Test for the playbackRate property </title> 1.8 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.9 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.10 + <script type="text/javascript" src="manifest.js"></script> 1.11 +</head> 1.12 +<body> 1.13 +<pre id="test"> 1.14 +<script class="testbody" type='application/javascript;version=1.8'> 1.15 + 1.16 +SimpleTest.expectAssertions(0, 2); 1.17 + 1.18 +if (navigator.platform.startsWith("Win")) { 1.19 + SimpleTest.expectAssertions(0, 1); 1.20 +} else if (navigator.platform.startsWith("Mac")) { 1.21 + SimpleTest.expectAssertions(0, 2); 1.22 +} 1.23 + 1.24 +let manager = new MediaTestManager; 1.25 + 1.26 +function rangeCheck(lhs, rhs, threshold) { 1.27 + var diff = Math.abs(lhs - rhs); 1.28 + if (diff < threshold) { 1.29 + return true; 1.30 + } 1.31 + return false; 1.32 +} 1.33 + 1.34 +function checkPlaybackRate(wallclock, media, expected, threshold) { 1.35 + if (rangeCheck(media / wallclock, expected, threshold)) { 1.36 + return true; 1.37 + } 1.38 + return false; 1.39 +} 1.40 + 1.41 +// Those value are expected to match those at the top of HTMLMediaElement.cpp. 1.42 +let VERY_SLOW_RATE = 0.1, 1.43 + SLOW_RATE = 0.25, 1.44 + FAST_RATE = 5, 1.45 + VERY_FAST_RATE = 20, 1.46 + NULL_RATE = 0.0; 1.47 + 1.48 +function ontimeupdate(e) { 1.49 + var t = e.target; 1.50 + if (t.gotEnded) { 1.51 + return; 1.52 + } 1.53 + t.testedForSlowdown = true; 1.54 + if (t.currentTime > t.duration / 2) { 1.55 + t.oldCurrentTime = t.currentTime; 1.56 + t.timestamp = Date.now(); 1.57 + var delta = t.oldCurrentTime, 1.58 + delta_wallclock = (t.timestamp - t.startTimestamp - t.bufferingTime) / 1000; 1.59 + 1.60 + t.mozPreservesPitch = false; 1.61 + is(t.mozPreservesPitch, false, "If we disable the pitch preservation, it should appear as such."); 1.62 + 1.63 + t.bufferingTime = 0; 1.64 + 1.65 + is(t.playbackRate, SLOW_RATE, 1.66 + "The playback rate shoud be "+SLOW_RATE+"." + t.token); 1.67 + ok(checkPlaybackRate(delta_wallclock, delta, SLOW_RATE, 0.25), "We are effectively slowing down playback. (" + delta_wallclock + ", " + delta + ") for " + t.token); 1.68 + t.removeEventListener("timeupdate", ontimeupdate); 1.69 + t.addEventListener("pause", onpaused); 1.70 + t.playbackRate = NULL_RATE; 1.71 + t.oldCurrentTime = t.currentTime; 1.72 + setTimeout(function() { 1.73 + afterNullPlaybackRate(e); 1.74 + }, 100); 1.75 + } 1.76 +} 1.77 + 1.78 +function onpaused(e) { 1.79 + var t = e.target; 1.80 + t.pausedReceived = true; 1.81 +} 1.82 + 1.83 +function afterNullPlaybackRate(e) { 1.84 + var t = e.target; 1.85 + 1.86 + t.testedForNull = true; 1.87 + 1.88 + if (t.gotEnded) { 1.89 + return; 1.90 + } 1.91 + // The currentTime won't be perfectly equal because of the latency 1.92 + // compensation. We expect no more that 300ms difference. 1.93 + let THRESHOLD = 0.3; 1.94 + ok(rangeCheck(t.currentTime, t.oldCurrentTime, THRESHOLD), "Current time should not change when playbackRate is null (" + t.currentTime + " " + t.oldCurrentTime + ")."); 1.95 + ok(!t.paused, "The element should not be in paused state."); 1.96 + t.removeEventListener("paused", onpaused); 1.97 + is(t.pausedReceived, undefined, "Paused event should not have been received."); 1.98 + t.timestamp = Date.now(); 1.99 + t.oldCurrentTime = t.currentTime; 1.100 + t.playbackRate = VERY_FAST_RATE; 1.101 + is(t.playbackRate, FAST_RATE, "Playback rate should be clamped to " + FAST_RATE + "."); 1.102 +} 1.103 + 1.104 +function onended(e) { 1.105 + var t = e.target, 1.106 + playtime = (Date.now() - t.timestamp - t.bufferingTime) / 1000, 1.107 + mediaTime = t.duration - t.oldCurrentTime; 1.108 + 1.109 + if (!(t.testedForSlowdown && t.testedForNull)) { 1.110 + t.gotEnded = true; 1.111 + t.skippedFastPart = true; 1.112 + } 1.113 + 1.114 + t.bufferingTime = 0; 1.115 + // We got "ended" too early, skip these tests. 1.116 + if (t.testedForSlowdown && t.testedForNull) { 1.117 + is(t.playbackRate, FAST_RATE, "The playback rate should still be "+FAST_RATE+"."); 1.118 + ok(!t.muted, "The audio should be muted when playing at high speed, but should not appear as such."); 1.119 + is(t.currentTime, t.duration, "Current time should be equal to the duration (not change by playback rate)."); 1.120 + } 1.121 + finish_test(t); 1.122 +} 1.123 + 1.124 +function onratechange(e) { 1.125 + if (!e.target.ratechangecount) { 1.126 + e.target.ratechangecount = 0; 1.127 + } 1.128 + e.target.ratechangecount++; 1.129 +} 1.130 + 1.131 +function finish_test(element) { 1.132 + if (element.parentNode) 1.133 + element.parentNode.removeChild(element); 1.134 + element.src=""; 1.135 + manager.finished(element.token); 1.136 +} 1.137 + 1.138 +// These two functions handle the case when the playback pauses for buffering. It 1.139 +// adjusts the timestamps to be accurate. Despite the fact that the web servers 1.140 +// is supposed to be on the same machine, buffering pauses can occur (rarely, 1.141 +// but still). 1.142 +function onplaying(e) { 1.143 + var t = e.target; 1.144 + if (t.bufferingTimestamp != undefined) { 1.145 + t.bufferingTime += (Date.now() - t.bufferingTimestamp); 1.146 + t.bufferingTimestamp = undefined; 1.147 + } 1.148 +} 1.149 + 1.150 +function onwaiting(e) { 1.151 + var t = e.target; 1.152 + t.bufferingTimestamp = Date.now(); 1.153 +} 1.154 + 1.155 +function onvolumechange(e) { 1.156 + ok(false, "We should not receive a volumechange event when changing the playback rate."); 1.157 +} 1.158 + 1.159 +function startTest(test, token) { 1.160 + let elemType = /^audio/.test(test.type) ? "audio" : "video"; 1.161 + let element = document.createElement(elemType); 1.162 + element.src = test.name; 1.163 + element.preload = "metadata"; 1.164 + element.token = token; 1.165 + element.controls = true; 1.166 + element.bufferingTime = 0; 1.167 + document.body.appendChild(element); 1.168 + element.addEventListener("ratechange", onratechange); 1.169 + element.addEventListener("timeupdate", ontimeupdate); 1.170 + element.addEventListener("ended", onended); 1.171 + element.addEventListener("waiting", onwaiting); 1.172 + element.addEventListener("playing", onplaying); 1.173 + element.addEventListener("volumechange", onvolumechange); 1.174 + manager.started(token); 1.175 + element.startTimestamp = Date.now(); 1.176 + is(element.mozPreservesPitch, true, "Pitch preservation should be enabled by default."); 1.177 + element.addEventListener("loadedmetadata", function() { 1.178 + is(element.playbackRate, 1.0, "playbackRate should be initially 1.0"); 1.179 + is(element.defaultPlaybackRate, 1.0, "defaultPlaybackRate should be initially 1.0"); 1.180 + element.playbackRate = VERY_SLOW_RATE; 1.181 + is(element.playbackRate, SLOW_RATE, "PlaybackRate should be clamped to " + SLOW_RATE + "."); 1.182 + element.play(); 1.183 + element.playbackRate = SLOW_RATE; 1.184 + }); 1.185 +} 1.186 + 1.187 +manager.runTests(gPlayedTests, startTest); 1.188 + 1.189 +</script> 1.190 +</pre> 1.191 +<div id="elements"> 1.192 +</div> 1.193 +</body> 1.194 +</html>