Signatur
Beschreibung
Das Ereignis devicechange wird an das MediaDevices-Objekt (navigator.mediaDevices) gesendet, wenn sich die Liste der verfügbaren Mediengeräte ändert. Das passiert zum Beispiel, wenn ein USB-Headset eingesteckt, eine Webcam abgezogen oder ein Bluetooth-Lautsprecher verbunden wird. Auch wenn sich Geräteberechtigungen ändern, kann das Ereignis ausgelöst werden.
Das Ereignis enthält keine Angaben dazu, welches Gerät hinzugekommen oder weggefallen ist. Es ist ein einfaches Event. Um die aktuelle Liste zu bekommen, rufen Sie im Handler navigator.mediaDevices.enumerateDevices() erneut auf und vergleichen das Ergebnis mit dem vorherigen Stand.
Typische Anwendungen sind Geräteauswahl-Menüs in Videokonferenz-Apps, die automatisch aktualisiert werden, ein automatischer Wechsel auf ein neu angeschlossenes Headset oder ein Rückfall auf ein anderes Mikrofon, wenn das aktive Gerät entfernt wurde.
Sie können den Handler mit addEventListener("devicechange", handler) registrieren oder über die Eigenschaft navigator.mediaDevices.ondevicechange setzen. Über die Eigenschaft ist immer nur ein Handler möglich, und eine neue Zuweisung überschreibt den alten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, immer "devicechange". |
|
| $handler Pflicht | (event: Event) => void | Rückruffunktion, die ein einfaches Event ohne Geräteinformationen bekommt. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once oder signal (z. B. ein AbortSignal, um den Listener wieder zu entfernen). |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein Event-Objekt mit type === "devicechange".Beispiele
Geräteliste bei Änderungen neu laden (addEventListener)
const listDevices = async () => {
const devices = await navigator.mediaDevices.enumerateDevices();
const cams = devices.filter((d) => d.kind === 'videoinput');
const mics = devices.filter((d) => d.kind === 'audioinput');
console.log(`Kameras: ${cams.length}, Mikrofone: ${mics.length}`);
};
navigator.mediaDevices.addEventListener('devicechange', listDevices);
listDevices(); // Anfangszustand
Hinzugefügte und entfernte Geräte ermitteln
let known = new Map();
const snapshot = async () => {
const devices = await navigator.mediaDevices.enumerateDevices();
return new Map(devices.map((d) => [d.deviceId + d.kind, d]));
};
const onChange = async () => {
const current = await snapshot();
for (const [id, d] of current) {
if (!known.has(id)) console.log('Neu:', d.kind, d.label || '(ohne Name)');
}
for (const [id, d] of known) {
if (!current.has(id)) console.log('Entfernt:', d.kind, d.label || '(ohne Name)');
}
known = current;
};
known = await snapshot();
navigator.mediaDevices.addEventListener('devicechange', onChange);
Auf anderes Mikrofon ausweichen, wenn das aktive entfernt wurde
let stream = await navigator.mediaDevices.getUserMedia({ audio: true });
navigator.mediaDevices.ondevicechange = async () => {
const [track] = stream.getAudioTracks();
if (track.readyState === 'ended') {
console.log('Aktives Mikrofon verloren – wechsle auf Standardgerät');
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
}
};
Listener per AbortController entfernen
const controller = new AbortController();
navigator.mediaDevices.addEventListener(
'devicechange',
() => console.log('Geräteliste geändert'),
{ signal: controller.signal }
);
// Beim Verlassen der Ansicht aufräumen:
controller.abort();
// Alternativ bei der Eigenschaft:
navigator.mediaDevices.ondevicechange = null;
// Wichtig · Fallstricke
- Keine Details im Ereignis: Das Event sagt nicht, welches Gerät betroffen ist. Rufen Sie immer
enumerateDevices()auf und vergleichen Sie selbst. - Mehrfache Auslösung: Ein einziges Headset kann mehrere Ereignisse direkt nacheinander auslösen, etwa für Ein- und Ausgabe getrennt. Fassen Sie die Ereignisse bei Bedarf mit einem kurzen Debounce zusammen.
- Datenschutz: Ohne erteilte Kamera- oder Mikrofonberechtigung sind
labelleer unddeviceIdoft leer oder anonymisiert. Manche Browser lösendevicechangeerst aus, wenn die Seite sichtbar ist oder bereits eine Berechtigung hat. Das soll verhindern, dass Nutzer über ihre Hardware verfolgt werden (Fingerprinting). - Sicherer Kontext:
navigator.mediaDevicesgibt es nur unter HTTPS oder auflocalhost. Unter HTTP ist esundefined, undaddEventListenerwirft dann einen Fehler. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Safari unterstützt es ab Version 11. Audioausgabegeräte (
audiooutput) werden in Firefox und Safari nur eingeschränkt aufgelistet. - Ein entferntes aktives Gerät beendet den zugehörigen
MediaStreamTrack(ended-Ereignis). Oft ist es zuverlässiger, zusätzlich darauf zu reagieren.