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

MediaDevices.getUserMedia()

Methode

Fragt den Benutzer um Erlaubnis für Kamera und/oder Mikrofon und liefert ein Promise auf einen <code>MediaStream</code> mit den angeforderten Spuren.

seit JavaScript Baseline: alle modernen Browser (seit 2017) Kategorie: webapi

Signatur

MediaDevices.prototype.getUserMedia(constraints)

Beschreibung

navigator.mediaDevices.getUserMedia() ist der Standardweg, um im Browser auf Kamera und Mikrofon zuzugreifen. Die Methode zeigt dem Benutzer einen Berechtigungsdialog. Stimmt er zu, wird das Promise mit einem MediaStream erfüllt, der je nach Anforderung Video- und/oder Audiospuren (MediaStreamTrack) enthält.

Welche Medien man möchte und in welcher Qualität, legt man über ein Constraints-Objekt fest. Mit { video: true, audio: true } fordert man einfach beide Gerätearten an. Man kann aber auch genauer werden: Auflösung, Bildrate, Front- oder Rückkamera (facingMode), eine bestimmte deviceId oder Audio-Optionen wie echoCancellation. Werte lassen sich als ideal (Wunsch), exact (Pflicht) oder als Bereich mit min/max angeben.

Typische Einsätze sind Videotelefonie mit WebRTC (RTCPeerConnection), Fotos direkt im Browser, Barcode- und QR-Scanner, Sprachaufnahmen mit MediaRecorder und Audio-Analyse mit der Web Audio API. Den Stream zeigt man meist an, indem man ihn der Eigenschaft srcObject eines <video>-Elements zuweist.

Wichtig: Die API gibt es nur in einem sicheren Kontext (HTTPS oder localhost). Nach der Nutzung sollte man alle Spuren mit track.stop() beenden. Erst dann geht die Aufnahme-Anzeige (etwa die Kamera-LED) aus und das Gerät ist wieder frei.

Parameter

Name Typ Default Beschreibung
$constraints Pflicht MediaStreamConstraints Objekt mit den Schlüsseln audio und/oder video. Jeder Wert ist entweder boolean oder ein MediaTrackConstraints-Objekt, z. B. { width: { ideal: 1280 }, facingMode: 'user' }. Mindestens einer der beiden Schlüssel muss angefordert werden, sonst wird ein TypeError geworfen.

Rückgabewert

Typ
Promise<MediaStream>
Beschreibung
Promise, das mit einem MediaStream erfüllt wird, sobald der Benutzer zustimmt. Es wird mit einer DOMException abgelehnt, u. a. mit folgenden Namen: NotAllowedError (Zugriff verweigert oder unsicherer Kontext), NotFoundError (kein passendes Gerät), NotReadableError (Gerät belegt oder Hardwarefehler), OverconstrainedError (exact/min-Vorgaben nicht erfüllbar; die Eigenschaft constraint nennt die betroffene Vorgabe), AbortError und SecurityError. Bei ungültigen Constraints wird mit einem TypeError abgelehnt.

Beispiele

Kamerabild in einem video-Element anzeigen

// HTML: <video id="preview" autoplay playsinline muted></video>
const video = document.querySelector('#preview');

const startCamera = async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      video: { width: { ideal: 1280 }, height: { ideal: 720 } },
      audio: false
    });
    video.srcObject = stream;
    const [track] = stream.getVideoTracks();
    console.log('Kamera aktiv:', track.label, track.getSettings());
  } catch (err) {
    console.error(`${err.name}: ${err.message}`);
  }
};

startCamera();
Kamera aktiv: FaceTime HD Camera {width: 1280, height: 720, frameRate: 30, ...}

Fehler gezielt behandeln und Rückkamera bevorzugen

const getRearCamera = async () => {
  try {
    return await navigator.mediaDevices.getUserMedia({
      video: { facingMode: { ideal: 'environment' } }
    });
  } catch (err) {
    switch (err.name) {
      case 'NotAllowedError':
        alert('Bitte erlaube den Kamerazugriff in den Browser-Einstellungen.');
        break;
      case 'NotFoundError':
        alert('Es wurde keine Kamera gefunden.');
        break;
      case 'NotReadableError':
        alert('Die Kamera wird bereits von einer anderen Anwendung verwendet.');
        break;
      case 'OverconstrainedError':
        console.warn('Vorgabe nicht erfüllbar:', err.constraint);
        break;
      default:
        console.error(err);
    }
    return null;
  }
};

const stream = await getRearCamera();
console.log(stream ? 'Stream bereit' : 'Kein Stream');
Stream bereit

Sprachnachricht aufnehmen und Mikrofon wieder freigeben

const recordAudio = async (durationMs = 3000) => {
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: { echoCancellation: true, noiseSuppression: true }
  });
  const recorder = new MediaRecorder(stream);
  const chunks = [];
  recorder.ondataavailable = (e) => chunks.push(e.data);

  const stopped = new Promise((resolve) => (recorder.onstop = resolve));
  recorder.start();
  setTimeout(() => recorder.stop(), durationMs);
  await stopped;

  // Wichtig: alle Spuren beenden, damit das Mikrofon frei wird
  stream.getTracks().forEach((track) => track.stop());

  return new Blob(chunks, { type: recorder.mimeType });
};

const blob = await recordAudio();
console.log(`Aufnahme: ${blob.size} Bytes, ${blob.type}`);
Aufnahme: 48213 Bytes, audio/webm;codecs=opus

Ein bestimmtes Gerät per deviceId auswählen

// Gerätenamen (label) gibt es erst nach einer erteilten Berechtigung
const devices = await navigator.mediaDevices.enumerateDevices();
const mics = devices.filter((d) => d.kind === 'audioinput');
console.log(mics.map((m) => m.label));

const stream = await navigator.mediaDevices.getUserMedia({
  audio: { deviceId: { exact: mics[0].deviceId } }
});
console.log('Verwendet:', stream.getAudioTracks()[0].label);
["Standard - MacBook Pro-Mikrofon", "USB-Headset"] Verwendet: Standard - MacBook Pro-Mikrofon

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: Auf reinen HTTP-Seiten (außer localhost) ist navigator.mediaDevices undefined. Prüfe das vor dem Aufruf, etwa mit if (!navigator.mediaDevices?.getUserMedia).
  • iframes: Eingebettete Inhalte brauchen die Freigabe über die Berechtigungsrichtlinie, z. B. <iframe allow="camera; microphone">. Sonst wird mit NotAllowedError abgelehnt.
  • Das Promise wird eventuell nie erledigt: Schließt der Benutzer den Berechtigungsdialog nicht, bleibt das Promise offen. Die Oberfläche sollte darauf nicht blockierend warten.
  • Spuren beenden: Ohne track.stop() bleiben Kamera bzw. Mikrofon aktiv, auch wenn das <video>-Element entfernt wurde. Das ist ein Datenschutzproblem.
  • exact sparsam verwenden: exact- und min-Vorgaben führen schnell zu OverconstrainedError. Mit ideal sucht der Browser die beste verfügbare Näherung.
  • Autoplay auf iOS/Safari: Das <video>-Element braucht playsinline und meist muted. Sonst wird der Stream nicht inline abgespielt.
  • Veraltete API: navigator.getUserMedia() und Varianten mit Präfix wie webkitGetUserMedia sind veraltet und arbeiten mit Callbacks. Verwende ausschließlich navigator.mediaDevices.getUserMedia().
  • Bildschirmfreigabe läuft nicht über diese Methode, sondern über getDisplayMedia().