Skip to content

Commit

Permalink
Add DOM examples for Screen Capture API (#285)
Browse files Browse the repository at this point in the history
* Add DOM examples for Screen Capture API

* Update screen-capture-api/README.md

Co-authored-by: Brian Smith <[email protected]>

* Update screen-capture-api/README.md

Co-authored-by: Brian Smith <[email protected]>

* Fixes for bsmth review comments

---------

Co-authored-by: Brian Smith <[email protected]>
  • Loading branch information
chrisdavidmills and bsmth authored Nov 27, 2024
1 parent b232504 commit acad140
Show file tree
Hide file tree
Showing 11 changed files with 467 additions and 0 deletions.
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.
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,
#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;
}
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

0 comments on commit acad140

Please sign in to comment.