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

MediaDevices.enumerateDevices()

Methode

Liefert per Promise eine Liste der verfügbaren Medien-Ein- und -Ausgabegeräte wie Mikrofone, Kameras und Lautsprecher als <code>MediaDeviceInfo</code>-Objekte.

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

Signatur

navigator.mediaDevices.enumerateDevices()

Beschreibung

enumerateDevices() ist eine Methode der Schnittstelle MediaDevices, die über navigator.mediaDevices erreichbar ist. Sie gibt ein Promise zurück, das mit einem Array von MediaDeviceInfo-Objekten erfüllt wird. Jedes Objekt beschreibt ein Gerät mit den Eigenschaften deviceId, groupId, kind ("audioinput", "videoinput" oder "audiooutput") und label.

Typische Anwendungen sind Geräteauswahl-Menüs in Videokonferenz-Apps, das Umschalten zwischen Front- und Rückkamera oder die Wahl des Audio-Ausgabegeräts über HTMLMediaElement.setSinkId(). Mit der ermittelten deviceId kann man anschließend gezielt über getUserMedia({ video: { deviceId: { exact: id } } }) ein bestimmtes Gerät öffnen.

Aus Datenschutzgründen sind die Ergebnisse eingeschränkt, solange die Seite keine Medienberechtigung hat: label ist dann ein leerer String, deviceId kann leer sein, und manche Browser melden pro Gerätetyp nur einen einzigen Platzhalter-Eintrag. Erst nach einem erfolgreichen getUserMedia()-Aufruf werden vollständige Informationen geliefert.

Um auf das An- und Abstecken von Geräten zu reagieren, lauscht man auf das Ereignis devicechange von navigator.mediaDevices und ruft enumerateDevices() erneut auf.

Rückgabewert

Typ
Promise<MediaDeviceInfo[]>
Beschreibung
Ein Promise, das mit einem Array von MediaDeviceInfo-Objekten (bzw. InputDeviceInfo für Eingabegeräte) erfüllt wird. Sind keine Geräte vorhanden oder ist der Zugriff per Berechtigungsrichtlinie gesperrt, ist das Array leer.

Beispiele

Alle Geräte auflisten

const listDevices = async () => {
  if (!navigator.mediaDevices?.enumerateDevices) {
    console.warn('enumerateDevices() wird nicht unterstützt');
    return;
  }
  const devices = await navigator.mediaDevices.enumerateDevices();
  for (const { kind, label, deviceId } of devices) {
    console.log(`${kind}: ${label || '(ohne Label)'} id=${deviceId}`);
  }
};

listDevices();
audioinput: Internes Mikrofon id=default videoinput: FaceTime HD Camera id=3f1c... audiooutput: MacBook-Lautsprecher id=default

Kamera-Auswahl nach Berechtigung befüllen

const select = document.querySelector('#camera-select');
const video = document.querySelector('video');

const fillCameraSelect = async () => {
  // Erst Berechtigung holen, damit Labels sichtbar werden
  const tmp = await navigator.mediaDevices.getUserMedia({ video: true });
  tmp.getTracks().forEach((t) => t.stop());

  const devices = await navigator.mediaDevices.enumerateDevices();
  const cams = devices.filter((d) => d.kind === 'videoinput');
  select.replaceChildren(
    ...cams.map((cam, i) => new Option(cam.label || `Kamera ${i + 1}`, cam.deviceId))
  );
};

select.addEventListener('change', async () => {
  video.srcObject?.getTracks().forEach((t) => t.stop());
  video.srcObject = await navigator.mediaDevices.getUserMedia({
    video: { deviceId: { exact: select.value } }
  });
});

fillCameraSelect().catch((err) => console.error('Kein Kamerazugriff:', err.name));

Auf An- und Abstecken von Geräten reagieren

const countDevices = async () => {
  const devices = await navigator.mediaDevices.enumerateDevices();
  const count = (kind) => devices.filter((d) => d.kind === kind).length;
  console.log(`Mikrofone: ${count('audioinput')}, Kameras: ${count('videoinput')}, Ausgaben: ${count('audiooutput')}`);
};

navigator.mediaDevices.addEventListener('devicechange', countDevices);
countDevices();
Mikrofone: 1, Kameras: 1, Ausgaben: 1 // nach Einstecken eines USB-Headsets: Mikrofone: 2, Kameras: 1, Ausgaben: 2

// Wichtig · Fallstricke

  • Sicherer Kontext erforderlich: navigator.mediaDevices existiert nur unter HTTPS oder localhost; auf HTTP ist es undefined.
  • Leere Labels: Ohne erteilte Kamera-/Mikrofon-Berechtigung ist label leer und die Liste ggf. auf einen Eintrag pro Typ reduziert. Nicht aus leeren Labels auf fehlende Geräte schließen.
  • deviceId ist pro Ursprung eindeutig und wird beim Löschen der Website-Daten neu vergeben. Zum Speichern von Benutzerpräferenzen in localStorage geeignet, aber immer auf Existenz prüfen und label als Fallback nutzen.
  • audiooutput: Firefox und Safari listen Ausgabegeräte teilweise nicht oder erst nach selectAudioOutput()/Berechtigung; setSinkId() ist nicht überall verfügbar.
  • Die Pseudo-IDs "default" und "communications" (Chrome unter Windows) verweisen auf reale Geräte, die ebenfalls in der Liste auftauchen – beim Zählen ggf. über groupId deduplizieren.
  • In Iframes muss die Berechtigungsrichtlinie (allow="camera; microphone") gesetzt sein, sonst fehlen die entsprechenden Geräte.
  • Die Methode ist nur im Dokumentkontext verfügbar, nicht in Web Workern.