Signatur
Beschreibung
Das Interface MediaDevices gehört zur Media Capture and Streams API und ist der zentrale Einstiegspunkt für den Zugriff auf Medienhardware im Browser. Es gibt keinen öffentlichen Konstruktor. Man erhält die einzige Instanz immer über navigator.mediaDevices.
Die wichtigsten Methoden:
getUserMedia(constraints): fragt die Berechtigung für Kamera und/oder Mikrofon an und liefert einenMediaStream.getDisplayMedia(options): startet eine Bildschirm-, Fenster- oder Tab-Freigabe.enumerateDevices(): liefert eine Liste vonMediaDeviceInfo-Objekten (Kameras, Mikrofone, Audioausgänge).getSupportedConstraints(): gibt an, welche Constraints (z. B.width,facingMode,echoCancellation) der Browser versteht.selectAudioOutput()(experimentell): lässt Nutzende einen Audioausgang auswählen.
Da MediaDevices von EventTarget erbt, feuert es das Ereignis devicechange, wenn ein Gerät angeschlossen oder entfernt wird. Darauf reagiert man mit addEventListener("devicechange", …) oder über die Eigenschaft ondevicechange. Einsatzgebiete sind Videokonferenzen (WebRTC), Foto- und Scanner-Funktionen, Audioaufnahmen mit MediaRecorder und Screencasting.
Alle Methoden zur Aufnahme arbeiten asynchron mit Promises und benötigen einen sicheren Kontext (HTTPS oder localhost). Außerdem muss der Nutzer die Berechtigung erteilen. Deshalb gehört eine saubere Fehlerbehandlung (NotAllowedError, NotFoundError, OverconstrainedError) immer dazu.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $constraints | MediaStreamConstraints | {} | Für getUserMedia(): Objekt mit audio und/oder video (jeweils boolean oder MediaTrackConstraints). Mindestens eines davon muss gesetzt sein. |
| $options | DisplayMediaStreamOptions | { video: true } | Für getDisplayMedia(): steuert video, audio und Hinweise wie preferCurrentTab oder selfBrowserSurface. |
Beispiele
Instanz holen und Kamera im Video-Element anzeigen
const video = document.querySelector('video');
const startCamera = async () => {
if (!navigator.mediaDevices?.getUserMedia) {
console.warn('getUserMedia wird nicht unterstützt (kein sicherer Kontext?)');
return;
}
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: { ideal: 1280 }, height: { ideal: 720 }, facingMode: 'user' },
audio: false
});
video.srcObject = stream;
await video.play();
console.log('Kamera aktiv:', stream.getVideoTracks()[0].label);
} catch (err) {
if (err.name === 'NotAllowedError') console.error('Zugriff verweigert');
else if (err.name === 'NotFoundError') console.error('Keine Kamera gefunden');
else console.error(err);
}
};
startCamera();
Geräte auflisten und bei Änderungen aktualisieren
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}`);
cams.forEach(c => console.log(c.deviceId, c.label || '(Label erst nach Freigabe)'));
};
const onChange = () => {
console.log('Gerät angeschlossen/entfernt');
listDevices();
};
navigator.mediaDevices.addEventListener('devicechange', onChange);
listDevices();
// Später wieder abmelden:
// navigator.mediaDevices.removeEventListener('devicechange', onChange);
// Alternativ: navigator.mediaDevices.ondevicechange = onChange;
Bildschirmfreigabe starten und Ende erkennen
const shareButton = document.querySelector('#share');
shareButton.addEventListener('click', async () => {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: { frameRate: 30 },
audio: true
});
const [track] = stream.getVideoTracks();
console.log('Freigabe:', track.getSettings().displaySurface);
// Nutzer beendet die Freigabe über die Browser-Leiste
track.addEventListener('ended', () => console.log('Freigabe beendet'));
} catch (err) {
console.error('Freigabe abgebrochen:', err.name);
}
});
Unterstützte Constraints prüfen
const supported = navigator.mediaDevices.getSupportedConstraints();
const audio = {
echoCancellation: supported.echoCancellation ? true : undefined,
noiseSuppression: supported.noiseSuppression ? true : undefined
};
console.log(supported.facingMode, supported.echoCancellation);
const stream = await navigator.mediaDevices.getUserMedia({ audio });
console.log(stream.getAudioTracks()[0].getSettings());
// Wichtig · Fallstricke
- Nur im sicheren Kontext: Auf reinem HTTP (außer
localhost) istnavigator.mediaDevicesundefined. Deshalb vor dem Zugriff mitnavigator.mediaDevices?.getUserMediaprüfen. - Berechtigungen und Datenschutz:
enumerateDevices()gibtlabelund oft auchdeviceIderst zurück, nachdem eine Berechtigung erteilt wurde. In iframes muss der Zugriff über das Attributallow="camera; microphone; display-capture"bzw. die Permissions Policy erlaubt sein. - Nutzeraktion nötig:
getDisplayMedia()muss durch eine Nutzeraktion wie einen Klick ausgelöst werden. Auf den meisten mobilen Browsern wird es nicht unterstützt. - Ressourcen freigeben: Die Kamera-LED bleibt an, bis alle Tracks mit
stream.getTracks().forEach(t => t.stop())beendet werden. - Constraints:
exact-Werte, die das Gerät nicht erfüllen kann, führen zu einemOverconstrainedError. Besser istideal. - Die veraltete Funktion
navigator.getUserMedia()(mit Callbacks) sollte nicht mehr verwendet werden.selectAudioOutput()ist experimentell und wird derzeit fast nur von Firefox unterstützt.