2022-09-27 15:19:48 +00:00
|
|
|
/*
|
|
|
|
Copyright 2022 Matrix.org Foundation C.I.C.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2022-09-29 12:19:46 +00:00
|
|
|
import { logger } from "matrix-js-sdk/src/logger";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds a media device with label matching 'deviceName'
|
|
|
|
* @param deviceName The label of the device to look for
|
|
|
|
* @param devices The list of devices to search
|
|
|
|
* @returns A matching media device or undefined if no matching device was found
|
|
|
|
*/
|
2022-09-27 15:19:48 +00:00
|
|
|
export async function findDeviceByName(
|
2022-09-29 12:19:46 +00:00
|
|
|
deviceName: string,
|
2022-09-29 16:07:10 +00:00
|
|
|
kind: MediaDeviceKind,
|
2022-09-29 12:19:46 +00:00
|
|
|
devices: MediaDeviceInfo[]
|
2022-09-27 15:19:48 +00:00
|
|
|
): Promise<string | undefined> {
|
2022-09-29 16:07:10 +00:00
|
|
|
const deviceInfo = devices.find(
|
|
|
|
(d) => d.kind === kind && d.label === deviceName
|
|
|
|
);
|
2022-09-27 15:19:48 +00:00
|
|
|
return deviceInfo?.deviceId;
|
|
|
|
}
|
2022-09-29 12:19:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the available audio input/output and video input devices
|
|
|
|
* from the browser: a wrapper around mediaDevices.enumerateDevices()
|
|
|
|
* that requests a stream and holds it while calling enumerateDevices().
|
|
|
|
* This is because some browsers (Firefox) only return device labels when
|
|
|
|
* the app has an active user media stream. In Chrome, this will get a
|
|
|
|
* stream from the default camera which can mean, for example, that the
|
|
|
|
* light for the FaceTime camera turns on briefly even if you selected
|
|
|
|
* another camera. Once the Permissions API
|
|
|
|
* (https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)
|
|
|
|
* is ready for primetime, this should allow us to avoid this.
|
|
|
|
*
|
|
|
|
* @return The available media devices
|
|
|
|
*/
|
|
|
|
export async function getDevices(): Promise<MediaDeviceInfo[]> {
|
2022-09-29 16:08:48 +00:00
|
|
|
let stream: MediaStream;
|
2022-09-29 12:19:46 +00:00
|
|
|
try {
|
|
|
|
stream = await navigator.mediaDevices.getUserMedia({
|
|
|
|
audio: true,
|
|
|
|
video: true,
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
logger.info("Couldn't get media stream for enumerateDevices: failing");
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
return await navigator.mediaDevices.enumerateDevices();
|
|
|
|
} catch (error) {
|
|
|
|
logger.warn("Unable to refresh WebRTC Devices: ", error);
|
|
|
|
} finally {
|
|
|
|
for (const track of stream.getTracks()) {
|
|
|
|
track.stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|