Signatur
Beschreibung
Die Methode getCapabilities() gehört zur Schnittstelle InputDeviceInfo. Das ist die Variante von MediaDeviceInfo für Eingabegeräte, also Kameras (kind === "videoinput") und Mikrofone (kind === "audioinput"). Du bekommst solche Objekte über navigator.mediaDevices.enumerateDevices(). Die Methode gibt ein MediaTrackCapabilities-Objekt zurück. Es enthält die Wertebereiche und Optionen, die das Gerät für seine primäre Spur unterstützt, zum Beispiel width, height, frameRate, facingMode, echoCancellation oder sampleRate.
Der große Vorteil: Du kannst die Fähigkeiten eines Geräts prüfen, bevor du mit getUserMedia() einen Stream öffnest. So kannst du in einer Geräteauswahl anzeigen, welche Auflösungen eine Kamera unterstützt, oder für getUserMedia() passende Vorgaben (Constraints) bauen, die das Gerät auch wirklich erfüllen kann. Ohne diese Methode musst du erst einen Stream öffnen und dann MediaStreamTrack.getCapabilities() aufrufen.
Bereiche wie width oder frameRate kommen als Objekt mit min und max. Auswahlwerte wie facingMode oder echoCancellation kommen als Array. Die Methode liefert nur dann sinnvolle Werte, wenn die Seite bereits die Berechtigung für Kamera bzw. Mikrofon hat. Sonst ist das Objekt meist leer, genau wie label und deviceId.
Rückgabewert
{ min, max } angegeben (z. B. width, height, frameRate, sampleRate), Auswahlwerte als Array (z. B. facingMode, echoCancellation). Außerdem enthalten sind deviceId und groupId. Fehlt die Berechtigung, ist das Objekt leer.Beispiele
Unterstützte Auflösungen aller Kameras auflisten
const listCameraCapabilities = async () => {
// Berechtigung einholen, sonst sind die Capabilities leer
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
stream.getTracks().forEach((t) => t.stop());
const devices = await navigator.mediaDevices.enumerateDevices();
const cameras = devices.filter((d) => d.kind === 'videoinput');
for (const cam of cameras) {
if (typeof cam.getCapabilities !== 'function') {
console.log(`${cam.label}: getCapabilities() nicht unterstützt`);
continue;
}
const caps = cam.getCapabilities();
console.log(
`${cam.label}: bis ${caps.width?.max}×${caps.height?.max} px, ` +
`max. ${caps.frameRate?.max} fps`
);
}
};
listCameraCapabilities().catch(console.error);
Passende Vorgaben für getUserMedia() aus den Fähigkeiten bauen
const openBestCamera = async (device) => {
const caps = device.getCapabilities();
const clamp = (wish, range) =>
range ? Math.min(Math.max(wish, range.min), range.max) : wish;
const constraints = {
video: {
deviceId: { exact: device.deviceId },
width: { ideal: clamp(1920, caps.width) },
height: { ideal: clamp(1080, caps.height) },
frameRate: { ideal: clamp(60, caps.frameRate) }
}
};
console.log(constraints.video);
return navigator.mediaDevices.getUserMedia(constraints);
};
const devices = await navigator.mediaDevices.enumerateDevices();
const cam = devices.find((d) => d.kind === 'videoinput');
if (cam) {
const stream = await openBestCamera(cam);
document.querySelector('video').srcObject = stream;
}
Mikrofone mit Echounterdrückung finden
const findMicsWithEchoCancellation = async () => {
const devices = await navigator.mediaDevices.enumerateDevices();
return devices
.filter((d) => d.kind === 'audioinput' && typeof d.getCapabilities === 'function')
.filter((d) => d.getCapabilities().echoCancellation?.includes(true))
.map((d) => d.label || '(ohne Namen – keine Berechtigung)');
};
console.log(await findMicsWithEchoCancellation());
// Wichtig · Fallstricke
- Berechtigung nötig: Wenn die Seite noch keinen Zugriff auf Kamera oder Mikrofon hat, gibt
getCapabilities()ein leeres Objekt zurück. Frag vorher übergetUserMedia()nach, oder prüf den Status mit der Permissions-API. - Browser-Unterstützung: Chromium-Browser und neuere Safari-Versionen unterstützen die Methode. Firefox liefert bei
enumerateDevices()nurMediaDeviceInfo-Objekte ohne diese Methode. Prüf deshalb immer mittypeof device.getCapabilities === "function"und nutz sonstMediaStreamTrack.getCapabilities()auf einem geöffneten Stream. - Nur sicherer Kontext:
navigator.mediaDevicesgibt es nur über HTTPS oder auflocalhost. - Nur die primäre Spur: Die Werte beziehen sich auf die Standardspur des Geräts. Ob eine bestimmte Kombination (z. B. höchste Auflösung zusammen mit höchster Bildrate) wirklich funktioniert, ist nicht garantiert. Setz Vorgaben daher lieber mit
idealals mitexact. - Felder können fehlen: Welche Felder vorhanden sind, hängt von Browser und Gerät ab. Greif defensiv darauf zu, z. B. mit
caps.width?.max. - Fingerprinting: Browser können die Werte aus Datenschutzgründen vergröbern oder verschleiern.