From 4a5b69800ccb6de3ac0a5b4a6244ab781274445a Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 27 Sep 2022 16:19:48 +0100 Subject: [PATCH] Use device labels rather than IDs in widget API device IDs are different for each origin, so won't match up when passed in & out of widgets. Use the label instead. For https://github.com/vector-im/element-web/issues/23331 --- src/media-utils.ts | 23 +++++++++++++++++++++++ src/room/GroupCallView.tsx | 28 ++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/media-utils.ts diff --git a/src/media-utils.ts b/src/media-utils.ts new file mode 100644 index 0000000..0c01b5d --- /dev/null +++ b/src/media-utils.ts @@ -0,0 +1,23 @@ +/* +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. +*/ + +export async function findDeviceByName( + deviceName: string +): Promise { + const devices = await navigator.mediaDevices.enumerateDevices(); + const deviceInfo = devices.find((d) => d.label === deviceName); + return deviceInfo?.deviceId; +} diff --git a/src/room/GroupCallView.tsx b/src/room/GroupCallView.tsx index 0ee6cfb..0598e4d 100644 --- a/src/room/GroupCallView.tsx +++ b/src/room/GroupCallView.tsx @@ -18,6 +18,7 @@ import React, { useCallback, useEffect, useState } from "react"; import { useHistory } from "react-router-dom"; import { GroupCall, GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall"; import { MatrixClient } from "matrix-js-sdk/src/client"; +import { logger } from "matrix-js-sdk/src/logger"; import type { IWidgetApiRequest } from "matrix-widget-api"; import { widget, ElementWidgetActions, JoinCallData } from "../widget"; @@ -31,6 +32,7 @@ import { useRoomAvatar } from "./useRoomAvatar"; import { useSentryGroupCallHandler } from "./useSentryGroupCallHandler"; import { useLocationNavigation } from "../useLocationNavigation"; import { useMediaHandler } from "../settings/useMediaHandler"; +import { findDeviceByName } from "../media-utils"; declare global { interface Window { @@ -96,8 +98,30 @@ export function GroupCallView({ const onJoin = async (ev: CustomEvent) => { const { audioInput, videoInput } = ev.detail .data as unknown as JoinCallData; - if (audioInput !== null) setAudioInput(audioInput); - if (videoInput !== null) setVideoInput(videoInput); + + if (audioInput !== null) { + const deviceId = await findDeviceByName(audioInput); + if (!deviceId) { + logger.warn("Unknown audio input: " + audioInput); + } else { + logger.debug( + `Found audio input ID ${deviceId} for name ${audioInput}` + ); + setAudioInput(deviceId); + } + } + + if (videoInput !== null) { + const deviceId = await findDeviceByName(videoInput); + if (!deviceId) { + logger.warn("Unknown video input: " + videoInput); + } else { + logger.debug( + `Found video input ID ${deviceId} for name ${videoInput}` + ); + setVideoInput(deviceId); + } + } await Promise.all([ groupCall.setMicrophoneMuted(audioInput === null), groupCall.setLocalVideoMuted(videoInput === null),