зеркало из https://github.com/mozilla/gecko-dev.git
217 строки
9.0 KiB
HTML
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>
|