Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Die Screen Capture API verwenden

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 erfahren Sie, wie Sie mit der Screen Capture API und ihrer Methode getDisplayMedia() einen Teil des Bildschirms oder den gesamten Bildschirm erfassen können, um ihn während einer WebRTC-Konferenz zu streamen, aufzuzeichnen oder zu teilen.

Hinweis: Neuere Versionen des WebRTC adapter.js shim enthalten Implementierungen von getDisplayMedia(). Damit lässt sich die Bildschirmfreigabe in Browsern nutzen, die sie unterstützen, aber die aktuelle Standard-API nicht implementieren. Dies funktioniert mindestens mit Chrome, Edge und Firefox.

Bildschirminhalte erfassen

Um Bildschirminhalte als Live-MediaStream zu erfassen, rufen Sie navigator.mediaDevices.getDisplayMedia() auf. Die Methode gibt ein Promise zurück, das mit einem Stream der aktuellen Bildschirminhalte erfüllt wird. Das in den folgenden Beispielen verwendete Objekt displayMediaOptions könnte so aussehen:

js
const displayMediaOptions = {
  video: {
    displaySurface: "browser",
  },
  audio: {
    suppressLocalAudioPlayback: false,
  },
  preferCurrentTab: false,
  selfBrowserSurface: "exclude",
  systemAudio: "include",
  surfaceSwitching: "include",
  monitorTypeSurfaces: "include",
};

Bildschirmaufnahme starten: mit async/await

js
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 Promise direkt verwenden, wie im folgenden Beispiel.

Bildschirmaufnahme starten: mit Promise

js
function startCapture(displayMediaOptions) {
  return navigator.mediaDevices
    .getDisplayMedia(displayMediaOptions)
    .catch((err) => {
      console.error(err);
      return null;
    });
}

In beiden Fällen zeigt der User Agent eine Benutzeroberfläche an, auf der die Person den freizugebenden Bildschirmbereich auswählen kann. Beide Implementierungen von startCapture() geben den MediaStream mit den erfassten Bildschirminhalten zurück.

Unter Optionen und Constraints erfahren Sie mehr darüber, wie Sie die gewünschte Art der Anzeigefläche angeben und den resultierenden Stream anpassen können.

Beispiel eines Fensters zur Auswahl einer Anzeigefläche

Screenshot des Chrome-Fensters zur Auswahl einer Quellfläche

Den erfassten Stream captureStream können Sie anschließend überall dort verwenden, wo ein Stream als Eingabe akzeptiert wird. Die folgenden Beispiele zeigen einige Verwendungsmöglichkeiten.

Sichtbare und logische Anzeigeflächen

Im Sinne der Screen Capture API ist eine Anzeigefläche jedes Inhaltsobjekt, das über die API zur Freigabe ausgewählt werden kann. Dazu gehören der Inhalt eines Browser-Tabs, ein vollständiges Fenster sowie ein Monitor oder mehrere zu einer Fläche zusammengefasste Monitore.

Es gibt zwei Arten von Anzeigeflächen. Eine sichtbare Anzeigefläche ist vollständig auf dem Bildschirm zu sehen, beispielsweise das vorderste Fenster oder Tab oder der gesamte Bildschirm.

Eine logische Anzeigefläche ist teilweise oder vollständig verdeckt: Sie wird von einem anderen Objekt überlagert oder ist ganz ausgeblendet beziehungsweise befindet sich außerhalb des sichtbaren Bildschirmbereichs. Wie die Screen Capture API damit umgeht, ist unterschiedlich. In der Regel stellt der Browser ein Bild bereit, in dem der verborgene Teil der logischen Anzeigefläche unkenntlich gemacht wird, etwa durch Unschärfe oder indem er durch eine Farbe oder ein Muster ersetzt wird. Dies dient der Sicherheit, da für die Person nicht sichtbare Inhalte Daten enthalten können, die sie nicht teilen möchte.

