Start · Sprachen · JavaScript · Referenz · MediaDevices.getDisplayMedia()

MediaDevices.getDisplayMedia()

Methode

Fordert den Benutzer auf, einen Bildschirm, ein Fenster oder einen Tab auszuwählen, und liefert dessen Inhalt als <code>MediaStream</code> für Bildschirmfreigabe oder Aufnahme.

seit JavaScript Baseline (Desktop): Chrome 72, Edge 79, Firefox 66 Kategorie: webapi

Signatur

MediaDevices.prototype.getDisplayMedia(options)

Beschreibung

navigator.mediaDevices.getDisplayMedia() ist die Standard-API für Bildschirmfreigabe im Browser. Beim Aufruf zeigt der Browser einen eigenen Auswahldialog an. Darin wählt der Benutzer einen ganzen Bildschirm, ein einzelnes Anwendungsfenster oder einen Browser-Tab aus. Das zurückgegebene Promise wird mit einem MediaStream erfüllt, der mindestens eine Videospur enthält. Je nach Browser und Auswahl kann auch eine Audiospur dabei sein, etwa der Ton eines Tabs.

Typische Anwendungsfälle sind Videokonferenzen über WebRTC (Spur per RTCPeerConnection.addTrack() senden), Bildschirmaufnahmen mit MediaRecorder, Screenshots über ein <video>- und <canvas>-Element sowie Vorschauen beim Präsentieren.

Anders als bei getUserMedia() kann die Webseite keine bestimmte Quelle vorgeben. Die Auswahl trifft immer der Benutzer. Mit Einschränkungen (Constraints) und Hinweisen wie displaySurface lässt sich nur eine Voreinstellung für den Dialog vorschlagen. Der Aufruf muss aus einer Benutzeraktion heraus erfolgen, etwa einem Klick (vorübergehende Benutzeraktivierung). Außerdem ist ein sicherer Kontext (HTTPS oder localhost) nötig.

Die Freigabe endet, wenn der Benutzer in der Browser-Oberfläche auf „Freigabe beenden“ klickt. Dann wird auf der Videospur das Ereignis ended ausgelöst. Darauf sollte die Anwendung immer reagieren und ihre Oberfläche entsprechend zurücksetzen.

Parameter

Name Typ Default Beschreibung
$options object { video: true } Optionales Konfigurationsobjekt mit den folgenden Eigenschaften.
$options.video boolean | MediaTrackConstraints true Einschränkungen für die Videospur, z. B. { frameRate: 30, width: { max: 1920 }, displaySurface: 'monitor' | 'window' | 'browser' }. false ist nicht erlaubt und führt zu einem TypeError.
$options.audio boolean | MediaTrackConstraints false Fordert zusätzlich Audio an, z. B. Tab-Ton oder Systemton. Ob Audio tatsächlich geliefert wird, hängt von Browser, Betriebssystem und gewählter Quelle ab.
$options.preferCurrentTab boolean false Schlägt den aktuellen Tab als Quelle im Dialog vor (nur Chromium).
$options.selfBrowserSurface 'include' | 'exclude' Legt fest, ob der aktuelle Tab im Dialog angeboten wird. 'exclude' verhindert den „Spiegelsaal“-Effekt (nur Chromium).
$options.surfaceSwitching 'include' | 'exclude' Legt fest, ob der Browser eine Schaltfläche anbietet, mit der der Benutzer während der Freigabe den Tab wechseln kann (nur Chromium).
$options.systemAudio 'include' | 'exclude' Legt fest, ob Systemton für ganze Bildschirme angeboten wird (nur Chromium).
$options.monitorTypeSurfaces 'include' | 'exclude' Mit 'exclude' werden ganze Bildschirme im Dialog ausgeblendet (nur Chromium).
$options.controller CaptureController Ein CaptureController, mit dem sich die Freigabe weiter steuern lässt, z. B. per setFocusBehavior() (Chromium).

Rückgabewert

Typ
Promise<MediaStream>
Beschreibung
Ein Promise, das mit einem MediaStream erfüllt wird. Der Stream enthält eine Videospur und optional eine Audiospur. Das Promise wird zurückgewiesen mit NotAllowedError (Benutzer bricht ab oder Berechtigungsrichtlinie verbietet den Zugriff), InvalidStateError (keine Benutzeraktivierung oder Dokument nicht aktiv), NotFoundError (keine Quelle verfügbar), NotReadableError (Betriebssystem blockiert den Zugriff), OverconstrainedError oder TypeError (z. B. bei video: false oder nicht erlaubten Constraints wie min/exact).

Beispiele

Bildschirmfreigabe per Klick starten und anzeigen

const button = document.querySelector('#share');
const video = document.querySelector('#preview');

button.addEventListener('click', async () => {
  try {
    const stream = await navigator.mediaDevices.getDisplayMedia({
      video: { frameRate: 30, displaySurface: 'window' },
      audio: false
    });
    video.srcObject = stream;
    await video.play();

    const [track] = stream.getVideoTracks();
    console.log('Freigegeben:', track.getSettings().displaySurface);

    // Benutzer beendet die Freigabe über die Browser-Oberfläche
    track.addEventListener('ended', () => {
      video.srcObject = null;
      console.log('Freigabe beendet');
    });
  } catch (err) {
    if (err.name === 'NotAllowedError') {
      console.warn('Freigabe abgelehnt oder abgebrochen');
    } else {
      console.error(err);
    }
  }
});
Freigegeben: window Freigabe beendet

Bildschirmaufnahme mit MediaRecorder als WebM herunterladen

const recordScreen = async (durationMs = 5000) => {
  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: true // Tab-Ton, sofern verfügbar
  });
  const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
  const chunks = [];

  recorder.addEventListener('dataavailable', (e) => chunks.push(e.data));
  recorder.addEventListener('stop', () => {
    const blob = new Blob(chunks, { type: 'video/webm' });
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'aufnahme.webm';
    a.click();
    URL.revokeObjectURL(a.href);
    stream.getTracks().forEach((t) => t.stop());
  });

  recorder.start();
  setTimeout(() => recorder.stop(), durationMs);
};

document.querySelector('#record').addEventListener('click', () => recordScreen());

Screenshot eines Fensters als PNG erzeugen

const takeScreenshot = async () => {
  const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
  const video = document.createElement('video');
  video.srcObject = stream;
  video.muted = true;
  await video.play();

  const canvas = document.createElement('canvas');
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.getContext('2d').drawImage(video, 0, 0);

  stream.getTracks().forEach((t) => t.stop()); // Freigabe sofort beenden
  const dataUrl = canvas.toDataURL('image/png');
  console.log(`Screenshot ${canvas.width}x${canvas.height}`);
  return dataUrl;
};

document.querySelector('#shot').addEventListener('click', takeScreenshot);
Screenshot 1920x1080

Freigabe in WebRTC-Verbindung ersetzen (Kamera → Bildschirm)

const switchToScreen = async (peerConnection) => {
  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: { width: { max: 1920 }, height: { max: 1080 } }
  });
  const [screenTrack] = stream.getVideoTracks();
  screenTrack.contentHint = 'detail'; // Text scharf halten

  const sender = peerConnection
    .getSenders()
    .find((s) => s.track?.kind === 'video');
  await sender.replaceTrack(screenTrack);
  console.log('Bildschirm wird gesendet');
};
Bildschirm wird gesendet