Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DOM examples for Screen Capture API #285

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ Code examples that accompany various MDN DOM and Web API documentation pages.

- The "resize-event" directory contains a basic demo to show how you can use the [resize event](https://developer.mozilla.org/docs/Web/API/Window/resize_event). Resize the browser window either by height or width to see the size of your current window. [Run the demo live](https://mdn.github.io/dom-examples/resize-event).

- The "screen-capture-api" directory contains demos to show typical usage of the [Screen Capture API](https://developer.mozilla.org/docs/Web/API/Screen_Capture_API) and [Screen Capture Extensions](https://developer.mozilla.org/docs/Web/API/Screen_Capture_extensions).

- The "screenleft-screentop" directory contains a demo to show how you could use the [Window.screenLeft](https://developer.mozilla.org/docs/Web/API/Window/screenLeft) and [Window.screenTop](https://developer.mozilla.org/docs/Web/API/Window/screenTop) properties to draw a circle on a canvas that always stays in the same physical place on the screen when you move your browser window. [Run the demo live](https://mdn.github.io/dom-examples/screenleft-screentop/).

- The "scrolltooptions" directory contains a demo to show how you could use the [ScrollToOptions](https://developer.mozilla.org/docs/Web/API/ScrollToOptions) dictionary along with the [Window.ScrollTo()](https://developer.mozilla.org/docs/Web/API/Window/scrollTo) method to programmatically scroll a web page. [Run the demo live](https://mdn.github.io/dom-examples/scrolltooptions/).
Expand Down
5 changes: 5 additions & 0 deletions screen-capture-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Screen Capture API examples

- [Screen Capture API example](https://mdn.github.io/dom-examples/screen-capture-api/basic-screen-capture): A basic example showing how to use the [Screen Capture API](https://developer.mozilla.org/docs/Web/API/Screen_Capture_API) to capture a surface (such as a window or tab) and broadcast the resulting stream in a `<video>` element.
- [Element Capture API example](https://mdn.github.io/dom-examples/screen-capture-api/element-capture): The same example, but this time using the [Element Capture API](https://developer.mozilla.org/docs/Web/API/Screen_Capture_extensions/Element_Region_Capture#the_element_capture_api) to restrict the broadcast stream to one particular rendered element inside the same tab the app is running in.
- [Region Capture API example](https://mdn.github.io/dom-examples/screen-capture-api/region-capture): The same example, but this time using the [Region Capture API](https://developer.mozilla.org/docs/Web/API/Screen_Capture_extensions/Element_Region_Capture#the_region_capture_api) to crop the broadcast stream to the screen area in which one particular element is rendered, inside the same tab the app is running in.
bsmth marked this conversation as resolved.
Show resolved Hide resolved
45 changes: 45 additions & 0 deletions screen-capture-api/basic-screen-capture/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
* {
box-sizing: border-box;
}

body {
padding: 0 25px;
}

#main-app {
display: flex;
gap: 5%;
min-width: 980px;
}

video,
#demo {
flex: 1;
}

video,
#demo>p,
bsmth marked this conversation as resolved.
Show resolved Hide resolved
#log {
border: 1px solid #CCC;
margin: 0;
}

video {
max-width: 50%;
aspect-ratio: 4/3;
}

#demo>h2 {
margin-top: 0;
}

#demo>p {
padding: 5px;
height: 320px;
}

#log {
height: 20rem;
bsmth marked this conversation as resolved.
Show resolved Hide resolved
padding: 0.5rem;
overflow: auto;
}
36 changes: 36 additions & 0 deletions screen-capture-api/basic-screen-capture/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>Screen Capture API demo</title>
<link href="index.css" rel="stylesheet">
<script defer src="index.js"></script>
</head>

<body>
<h1>Screen Capture API example</h1>
<p>
Click the "Start Capture" button to capture a tab, window, or screen as a video stream and broadcast it in the
<code>&lt;video&gt;</code> element on the left. This demo uses the Screen Capture API.
</p>

<p>
<button id="start">Start Capture</button>&nbsp;<button id="stop">
Stop Capture
</button>
</p>

<div id="main-app">
<video autoplay></video>
<div id="demo">
<h2>Some kind of demo</h2>
<p>This container is a placeholder for some kind of demo that you might want to share with other participants.</p>
</div>
</div>

<h2>Log:</h2>
<pre id="log"></pre>
</body>

</html>
63 changes: 63 additions & 0 deletions screen-capture-api/basic-screen-capture/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const videoElem = document.querySelector("video");
const logElem = document.getElementById("log");
const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");

// Options for getDisplayMedia()

const displayMediaOptions = {
video: {
displaySurface: "window",
},
audio: false,
};

// Set event listeners for the start and stop buttons
startElem.addEventListener(
"click",
(evt) => {
startCapture();
},
false,
);

stopElem.addEventListener(
"click",
(evt) => {
stopCapture();
},
false,
);

console.log = (msg) => (logElem.textContent = `${logElem.textContent}\n${msg}`);
console.error = (msg) =>
(logElem.textContent = `${logElem.textContent}\nError: ${msg}`);

async function startCapture() {
logElem.textContent = "";

try {
videoElem.srcObject =
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
dumpOptionsInfo();
} catch (err) {
console.error(err);
}
}

function stopCapture(evt) {
let tracks = videoElem.srcObject.getTracks();

tracks.forEach((track) => track.stop());
videoElem.srcObject = null;
}

function dumpOptionsInfo() {
const videoTrack = videoElem.srcObject.getVideoTracks()[0];

console.log("Track settings:");
console.log(JSON.stringify(videoTrack.getSettings(), null, 2));
console.log("Track constraints:");
console.log(JSON.stringify(videoTrack.getConstraints(), null, 2));
}

53 changes: 53 additions & 0 deletions screen-capture-api/element-capture/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
* {
box-sizing: border-box;
}

body {
padding: 0 25px;
}

#main-app {
display: flex;
gap: 5%;
min-width: 980px;
}

