gecko-dev/dom/media/tests/mochitest/test_getUserMedia_basicScre...

217 строки
9.0 KiB
HTML

<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="/tests/dom/canvas/test/captureStream_common.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
title: "getUserMedia Basic Screenshare Test",
bug: "1211656",
visible: true,
});
let verifyScreenshare = async (video, helper, upleft, upright, downleft, downright) => {
if (video.readyState < video.HAVE_CURRENT_DATA) {
info("Waiting for data");
await new Promise(r => video.addEventListener("loadeddata", r, {once: true}));
}
// We assume video size will not change. Offsets help to account for a
// square fullscreen-canvas, while the screen is rectangular.
let offsetX = Math.max(0, video.videoWidth - video.videoHeight) / 2;
let offsetY = Math.max(0, video.videoHeight - video.videoWidth) / 2;
let verifyAround = async (internalX, internalY, color) => {
// Pick a couple of samples around a coordinate to check for a color.
// We check multiple rows and columns, to avoid most artifact issues.
let areaSamples = [
{dx: 0, dy: 0},
{dx: 1, dy: 3},
{dx: 8, dy: 5},
];
for (let {dx, dy} of areaSamples) {
let x = offsetX + dx + internalX;
let y = offsetY + dy + internalY;
info("Checking screen coordinate (" + [x,y] + ") of total resolution "
+ video.videoWidth + "x" + video.videoHeight
+ " against " + color.name + ".");
await helper.waitForPixel(video, px => {
let result = helper.isPixel(px, color, 16);
info("Checking pixel against " + color.name + ". Got ["
+ Array.from(px) + "] (" + (result ? "YES" : "NO") + ")");
return result;
}, {offsetX: x, offsetY: y});
}
};
let screenSizeSq = Math.min(video.videoWidth, video.videoHeight);
info("Waiting for upper left quadrant to become " + upleft.name);
await verifyAround(screenSizeSq / 4, screenSizeSq / 4, upleft);
info("Waiting for upper right quadrant to become " + upright.name);
await verifyAround(screenSizeSq * 3 / 4, screenSizeSq / 4, upright);
info("Waiting for lower left quadrant to become " + downleft.name);
await verifyAround(screenSizeSq / 4, screenSizeSq * 3 / 4, downleft);
info("Waiting for lower right quadrant to become " + downright.name);
await verifyAround(screenSizeSq * 3 / 4, screenSizeSq * 3 / 4, downright);
};
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for a screenshare MediaStream on a video HTMLMediaElement.
*/
runTest(async function () {
await pushPrefs(
["full-screen-api.enabled", true],
["full-screen-api.allow-trusted-requests-only", false],
["full-screen-api.transition-duration.enter", "0 0"],
["full-screen-api.transition-duration.leave", "0 0"],
);
let testVideo = createMediaElement('video', 'testVideo');
let canvas = document.createElement("canvas");
canvas.width = canvas.height = 20;
document.getElementById("content").appendChild(canvas);
let draw = (upleft, upright, downleft, downright) => {
helper.drawColor(canvas, upleft, {offsetX: 0, offsetY: 0});
helper.drawColor(canvas, upright, {offsetX: 10, offsetY: 0});
helper.drawColor(canvas, downleft, {offsetX: 0, offsetY: 10});
helper.drawColor(canvas, downright, {offsetX: 10, offsetY: 10});
};
let helper = new CaptureStreamTestHelper2D(1, 1);
await new Promise((resolve, reject) => {
SpecialPowers.wrap(document).onfullscreenchange = resolve;
SpecialPowers.wrap(document).onfullscreenerror = () => reject(new Error("fullscreenerror"));
// Note that going fullscreen requires the tab (and window) to be in the
// foreground and having focus.
SpecialPowers.wrap(canvas).requestFullscreen();
});
info("Testing screenshare without constraints");
let stream = await getUserMedia({video: {mediaSource: "screen"}});
let settings = stream.getTracks()[0].getSettings();
ok(settings.width <= 8192,
`Width setting ${settings.width} should be set after gUM (or 0 per bug 1453247)`);
ok(settings.height <= 8192,
`Height setting ${settings.height} should be set after gUM (or 0 per bug 1453247)`);
draw(helper.red, helper.blue,
helper.green, helper.grey);
let playback = new MediaStreamPlayback(testVideo, stream);
playback.startMedia();
await playback.verifyPlaying();
settings = stream.getTracks()[0].getSettings();
is(settings.width, testVideo.videoWidth,
"Width setting should match video width");
is(settings.height, testVideo.videoHeight,
"Height setting should match video height");
let screenWidth = testVideo.videoWidth;
let screenHeight = testVideo.videoHeight;
await verifyScreenshare(testVideo, helper,
helper.red, helper.blue,
helper.green, helper.grey);
for (let track of stream.getTracks()) {
track.stop();
}
playback.detachFromMediaElement();
info("Testing screenshare with size and framerate constraints");
stream = await getUserMedia({
video: {
mediaSource: 'screen',
width: {
min: '10',
max: '100'
},
height: {
min: '10',
max: '100'
},
frameRate: {
min: '10',
max: '15'
},
},
});
settings = stream.getTracks()[0].getSettings();
ok(settings.width == 0 || (settings.width >= 10 && settings.width <= 100),
`Width setting ${settings.width} should be correct after gUM (or 0 per bug 1453247)`);
ok(settings.height == 0 || (settings.height >= 10 && settings.height <= 100),
`Height setting ${settings.height} should be correct after gUM (or 0 per bug 1453247)`);
draw(helper.green, helper.red,
helper.grey, helper.blue);
playback = new MediaStreamPlayback(testVideo, stream);
playback.startMedia();
await playback.verifyPlaying();
settings = stream.getTracks()[0].getSettings();
ok(settings.width >= 10 && settings.width <= 100,
`Width setting ${settings.width} should be within constraints`);
ok(settings.height >= 10 && settings.height <= 100,
`Height setting ${settings.height} should be within constraints`);
is(settings.width, testVideo.videoWidth,
"Width setting should match video width");
is(settings.height, testVideo.videoHeight,
"Height setting should match video height");
let expectedHeight = (screenHeight * settings.width) / screenWidth;
ok(Math.abs(expectedHeight - settings.height) <= 1,
"Aspect ratio after constrained gUM should be close enough");
await verifyScreenshare(testVideo, helper,
helper.green, helper.red,
helper.grey, helper.blue);
info("Testing modifying screenshare with applyConstraints");
let resize = haveEvent(testVideo, "resize", wait(5000, new Error("Timeout")));
await testVideo.srcObject.getVideoTracks()[0].applyConstraints({
mediaSource: 'screen',
width: 200,
height: 200,
frameRate: {
min: '5',
max: '10'
}
});
// getSettings() should report correct size as soon as applyConstraints()
// resolves - bug 1453259. Until fixed, check that we at least report
// something sane.
let newSettings = stream.getTracks()[0].getSettings();
ok(newSettings.width > settings.width && newSettings.width < screenWidth,
`Width setting ${newSettings.width} should have increased after applyConstraints`);
ok(newSettings.height > settings.height && newSettings.height < screenHeight,
`Height setting ${newSettings.height} should have increased after applyConstraints`);
await resize;
settings = stream.getTracks()[0].getSettings();
ok(settings.width > 100 && settings.width < screenWidth,
`Width setting ${settings.width} should have increased after first frame after applyConstraints`);
ok(settings.height > 100 && settings.height < screenHeight,
`Height setting ${settings.height} should have increased after first frame after applyConstraints`);
is(settings.width, testVideo.videoWidth,
"Width setting should match video width");
is(settings.height, testVideo.videoHeight,
"Height setting should match video height");
expectedHeight = (screenHeight * settings.width) / screenWidth;
ok(Math.abs(expectedHeight - settings.height) <= 1,
"Aspect ratio after applying constraints should be close enough");
draw(helper.grey, helper.green,
helper.blue, helper.red);
await playback.verifyPlaying(); // still playing
await verifyScreenshare(testVideo, helper,
helper.grey, helper.green,
helper.blue, helper.red);
await playback.stopTracksForStreamInMediaPlayback();
playback.detachFromMediaElement();
SpecialPowers.wrap(document).exitFullscreen();
});
</script>
</pre>
</body>
</html>