Ein User Agent kann die Erfassung des gesamten Inhalts eines verdeckten Fensters ermöglichen, nachdem die Person dies erlaubt hat. In diesem Fall kann er den verdeckten Inhalt einbeziehen, indem er entweder den aktuellen Inhalt des verborgenen Fensterbereichs erfasst oder, falls dieser nicht verfügbar ist, den zuletzt sichtbaren Inhalt wiedergibt.

Optionen und Constraints

Mit dem an getDisplayMedia() übergebenen Optionsobjekt legen Sie Optionen für den resultierenden Stream fest.

Die Objekte video und audio innerhalb des Optionsobjekts können zusätzliche Constraints für die jeweiligen Medientracks enthalten. Unter Eigenschaften freigegebener Bildschirmtracks finden Sie Einzelheiten zu zusätzlichen Constraints für die Konfiguration eines Bildschirmaufnahmestreams, die MediaTrackConstraints hinzugefügt werden, zu den von MediaDevices.getSupportedConstraints() zurückgegebenen unterstützten Constraints und zu den von MediaStreamTrack.getSettings() zurückgegebenen aktuellen Einstellungen.

Constraints werden erst angewendet, nachdem der zu erfassende Inhalt ausgewählt wurde. Sie verändern das Bild im resultierenden Stream. Wenn Sie beispielsweise einen width-Constraint für das Video angeben, wird das Video skaliert, nachdem die Person den freizugebenden Bereich ausgewählt hat. Dadurch wird die Größe der Quelle selbst nicht eingeschränkt.

Hinweis: Constraints verändern niemals die Liste der Quellen, die über die Screen Capture API erfasst werden können. So wird verhindert, dass Webanwendungen eine Person zur Freigabe bestimmter Inhalte drängen, indem sie die Quellenliste auf einen einzigen Eintrag einschränken.

Während eine Bildschirmaufnahme läuft, zeigt das Gerät, das die Bildschirminhalte teilt, einen Hinweis an. So ist erkennbar, dass eine Freigabe stattfindet.

Hinweis: Aus Datenschutz- und Sicherheitsgründen lassen sich Quellen für die Bildschirmfreigabe nicht mit enumerateDevices() auflisten. Entsprechend wird das Ereignis devicechange nie ausgelöst, wenn sich die für getDisplayMedia() verfügbaren Quellen ändern.

Geteiltes Audio erfassen

getDisplayMedia() wird meist verwendet, um ein Video des Bildschirms oder eines Teils davon aufzunehmen. User Agents können jedoch auch die Erfassung von Audio zusammen mit dem Videoinhalt erlauben. Als Audioquelle kommen das ausgewählte Fenster, das gesamte Audiosystem des Computers oder das Mikrofon der Person infrage – auch in Kombination.

Wenn Ihr Projekt die Freigabe von Audio erfordert, prüfen Sie zunächst die Browser-Kompatibilität von getDisplayMedia(). So können Sie feststellen, ob die gewünschten Browser Audio in erfassten Bildschirmstreams unterstützen.

Um eine Bildschirmfreigabe einschließlich Audio anzufordern, könnten Sie getDisplayMedia() die folgenden Optionen übergeben:

js
const displayMediaOptions = {
  video: true,
  audio: true,
};

Damit kann die Person innerhalb der vom User Agent unterstützten Möglichkeiten frei auswählen, was sie teilen möchte. Sie können die Anforderung durch zusätzliche Optionen und Constraints in den Objekten audio und video weiter eingrenzen:

js
const displayMediaOptions = {
  video: {
    displaySurface: "window",
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    sampleRate: 44100,
    suppressLocalAudioPlayback: true,
  },
  surfaceSwitching: "include",
  selfBrowserSurface: "exclude",
  systemAudio: "exclude",
};

In diesem Beispiel soll das gesamte Fenster als Anzeigefläche erfasst werden. Für den Audiotrack sollen möglichst Rauschunterdrückung und Echounterdrückung aktiviert sein. Außerdem werden eine bevorzugte Audio-Abtastrate von 44,1 kHz und die Unterdrückung der lokalen Audiowiedergabe angegeben.

