Verwenden der Screen Capture API
Eingeschränkt verfügbar
Diese Funktion ist nicht Baseline, da sie in einigen der am weitesten verbreiteten Browser nicht funktioniert.
Want more browser support for this feature? Tell us why.
In diesem Artikel untersuchen wir, wie die Screen Capture API und ihre Methode getDisplayMedia() verwendet werden, um einen Teil oder den gesamten Bildschirm für Streaming, Aufzeichnung oder Freigabe während einer WebRTC-Konferenzsitzung zu erfassen.
Hinweis:
Es kann hilfreich sein zu wissen, dass aktuelle Versionen des WebRTC-adapter.js-Shims Implementierungen von getDisplayMedia() enthalten, um die Bildschirmfreigabe in Browsern zu ermöglichen, die sie unterstützen, aber die aktuelle Standard-API nicht implementieren. Dies funktioniert mindestens mit Chrome, Edge und Firefox.
Bildschirm-inhalte erfassen
Die Erfassung von Bildschirminhalten als Live-MediaStream wird durch Aufrufen von navigator.mediaDevices.getDisplayMedia() gestartet. Diese Methode gibt ein Promise zurück, das zu einem Stream mit den Live-Bildschirminhalten aufgelöst wird. Das in den folgenden Beispielen referenzierte Objekt displayMediaOptions könnte etwa wie folgt aussehen:
const displayMediaOptions = {
video: {
displaySurface: "browser",
},
audio: {
suppressLocalAudioPlayback: false,
},
preferCurrentTab: false,
selfBrowserSurface: "exclude",
systemAudio: "include",
surfaceSwitching: "include",
monitorTypeSurfaces: "include",
};
Bildschirmaufnahme starten: Stil mit async/await
async function startCapture(displayMediaOptions) {
let captureStream = null;
try {
captureStream =
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
} catch (err) {
console.error(`Error: ${err}`);
}
return captureStream;
}
Sie können diesen Code entweder mit einer asynchronen Funktion und dem Operator await schreiben, wie oben gezeigt, oder direkt mit dem Promise, wie unten dargestellt.
Bildschirmaufnahme starten: Stil mit Promise
function startCapture(displayMediaOptions) {
return navigator.mediaDevices
.getDisplayMedia(displayMediaOptions)
.catch((err) => {
console.error(err);
return null;
});
}
In beiden Fällen reagiert der User Agent, indem er eine Benutzeroberfläche anzeigt, die den Benutzer auffordert, den freizugebenden Bildschirmbereich auszuwählen. Beide Implementierungen von startCapture() geben den MediaStream zurück, der die erfassten Bildschirmbilder enthält.
Weitere Informationen dazu, wie Sie sowohl den gewünschten Oberflächentyp festlegen als auch den resultierenden Stream auf andere Weise anpassen können, finden Sie unten unter Optionen und Einschränkungen.
Beispiel eines Fensters, das dem Benutzer die Auswahl einer zu erfassenden Anzeigeoberfläche ermöglicht

