2021-09-29 18:30:42 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2023-01-09 18:38:57 +00:00
|
|
|
import type { AudioDevice } from '@signalapp/ringrtc';
|
2021-09-29 18:30:42 +00:00
|
|
|
|
2024-10-07 20:32:31 +00:00
|
|
|
export function findBestMatchingAudioDeviceIndex(
|
|
|
|
{
|
|
|
|
available,
|
|
|
|
preferred,
|
|
|
|
}: Readonly<{
|
|
|
|
available: ReadonlyArray<AudioDevice>;
|
|
|
|
preferred: undefined | AudioDevice;
|
|
|
|
}>,
|
|
|
|
isWindows: boolean
|
|
|
|
): undefined | number {
|
2021-09-29 18:30:42 +00:00
|
|
|
if (!preferred) {
|
|
|
|
return available.length > 0 ? 0 : undefined;
|
|
|
|
}
|
|
|
|
|
2024-10-07 20:32:31 +00:00
|
|
|
// On Linux and Mac, the default device is at index 0.
|
|
|
|
// On Windows, there are two default devices, as presented by RingRTC:
|
|
|
|
// * The default communications device (for voice calls, at index 0)
|
|
|
|
// * the default device (for, e.g., media, at index 1)
|
2021-09-29 18:30:42 +00:00
|
|
|
if (
|
2024-01-05 02:25:51 +00:00
|
|
|
preferred.index === 0 ||
|
2024-10-07 20:32:31 +00:00
|
|
|
(isWindows && preferred.index === 1 && available.length >= 2)
|
2021-09-29 18:30:42 +00:00
|
|
|
) {
|
|
|
|
return preferred.index;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (preferred.uniqueId) {
|
|
|
|
const idMatchIndex = available.findIndex(
|
|
|
|
d => d.uniqueId === preferred.uniqueId
|
|
|
|
);
|
|
|
|
if (idMatchIndex !== -1) {
|
|
|
|
return idMatchIndex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const nameMatchIndex = available.findIndex(d => d.name === preferred.name);
|
|
|
|
if (nameMatchIndex !== -1) {
|
|
|
|
return nameMatchIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
return available.length > 0 ? 0 : undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function findBestMatchingCameraId(
|
|
|
|
available: ReadonlyArray<MediaDeviceInfo>,
|
|
|
|
preferred?: string
|
|
|
|
): undefined | string {
|
|
|
|
const matchingId = available.filter(d => d.deviceId === preferred);
|
|
|
|
const nonInfrared = available.filter(d => !d.label.includes('IR Camera'));
|
|
|
|
|
|
|
|
// By default, pick the first non-IR camera (but allow the user to pick the
|
|
|
|
// infrared if they so desire)
|
|
|
|
if (matchingId.length > 0) {
|
|
|
|
return matchingId[0].deviceId;
|
|
|
|
}
|
|
|
|
if (nonInfrared.length > 0) {
|
|
|
|
return nonInfrared[0].deviceId;
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
}
|