async function getDeviceCapabilities(kind, deviceId) {
const videoConstraints = {
deviceId: deviceId ? { exact: deviceId } : undefined
const audioConstraints = {
deviceId: deviceId ? { exact: deviceId } : undefined
const constraints = !kind ? undefined :
kind === 'audioinput' ? audioConstraints :
kind === 'videoinput' ? videoConstraints :
new Error('getDeviceCapabilities/unexpected_args', kind)
if (constraints instanceof Error) return
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints)
const capabilities = mediaStream.getTracks().map(track => track.getCapabilities())
mediaStream.getTracks().forEach(track => track.stop())
console.error('getDeviceCapabilities/getUserMedia', err)
const capabilities = await Promise.all(devices.map(d => getCapabilities(d.kind, d.deviceId)))