Darüber hinaus signalisiert die Anwendung dem User Agent, dass er:

  • während der Bildschirmfreigabe ein Bedienelement bereitstellen soll, mit dem die Person den geteilten Tab wechseln kann;
  • den aktuellen Tab aus den Auswahlmöglichkeiten ausblenden soll, die bei der Anforderung der Aufnahme angezeigt werden;
  • Systemaudio nicht unter den angebotenen Audioquellen aufführen soll.

Die Erfassung von Audio ist immer optional. Selbst wenn Webinhalte einen Stream mit Audio und Video anfordern, kann der zurückgegebene MediaStream nur einen Videotrack und keinen Audiotrack enthalten.

Den erfassten Stream verwenden

Das von getDisplayMedia() zurückgegebene Promise wird mit einem MediaStream erfüllt. Dieser enthält mindestens einen Videostream mit dem Bildschirm oder Bildschirmbereich, dessen Bild anhand der beim Aufruf von getDisplayMedia() angegebenen Constraints angepasst oder gefiltert wird.

Mögliche Risiken

Datenschutz- und Sicherheitsprobleme bei der Bildschirmfreigabe sind meist nicht besonders schwerwiegend, können aber auftreten. Das größte Risiko besteht darin, dass Personen unbeabsichtigt Inhalte teilen, die sie nicht freigeben wollten.

Beispielsweise kann es leicht zu Datenschutz- oder Sicherheitsverletzungen kommen, wenn eine Person ihren Bildschirm teilt und ein sichtbares Fenster im Hintergrund persönliche Informationen enthält oder ihr Passwortmanager im geteilten Stream zu sehen ist. Bei der Erfassung logischer Anzeigeflächen kann sich dieses Risiko erhöhen: Sie können Inhalte enthalten, die der Person nicht einmal bekannt sind, geschweige denn für sie sichtbar.

User Agents, die den Datenschutz ernst nehmen, sollten Inhalte unkenntlich machen, die auf dem Bildschirm nicht tatsächlich sichtbar sind – es sei denn, die Freigabe genau dieser Inhalte wurde ausdrücklich erlaubt.

Erfassung von Bildschirminhalten autorisieren

Bevor die Übertragung erfasster Bildschirminhalte beginnen kann, fordert der User Agent die Person auf, die Freigabeanfrage zu bestätigen und den freizugebenden Inhalt auszuwählen.

Beispiele

Bildschirmaufnahme streamen

In diesem Beispiel wird der Inhalt des erfassten Bildschirmbereichs in ein <video>-Element auf derselben Seite gestreamt.

JavaScript

Dafür ist nicht viel Code erforderlich. Wenn Sie bereits getUserMedia() verwendet haben, um ein Kameravideo zu erfassen, wird Ihnen getDisplayMedia() vertraut vorkommen.

Einrichtung

Zunächst werden Konstanten angelegt, die auf die benötigten Seitenelemente verweisen: das <video>-Element, in das die erfassten Bildschirminhalte gestreamt werden, einen Bereich für Protokollausgaben sowie die Schaltflächen zum Starten und Beenden der Bildschirmaufnahme.

Das Objekt displayMediaOptions enthält die Optionen, die an getDisplayMedia() übergeben werden. Hier ist die Eigenschaft displaySurface auf window gesetzt. Damit wird angegeben, dass das gesamte Fenster erfasst werden soll.

Schließlich werden Event-Listener eingerichtet, die Klicks auf die Schaltflächen zum Starten und Beenden erkennen.

js
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.

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

Dadurch können wir mit console.log() und console.error() Informationen im Protokollbereich des Dokuments ausgeben.

Bildschirmaufnahme starten

Die folgende Methode startCapture() startet die Erfassung eines MediaStream, dessen Inhalt aus einem von der Person ausgewählten Bildschirmbereich stammt. startCapture() wird aufgerufen, wenn auf die Schaltfläche „Start Capture“ geklickt wird.

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

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