#demo {
isolation: isolate;
/* Forms a stacking context. */
transform-style: flat;
/* Flattened. */
background-color: white;
}

video,
#demo {
flex: 1;
}

video,
#demo>p,
#log {
border: 1px solid #CCC;
margin: 0;
}

video {
max-width: 50%;
aspect-ratio: 4/3;
}

#demo>h2 {
margin-top: 0;
}

#demo>p {
padding: 5px;
height: 320px;
}

#log {
height: 20rem;
padding: 0.5rem;
overflow: auto;
}
37 changes: 37 additions & 0 deletions screen-capture-api/element-capture/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>Element Capture API demo</title>
<link href="index.css" rel="stylesheet">
<script defer src="index.js"></script>
</head>

<body>
<h1>Element Capture API example</h1>
<p>
Click the "Start Capture" button to capture the demo container element shown on the right as a video stream and
broadcast it in the <code>&lt;video&gt;</code> element on the left. This demo uses the Screen Capture API and the
Element Capture API.
</p>

<p>
<button id="start">Start Capture</button>&nbsp;<button id="stop">
Stop Capture
</button>
</p>

<div id="main-app">
<video autoplay></video>
<div id="demo">
<h2>Some kind of demo</h2>
<p>This container is a placeholder for some kind of demo that you might want to share with other participants.</p>
</div>
</div>

<h2>Log:</h2>
<pre id="log"></pre>
</body>

</html>
72 changes: 72 additions & 0 deletions screen-capture-api/element-capture/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const videoElem = document.querySelector("video");
const logElem = document.getElementById("log");
const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");
const demoElem = document.querySelector("#demo");


// Options for getDisplayMedia()

const displayMediaOptions = {
video: {
displaySurface: "window",
},
audio: false,
preferCurrentTab: true,
};

// Set event listeners for the start and stop buttons
startElem.addEventListener(
"click",
(evt) => {
startCapture();
},
false,
);

stopElem.addEventListener(
"click",
(evt) => {
stopCapture();
},
false,
);

console.log = (msg) => (logElem.textContent = `${logElem.textContent}\n${msg}`);
console.error = (msg) =>
(logElem.textContent = `${logElem.textContent}\nError: ${msg}`);

async function startCapture() {
logElem.textContent = "";

try {
const stream =
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
const [track] = stream.getVideoTracks();
const restrictionTarget = await RestrictionTarget.fromElement(demoElem);
await track.restrictTo(restrictionTarget);

videoElem.srcObject = stream;

dumpOptionsInfo();
} catch (err) {
console.error(err);
}
}

function stopCapture(evt) {
let tracks = videoElem.srcObject.getTracks();

tracks.forEach((track) => track.stop());
videoElem.srcObject = null;
}

function dumpOptionsInfo() {
const videoTrack = videoElem.srcObject.getVideoTracks()[0];

console.log("Track settings:");
console.log(JSON.stringify(videoTrack.getSettings(), null, 2));
console.log("Track constraints:");
console.log(JSON.stringify(videoTrack.getConstraints(), null, 2));
}

45 changes: 45 additions & 0 deletions screen-capture-api/region-capture/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
* {
box-sizing: border-box;
}

body {
padding: 0 25px;
}

#main-app {
display: flex;
gap: 5%;
min-width: 980px;
}

video,
#demo {
flex: 1;
}

video,
#demo>p,
#log {
border: 1px solid #CCC;
margin: 0;
}

video {
max-width: 50%;
aspect-ratio: 4/3;
}

#demo>h2 {
margin-top: 0;
}

#demo>p {
padding: 5px;
height: 320px;
}

#log {
height: 20rem;
padding: 0.5rem;
overflow: auto;
}
Loading