Signatur
Beschreibung
Die Eigenschaft deviceId eines MediaDeviceInfo-Objekts enthält einen undurchsichtigen Bezeichner für ein Kamera-, Mikrofon- oder Audioausgabegerät. Solche Objekte liefert navigator.mediaDevices.enumerateDevices(). Der Wert gilt pro Ursprung: Zwei verschiedene Websites erhalten für dasselbe physische Gerät unterschiedliche IDs. Das soll verhindern, dass Nutzer seitenübergreifend verfolgt werden können (Fingerprinting).
Der wichtigste Einsatzzweck ist die gezielte Auswahl eines Geräts. Man übergibt die ID als Constraint an getUserMedia(), etwa { video: { deviceId: { exact: id } } }, oder bei Audioausgabegeräten an HTMLMediaElement.setSinkId(). Die ID bleibt über Sitzungen hinweg gleich. Deshalb kann man sie in localStorage speichern und das zuletzt gewählte Gerät beim nächsten Besuch automatisch wieder verwenden.
Was man tatsächlich erhält, hängt von den Berechtigungen ab. Solange die Seite keine Medienberechtigung hat, geben Browser oft eine leere Zeichenkette zurück oder listen nur ein Gerät pro Art auf. Die vollständige, dauerhafte ID erscheint meist erst, nachdem der Nutzer getUserMedia() zugestimmt hat oder die Berechtigung dauerhaft erteilt wurde. Löscht der Nutzer Cookies oder Website-Daten, erzeugt der Browser neue IDs.
Daneben gibt es Sonderwerte: "default" steht für das Standardgerät des Systems, "communications" (unter Windows in Chrome) für das Standardgerät für Kommunikation.
Rückgabewert
"default" sein.Beispiele
Alle Geräte mit ihrer ID auflisten
const listDevices = async () => {
// Erst Berechtigung holen, damit die IDs vollständig sind
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach((t) => t.stop());
const devices = await navigator.mediaDevices.enumerateDevices();
for (const { kind, label, deviceId } of devices) {
console.log(`${kind}: ${label || '(ohne Namen)'} → ${deviceId}`);
}
};
listDevices().catch(console.error);
Bestimmte Kamera per deviceId öffnen
const startCamera = async (deviceId) => {
const stream = await navigator.mediaDevices.getUserMedia({
video: { deviceId: { exact: deviceId } }
});
document.querySelector('video').srcObject = stream;
return stream;
};
const select = document.querySelector('#camera-select');
const devices = await navigator.mediaDevices.enumerateDevices();
devices
.filter((d) => d.kind === 'videoinput')
.forEach((d, i) => select.add(new Option(d.label || `Kamera ${i + 1}`, d.deviceId)));
select.addEventListener('change', () => startCamera(select.value));
Gewähltes Mikrofon merken und wiederverwenden
const KEY = 'preferredMic';
const getMicStream = async () => {
const saved = localStorage.getItem(KEY);
const devices = await navigator.mediaDevices.enumerateDevices();
const available = devices.some((d) => d.kind === 'audioinput' && d.deviceId === saved);
// ideal statt exact: fällt auf ein anderes Gerät zurück, falls es fehlt
const stream = await navigator.mediaDevices.getUserMedia({
audio: available ? { deviceId: { ideal: saved } } : true
});
const usedId = stream.getAudioTracks()[0].getSettings().deviceId;
localStorage.setItem(KEY, usedId);
console.log('Verwendetes Mikrofon:', usedId);
return stream;
};
getMicStream();
Audioausgabe auf ein bestimmtes Gerät umleiten
const audio = document.querySelector('audio');
const outputs = (await navigator.mediaDevices.enumerateDevices())
.filter((d) => d.kind === 'audiooutput');
if (outputs.length > 1 && 'setSinkId' in audio) {
await audio.setSinkId(outputs[1].deviceId);
console.log('Ausgabe umgeleitet auf', outputs[1].label);
}
// Wichtig · Fallstricke
- Leere IDs ohne Berechtigung: Vor der Zustimmung zu
getUserMedia()istdeviceIdhäufig"". Auchlabelist dann leer. Rufen SieenumerateDevices()deshalb erst nach erteilter Berechtigung erneut auf. - Nur in sicheren Kontexten:
navigator.mediaDevicesgibt es nur unter HTTPS oderlocalhost. - Pro Ursprung, nicht global: IDs lassen sich nicht zwischen Domains austauschen. Nach dem Löschen der Website-Daten oder im privaten Modus können sie sich ändern. Gespeicherte IDs sollten Sie daher immer gegen die aktuelle Geräteliste prüfen.
exactoderideal: Mit{ exact: id }scheitertgetUserMedia()mitOverconstrainedError, wenn das Gerät nicht mehr vorhanden ist.{ ideal: id }weicht in diesem Fall auf ein anderes Gerät aus.- Datenschutz: Die ID ist ein dauerhafter Bezeichner. Behandeln Sie sie wie personenbezogene Daten und senden Sie sie nicht unnötig an den Server.
- Browserunterschiede:
"default"und"communications"kommen vor allem in Chromium-Browsern vor.audiooutput-Geräte undsetSinkId()unterstützt Safari nur eingeschränkt. - Auf das Ereignis
devicechangevonnavigator.mediaDevicesreagieren Sie am besten, indem Sie die Liste der IDs neu einlesen.