Zunächst wird der Protokollbereich geleert, um Text eines vorherigen Verbindungsversuchs zu entfernen. Anschließend ruft startCapture() getDisplayMedia() auf und übergibt dabei das durch displayMediaOptions definierte Constraints-Objekt. Durch await wird die nächste Codezeile erst ausgeführt, wenn das von getDisplayMedia() zurückgegebene Promise erfüllt wurde. Das Promise liefert dann einen MediaStream, der den Inhalt des von der Person ausgewählten Bildschirms, Fensters oder eines anderen Bereichs streamt.

Der Stream wird mit dem <video>-Element verbunden, indem der zurückgegebene MediaStream in dessen Eigenschaft srcObject gespeichert wird.

Die Funktion dumpOptionsInfo(), die wir gleich näher betrachten, gibt zu Demonstrationszwecken Informationen über den Stream im Protokollbereich aus.

Falls dabei ein Fehler auftritt, gibt der catch()-Block eine Fehlermeldung im Protokollbereich aus.

Bildschirmaufnahme beenden

Die Methode stopCapture() wird aufgerufen, wenn auf die Schaltfläche „Stop Capture“ geklickt wird. Sie ruft mit MediaStream.getTracks() die Trackliste des Streams ab und beendet jeden Track mit dessen Methode stop(). Danach wird srcObject auf null gesetzt, damit erkennbar ist, dass kein Stream mehr verbunden ist.

js
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. Diese gibt sowohl die aktuellen Trackeinstellungen als auch die Constraints aus, die beim Erstellen des Streams festgelegt wurden.

js
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 abgerufen, indem getVideoTracks() für den MediaStream der Bildschirmaufnahme aufgerufen wird. Die aktuell geltenden Einstellungen werden mit getSettings() abgerufen, die festgelegten Constraints mit getConstraints().

HTML

Das HTML beginnt mit einem einleitenden Absatz. Danach folgen die wesentlichen Elemente.

html
<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>&nbsp;<button id="stop">
    Stop Capture
  </button>
</p>

<video id="video" autoplay></video>
<br />

<strong>Log:</strong>
<br />
<pre id="log"></pre>

Die wichtigsten Bestandteile des HTML sind:

  1. Ein <button> mit der Beschriftung „Start Capture“. Bei einem Klick ruft er die Funktion startCapture() auf, um Zugriff auf Bildschirminhalte anzufordern und deren Erfassung zu starten.
  2. Eine zweite Schaltfläche mit der Beschriftung „Stop Capture“. Bei einem Klick ruft sie stopCapture() auf, um die Erfassung zu beenden.
  3. Ein <video>-Element, in das die erfassten Bildschirminhalte gestreamt werden.
  4. Ein <pre>-Block, in den die abgefangene console-Methode Protokolltext schreibt.

CSS

Das CSS dient in diesem Beispiel ausschließlich der Darstellung. Das Video erhält einen Rahmen und eine Breite, die nahezu den gesamten verfügbaren horizontalen Platz einnimmt (width: 98%). Mit max-width wird bei 860px eine absolute Obergrenze für die Videobreite festgelegt.

css
#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

So sieht das fertige Beispiel aus. Wenn Ihr Browser die Screen Capture API unterstützt, öffnet ein Klick auf „Start Capture“ die Benutzeroberfläche des User Agents, in der Sie einen Bildschirm, ein Fenster oder ein Tab zur Freigabe auswählen können.

Sicherheit

Damit die API bei aktivierter Permissions Policy funktioniert, benötigen Sie die Berechtigung display-capture. Diese können Sie über den HTTP-Header Permissions-Policy erteilen oder – wenn Sie die Screen Capture API in einem <iframe> verwenden – über das Attribut allow des <iframe>-Elements.

Die folgende Zeile in den HTTP-Headern aktiviert beispielsweise die Screen Capture API für das Dokument und alle eingebetteten <iframe>-Elemente, die vom selben Origin geladen werden:

http
Permissions-Policy: display-capture=(self)

Wenn Sie eine Bildschirmaufnahme innerhalb eines <iframe> durchführen, können Sie die Berechtigung nur für diesen Frame anfordern. Das ist sicherer, als die Berechtigung allgemeiner zu erteilen:

html
<iframe src="https://mycode.example.net/etc" allow="display-capture"> </iframe>

Browser-Kompatibilität

Siehe auch