diff options
Diffstat (limited to 'dom/media/test/test_playback_rate.html')
-rw-r--r-- | dom/media/test/test_playback_rate.html | 175 |
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> |