Signatur
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 einenMediaStream.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
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);
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);
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);
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);
// Wichtig · Fallstricke
- Sicherer Kontext: Über HTTP ist
navigator.mediaDevicesundefined. Ein direkter Aufruf wienavigator.mediaDevices.getUserMedia()wirft dann einenTypeError. Deshalb Optional Chaining (?.) verwenden. - Berechtigungen:
getUserMedia()undgetDisplayMedia()ö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 Attributallow="camera; microphone; display-capture". - Datenschutz bei
enumerateDevices(): Solange keine Berechtigung erteilt wurde, sindlabelund teilweisedeviceIdleer. Erst nach einem erfolgreichengetUserMedia()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 wiewebkitGetUserMediaist 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 Attributplaysinlinehaben.