Sie können den erfassten Stream captureStream anschließend für alles verwenden, was einen Stream als Eingabe akzeptiert. Die folgenden Beispiele zeigen einige Möglichkeiten, den Stream zu verwenden.
Sichtbare und logische Anzeigeoberflächen
Für die Zwecke der Screen Capture API ist eine Anzeigeoberfläche jedes Inhaltsobjekt, das von der API zur Freigabe ausgewählt werden kann. Freigabeoberflächen umfassen den Inhalt eines Browser-Tabs, ein vollständiges Fenster und einen Monitor (oder eine Gruppe von Monitoren, die zu einer Oberfläche zusammengefasst sind).
Es gibt zwei Arten von Anzeigeoberflächen. Eine sichtbare Anzeigeoberfläche ist eine Oberfläche, die vollständig auf dem Bildschirm sichtbar ist, etwa das vorderste Fenster oder der vorderste Tab oder der gesamte Bildschirm.
Eine logische Anzeigeoberfläche ist teilweise oder vollständig verdeckt, entweder weil sie in gewissem Umfang von einem anderen Objekt überlagert wird oder weil sie vollständig ausgeblendet ist bzw. sich außerhalb des Bildschirms befindet. Die Behandlung solcher Oberflächen durch die Screen Capture API ist unterschiedlich. Im Allgemeinen stellt der Browser ein Bild bereit, das den ausgeblendeten Teil der logischen Anzeigeoberfläche auf irgendeine Weise verdeckt, etwa durch Unschärfe oder durch Ersetzen durch eine Farbe oder ein Muster. Dies geschieht aus Sicherheitsgründen, da die Inhalte, die der Benutzer nicht sehen kann, Daten enthalten können, die er nicht freigeben möchte.
Ein User Agent kann die Erfassung des vollständigen Inhalts eines verdeckten Fensters zulassen, nachdem die Erlaubnis des Benutzers dafür eingeholt wurde. In diesem Fall kann der User Agent den verdeckten Inhalt einbeziehen, indem er entweder den aktuellen Inhalt des ausgeblendeten Fensterbereichs abruft oder den zuletzt sichtbaren Inhalt darstellt, falls der aktuelle Inhalt nicht verfügbar ist.
Optionen und Einschränkungen
Das an getDisplayMedia() übergebene Optionsobjekt wird verwendet, um Optionen für den resultierenden Stream festzulegen.
Die an das Optionsobjekt übergebenen Objekte video und audio können außerdem zusätzliche Einschränkungen enthalten, die speziell für diese Medientracks gelten. Einzelheiten zu zusätzlichen Einschränkungen für die Konfiguration eines Bildschirmaufnahme-Streams, die zu MediaTrackConstraints, MediaTrackSupportedConstraints und MediaTrackSettings) hinzugefügt werden, finden Sie unter Eigenschaften freigegebener Bildschirm-Tracks.
Keine der Einschränkungen wird angewendet, bevor der zu erfassende Inhalt ausgewählt wurde. Die Einschränkungen verändern, was Sie im resultierenden Stream sehen. Wenn Sie beispielsweise eine Einschränkung für width für das Video angeben, wird sie durch Skalieren des Videos angewendet, nachdem der Benutzer den freizugebenden Bereich ausgewählt hat. Sie legt keine Einschränkung für die Größe der Quelle selbst fest.
Hinweis: Einschränkungen führen niemals zu Änderungen an der Liste der Quellen, die von der Screen Sharing API zur Erfassung angeboten werden. Dadurch wird sichergestellt, dass Webanwendungen den Benutzer nicht dazu zwingen können, bestimmte Inhalte freizugeben, indem sie die Quellliste einschränken, bis nur noch ein Eintrag übrig bleibt.
Während eine Anzeigeerfassung aktiv ist, zeigt das Gerät, das Bildschirminhalte freigibt, eine Art von Indikator an, damit der Benutzer weiß, dass eine Freigabe stattfindet.
Hinweis:
Aus Datenschutz- und Sicherheitsgründen können Quellen für die Bildschirmfreigabe nicht mit enumerateDevices() aufgezählt werden. Damit zusammenhängend wird das Ereignis devicechange niemals gesendet, wenn sich die für getDisplayMedia() verfügbaren Quellen ändern.
Freigegebenes Audio erfassen
getDisplayMedia() wird am häufigsten verwendet, um Video vom Bildschirm eines Benutzers oder von Teilen davon zu erfassen. User Agents können jedoch die Erfassung von Audio zusammen mit den Videoinhalten erlauben. Die Quelle dieses Audios kann das ausgewählte Fenster, das gesamte Audiosystem des Computers oder das Mikrofon des Benutzers sein – oder eine Kombination davon.
Bevor Sie ein Projekt starten, das die Freigabe von Audio erfordert, sollten Sie die Browser-Kompatibilität für getDisplayMedia() prüfen, um festzustellen, ob die Browser, mit denen Sie kompatibel sein möchten, Audio in erfassten Bildschirm-Streams unterstützen.
Um anzufordern, dass der Bildschirm mit eingeschlossenem Audio freigegeben wird, könnten die an getDisplayMedia() übergebenen Optionen wie folgt aussehen:
const displayMediaOptions = {
video: true,
audio: true,
};
Dadurch hat der Benutzer innerhalb der Grenzen dessen, was der User Agent unterstützt, vollständige Freiheit, beliebige Optionen auszuwählen. Dies könnte durch Angabe zusätzlicher Optionen und Einschränkungen innerhalb der Objekte audio und video weiter verfeinert werden:
const displayMediaOptions = {
video: {
displaySurface: "window",
},
audio: {
echoCancellation: true,
noiseSuppression: true,
sampleRate: 44100,
suppressLocalAudioPlayback: true,
},
surfaceSwitching: "include",
selfBrowserSurface: "exclude",
systemAudio: "exclude",
};
In diesem Beispiel soll die erfasste Anzeigeoberfläche das gesamte Fenster sein. Der Audiotrack sollte idealerweise die Funktionen zur Rauschunterdrückung und Echounterdrückung aktiviert haben, ebenso wie eine ideale Audio-Abtastrate von 44,1 kHz und die Unterdrückung der lokalen Audiowiedergabe.
Darüber hinaus weist die App den User Agent darauf hin, dass er Folgendes tun sollte:
- Während der Bildschirmfreigabe ein Steuerelement bereitstellen, mit dem der Benutzer den freigegebenen Tab dynamisch wechseln kann.
- Den aktuellen Tab aus der Liste der Optionen ausblenden, die dem Benutzer bei der Anforderung einer Erfassung angezeigt werden.
- Das Systemaudio nicht zu den möglichen Audioquellen zählen, die dem Benutzer angeboten werden.
Die Erfassung von Audio ist immer optional. Selbst wenn Webinhalte einen Stream mit Audio und Video anfordern, kann der zurückgegebene MediaStream daher weiterhin nur einen Videotrack ohne Audio enthalten.
Den erfassten Stream verwenden
Das von getDisplayMedia() zurückgegebene Promise wird zu einem MediaStream aufgelöst, der mindestens einen Videostream enthält, welcher den Bildschirm oder Bildschirmbereich beinhaltet und anhand der beim Aufruf von getDisplayMedia() angegebenen Einschränkungen angepasst oder gefiltert wird.
Potenzielle Risiken
Datenschutz- und Sicherheitsprobleme im Zusammenhang mit der Bildschirmfreigabe sind in der Regel nicht allzu schwerwiegend, bestehen jedoch. Das größte potenzielle Problem besteht darin, dass Benutzer unbeabsichtigt Inhalte freigeben, die sie nicht freigeben wollten.
Beispielsweise können Datenschutz- und/oder Sicherheitsverletzungen leicht auftreten, wenn der Benutzer seinen Bildschirm freigibt und ein sichtbares Hintergrundfenster zufällig persönliche Informationen enthält oder wenn sein Passwort-Manager im freigegebenen Stream sichtbar ist. Dieser Effekt kann bei der Erfassung logischer Anzeigeoberflächen verstärkt werden, da diese Inhalte enthalten können, von denen der Benutzer nichts weiß und die er erst recht nicht sehen kann.
User Agents, die den Datenschutz ernst nehmen, sollten Inhalte verschleiern, die nicht tatsächlich auf dem Bildschirm sichtbar sind, sofern nicht ausdrücklich eine Berechtigung zum Teilen dieser Inhalte erteilt wurde.
Erfassung von Anzeigeinhalten autorisieren
Bevor das Streaming erfasster Bildschirminhalte beginnen kann, fordert der User Agent den Benutzer auf, die Freigabeanfrage zu bestätigen und die freizugebenden Inhalte auszuwählen.
Beispiele
>Bildschirmaufnahme streamen
In diesem Beispiel werden die Inhalte des erfassten Bildschirmbereichs in ein <video>-Element auf derselben Seite gestreamt.
JavaScript
Für die Umsetzung ist nicht besonders viel Code erforderlich. Wenn Sie mit getUserMedia() zur Erfassung von Video von einer Kamera vertraut sind, wird Ihnen getDisplayMedia() sehr vertraut vorkommen.
Einrichtung
Zunächst werden einige Konstanten eingerichtet, um auf die Elemente der Seite zu verweisen, auf die wir zugreifen müssen: das <video>, in das die erfassten Bildschirminhalte gestreamt werden, ein Feld, in das protokollierte Ausgaben geschrieben werden, sowie die Schaltflächen zum Starten und Beenden der Erfassung von Bildschirmbildern.
Das Objekt displayMediaOptions enthält die an getDisplayMedia() zu übergebenden Optionen. Hier ist die Eigenschaft displaySurface auf window gesetzt, was angibt, dass das gesamte Fenster erfasst werden soll.
Abschließend werden Event-Listener eingerichtet, um Klicks des Benutzers auf die Schaltflächen zum Starten und Beenden zu erkennen.
const videoElem = document.getElementById("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();
});
stopElem.addEventListener("click", (evt) => {
stopCapture();
});
Inhalte protokollieren
Dieses Beispiel überschreibt bestimmte Methoden von console, um ihre Meldungen im <pre>-Block mit der ID log auszugeben.
console.log = (msg) => (logElem.textContent = `${logElem.textContent}\n${msg}`);
console.error = (msg) =>
(logElem.textContent = `${logElem.textContent}\nError: ${msg}`);
Dadurch können wir console.log() und console.error() verwenden, um Informationen im Protokollfeld des Dokuments auszugeben.
Anzeigeerfassung starten
Die nachstehende Methode startCapture() startet die Erfassung eines MediaStream, dessen Inhalte aus einem vom Benutzer ausgewählten Bereich des Bildschirms stammen. startCapture() wird aufgerufen, wenn auf die Schaltfläche „Start Capture“ geklickt wird.
async function startCapture() {
logElem.textContent = "";
try {
videoElem.srcObject =
await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
dumpOptionsInfo();
} catch (err) {
console.error(err);
}
}
Nachdem der Inhalt des Protokolls gelöscht wurde, um verbliebenen Text vom vorherigen Verbindungsversuch zu entfernen, ruft startCapture() getDisplayMedia() auf und übergibt ihm das durch displayMediaOptions definierte Einschränkungsobjekt. Durch die Verwendung von await wird die folgende Codezeile erst ausgeführt, nachdem das von getDisplayMedia() zurückgegebene Promise aufgelöst wurde. Nach der Auflösung gibt das Promise einen MediaStream zurück, der die Inhalte des vom Benutzer ausgewählten Bildschirms, Fensters oder anderen Bereichs streamt.
Der Stream wird mit dem <video>-Element verbunden, indem der zurückgegebene MediaStream in srcObject des Elements gespeichert wird.
Die Funktion dumpOptionsInfo(), die wir gleich betrachten werden, gibt zu Lernzwecken Informationen über den Stream im Protokollfeld aus.
Falls etwas davon fehlschlägt, gibt die Klausel catch() eine Fehlermeldung im Protokollfeld aus.
Anzeigeerfassung beenden
Die Methode stopCapture() wird aufgerufen, wenn auf die Schaltfläche „Stop Capture“ geklickt wird. Sie beendet den Stream, indem sie mithilfe von MediaStream.getTracks() dessen Trackliste abruft und dann die Methode stop() jedes Tracks aufruft. Danach wird srcObject auf null gesetzt, damit für alle Interessierten klar ist, dass kein Stream verbunden ist.
function stopCapture(evt) {
let tracks = videoElem.srcObject.getTracks();
tracks.forEach((track) => track.stop());
videoElem.srcObject = null;
}
Konfigurationsinformationen ausgeben
Zu Informationszwecken ruft die oben gezeigte Methode startCapture() eine Methode namens dumpOptions() auf, die die aktuellen Track-Einstellungen sowie die Einschränkungen ausgibt, die beim Erstellen auf den Stream angewendet wurden.
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));
}
Die Trackliste wird durch Aufrufen von getVideoTracks() auf dem MediaStream des erfassten Bildschirms abgerufen. Die aktuell wirksamen Einstellungen werden mit getSettings() abgerufen, und die festgelegten Einschränkungen mit getConstraints().
HTML
Das HTML beginnt mit einem einleitenden Absatz und kommt dann zum Wesentlichen.
<p>
This example shows you the contents of the selected part of your display.
Click the Start Capture button to begin.
</p>
<p>
<button id="start">Start Capture</button> <button id="stop">
Stop Capture
</button>
</p>
<video id="video" autoplay></video>
<br />
<strong>Log:</strong>
<br />
<pre id="log"></pre>
Die wichtigsten Teile des HTML sind:
- Ein mit „Start Capture“ beschriftetes
<button>, das beim Anklicken die FunktionstartCapture()aufruft, um Zugriff auf Bildschirminhalte anzufordern und deren Erfassung zu starten. - Eine zweite Schaltfläche „Stop Capture“, die beim Anklicken
stopCapture()aufruft, um die Erfassung von Bildschirminhalten zu beenden. - Ein
<video>, in das die erfassten Bildschirminhalte gestreamt werden. - Ein
<pre>-Block, in den durch die abgefangeneconsole-Methode protokollierter Text eingefügt wird.
CSS
Das CSS ist in diesem Beispiel rein kosmetisch. Das Video erhält einen Rahmen, und seine Breite wird so festgelegt, dass es nahezu den gesamten verfügbaren horizontalen Platz einnimmt (width: 98%). max-width wird auf 860px gesetzt, um eine absolute Obergrenze für die Größe des Videos festzulegen.
#video {
border: 1px solid #999999;
width: 98%;
max-width: 860px;
}
#log {
width: 25rem;
height: 15rem;
border: 1px solid black;
padding: 0.5rem;
overflow: scroll;
}
Ergebnis
Das Endergebnis sieht wie folgt aus. Wenn Ihr Browser die Screen Capture API unterstützt, wird durch Klicken auf „Start Capture“ die Oberfläche des User Agents zur Auswahl eines freizugebenden Bildschirms, Fensters oder Tabs angezeigt.
Sicherheit
Damit die Funktion bei aktivierter Permissions Policy funktioniert, benötigen Sie die Berechtigung display-capture. Dies kann mithilfe des HTTP-Headers Permissions-Policy erfolgen oder, wenn Sie die Screen Capture API in einem <iframe> verwenden, mit dem Attribut allow des <iframe>-Elements.
Beispielsweise aktiviert diese Zeile in den HTTP-Headern die Screen Capture API für das Dokument und alle eingebetteten <iframe>-Elemente, die vom selben Ursprung geladen werden:
Permissions-Policy: display-capture=(self)
Wenn Sie die Bildschirmaufnahme innerhalb eines <iframe> durchführen, können Sie die Berechtigung nur für diesen Frame anfordern, was eindeutig sicherer ist als eine allgemeinere Berechtigungsanforderung:
<iframe src="https://mycode.example.net/etc" allow="display-capture"> </iframe>
Browser-Kompatibilität
Siehe auch
- Screen Capture API
- Media Capture and Streams API
- Standbilder mit WebRTC aufnehmen
HTMLCanvasElement.captureStream(), um einenMediaStreammit den Live-Inhalten eines<canvas>zu erhalten