Start · Sprachen · JavaScript · Referenz · Navigator.mediaDevices

Navigator.mediaDevices

Eigenschaft

Schreibgeschützte Eigenschaft, die ein <code>MediaDevices</code>-Objekt für den Zugriff auf Kameras, Mikrofone und die Bildschirmfreigabe zurückgibt.

seit JavaScript Baseline: alle modernen Browser (Chrome 47+, Firef Kategorie: webapi

Signatur

Navigator.mediaDevices

Beschreibung

navigator.mediaDevices ist der Einstiegspunkt für die Media Capture and Streams API. Das zurückgegebene MediaDevices-Objekt ist ein Singleton: Jeder Zugriff liefert dasselbe Objekt. Es bietet unter anderem diese Methoden:

  • getUserMedia(constraints): fordert Kamera- und/oder Mikrofonzugriff an und liefert einen MediaStream.
  • getDisplayMedia(options): startet eine Bildschirm-, Fenster- oder Tab-Freigabe.
  • enumerateDevices(): listet die verfügbaren Ein- und Ausgabegeräte auf.
  • getSupportedConstraints(): zeigt, welche Constraints (z. B. facingMode, frameRate) der Browser kennt.

Man nutzt die Eigenschaft für Videotelefonie (WebRTC), Foto- und Barcode-Scanner, Sprachaufnahmen, Bildschirmaufzeichnung und Geräteauswahl-Menüs. Mit dem devicechange-Event, das auf navigator.mediaDevices ausgelöst wird, lässt sich darauf reagieren, wenn Geräte angeschlossen oder entfernt werden.

Wichtig: Die Eigenschaft gibt es nur in einem sicheren Kontext (HTTPS oder localhost). Über unverschlüsseltes HTTP ist navigator.mediaDevices undefined. Deshalb sollte man vor der Nutzung immer prüfen, ob sie vorhanden ist.

Rückgabewert

Typ
MediaDevices | undefined
Beschreibung
Das MediaDevices-Singleton des aktuellen Browsing-Kontexts. In unsicheren Kontexten (HTTP) ist der Wert undefined.

Beispiele

Unterstützung prüfen und Kamera in einem Video-Element anzeigen

const startCamera = async () => {
  if (!navigator.mediaDevices?.getUserMedia) {
    console.warn('Kamerazugriff nicht verfügbar (HTTPS erforderlich?)');
    return;
  }
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: { width: { ideal: 1280 }, facingMode: 'user' },
      audio: false
    });
    const video = document.querySelector('video');
    video.srcObject = stream;
    await video.play();
    console.log('Kamera aktiv:', stream.getVideoTracks()[0].label);
  } catch (err) {
    // NotAllowedError = Nutzer hat abgelehnt, NotFoundError = keine Kamera
    console.error(`${err.name}: ${err.message}`);
  }
};

document.querySelector('#start').addEventListener('click', startCamera);
Kamera aktiv: FaceTime HD Camera

Geräteliste für ein Auswahlmenü erzeugen

const fillDeviceSelect = async () => {
  const devices = await navigator.mediaDevices.enumerateDevices();
  const cams = devices.filter((d) => d.kind === 'videoinput');
  const select = document.querySelector('#camera-select');
  select.replaceChildren(
    ...cams.map((cam, i) => new Option(cam.label || `Kamera ${i + 1}`, cam.deviceId))
  );
  console.log(`${cams.length} Kamera(s) gefunden`);
};

fillDeviceSelect();
// Liste bei An-/Abstecken automatisch aktualisieren
navigator.mediaDevices.addEventListener('devicechange', fillDeviceSelect);
2 Kamera(s) gefunden

Bildschirm freigeben und Freigabe-Ende erkennen

const shareScreen = async () => {
  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: true,
    audio: true
  });
  const [track] = stream.getVideoTracks();
  document.querySelector('#preview').srcObject = stream;

  // Wird ausgelöst, wenn der Nutzer über die Browser-Leiste beendet
  track.addEventListener('ended', () => console.log('Freigabe beendet'));
  return stream;
};

document.querySelector('#share').addEventListener('click', shareScreen);
Freigabe beendet

Stream sauber beenden

const stopStream = (stream) => {
  stream.getTracks().forEach((track) => track.stop());
};

const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
// ... Aufnahme ...
stopStream(stream);
console.log(stream.active);
false

// Wichtig · Fallstricke

  • Sicherer Kontext: Über HTTP ist navigator.mediaDevices undefined. Ein direkter Aufruf wie navigator.mediaDevices.getUserMedia() wirft dann einen TypeError. Deshalb Optional Chaining (?.) verwenden.
  • Berechtigungen: getUserMedia() und getDisplayMedia() öffnen einen Berechtigungsdialog. getDisplayMedia() muss in fast allen Browsern durch eine Nutzeraktion (z. B. Klick) ausgelöst werden. In iframes braucht man zusätzlich das Attribut allow="camera; microphone; display-capture".
  • Datenschutz bei enumerateDevices(): Solange keine Berechtigung erteilt wurde, sind label und teilweise deviceId leer. Erst nach einem erfolgreichen getUserMedia() bekommt man vollständige Angaben.
  • Ressourcen freigeben: Tracks immer mit track.stop() beenden. Sonst bleiben Kamera-LED und Mikrofon-Anzeige an.
  • Veraltete APIs: Das alte navigator.getUserMedia() mit Callbacks und Präfix-Varianten wie webkitGetUserMedia ist veraltet und sollte nicht mehr verwendet werden.
  • Mobil: getDisplayMedia() wird auf iOS und den meisten Android-Browsern nicht unterstützt. Auf iOS muss das Video-Element für die Inline-Wiedergabe das Attribut playsinline haben.