Merge pull request #1135 from robintown/embedded-device-selection
Fix device selection never completing in widget mode
This commit is contained in:
commit
f08facbff3
3 changed files with 80 additions and 1 deletions
32
src/media-utils.ts
Normal file
32
src/media-utils.ts
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
Copyright 2022 New Vector Ltd
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
export async function findDeviceByName(
|
||||||
|
deviceName: string,
|
||||||
|
kind: MediaDeviceKind,
|
||||||
|
devices: MediaDeviceInfo[]
|
||||||
|
): Promise<string | undefined> {
|
||||||
|
const deviceInfo = devices.find(
|
||||||
|
(d) => d.kind === kind && d.label === deviceName
|
||||||
|
);
|
||||||
|
return deviceInfo?.deviceId;
|
||||||
|
}
|
|
@ -19,9 +19,11 @@ import { useHistory } from "react-router-dom";
|
||||||
import { GroupCall, GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
import { GroupCall, GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Room } from "livekit-client";
|
||||||
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import type { IWidgetApiRequest } from "matrix-widget-api";
|
import type { IWidgetApiRequest } from "matrix-widget-api";
|
||||||
import { widget, ElementWidgetActions } from "../widget";
|
import { widget, ElementWidgetActions, JoinCallData } from "../widget";
|
||||||
import { useGroupCall } from "./useGroupCall";
|
import { useGroupCall } from "./useGroupCall";
|
||||||
import { ErrorView, FullScreenView } from "../FullScreenView";
|
import { ErrorView, FullScreenView } from "../FullScreenView";
|
||||||
import { LobbyView } from "./LobbyView";
|
import { LobbyView } from "./LobbyView";
|
||||||
|
@ -32,6 +34,7 @@ import { useSentryGroupCallHandler } from "./useSentryGroupCallHandler";
|
||||||
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
|
||||||
import { useProfile } from "../profile/useProfile";
|
import { useProfile } from "../profile/useProfile";
|
||||||
import { UserChoices } from "../livekit/useLiveKit";
|
import { UserChoices } from "../livekit/useLiveKit";
|
||||||
|
import { findDeviceByName } from "../media-utils";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -90,6 +93,45 @@ export function GroupCallView({
|
||||||
if (widget && preload) {
|
if (widget && preload) {
|
||||||
// In preload mode, wait for a join action before entering
|
// In preload mode, wait for a join action before entering
|
||||||
const onJoin = async (ev: CustomEvent<IWidgetApiRequest>) => {
|
const onJoin = async (ev: CustomEvent<IWidgetApiRequest>) => {
|
||||||
|
const devices = await Room.getLocalDevices();
|
||||||
|
|
||||||
|
const { audioInput, videoInput } = ev.detail
|
||||||
|
.data as unknown as JoinCallData;
|
||||||
|
const newChoices = {} as UserChoices;
|
||||||
|
|
||||||
|
if (audioInput !== null) {
|
||||||
|
const deviceId = await findDeviceByName(
|
||||||
|
audioInput,
|
||||||
|
"audioinput",
|
||||||
|
devices
|
||||||
|
);
|
||||||
|
if (!deviceId) {
|
||||||
|
logger.warn("Unknown audio input: " + audioInput);
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
`Found audio input ID ${deviceId} for name ${audioInput}`
|
||||||
|
);
|
||||||
|
newChoices.audio = { selectedId: deviceId, enabled: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (videoInput !== null) {
|
||||||
|
const deviceId = await findDeviceByName(
|
||||||
|
videoInput,
|
||||||
|
"videoinput",
|
||||||
|
devices
|
||||||
|
);
|
||||||
|
if (!deviceId) {
|
||||||
|
logger.warn("Unknown video input: " + videoInput);
|
||||||
|
} else {
|
||||||
|
logger.debug(
|
||||||
|
`Found video input ID ${deviceId} for name ${videoInput}`
|
||||||
|
);
|
||||||
|
newChoices.video = { selectedId: deviceId, enabled: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setUserChoices(newChoices);
|
||||||
await enter();
|
await enter();
|
||||||
|
|
||||||
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
PosthogAnalytics.instance.eventCallEnded.cacheStartCall(new Date());
|
||||||
|
|
|
@ -47,6 +47,11 @@ export enum ElementWidgetActions {
|
||||||
ScreenshareStop = "io.element.screenshare_stop",
|
ScreenshareStop = "io.element.screenshare_stop",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface JoinCallData {
|
||||||
|
audioInput: string | null;
|
||||||
|
videoInput: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ScreenshareStartData {
|
export interface ScreenshareStartData {
|
||||||
desktopCapturerSourceId: string;
|
desktopCapturerSourceId: string;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue