Switch audio/video devices while in call
Enable the menus to switch audio/video devices.
Add connectionstatechange webRTCConnection listener to set the connected
status.
GitLab: #146
Change-Id: Ic3afbdee2b1a6bf312d3d7d902adb3c103a7d26f
diff --git a/client/src/components/CallButtons.tsx b/client/src/components/CallButtons.tsx
index 6f53b73..2ecc4fc 100644
--- a/client/src/components/CallButtons.tsx
+++ b/client/src/components/CallButtons.tsx
@@ -18,11 +18,10 @@
import { IconButton, IconButtonProps, PaletteColor } from '@mui/material';
import { styled, Theme } from '@mui/material/styles';
-import { useContext, useMemo } from 'react';
+import { ChangeEvent, useContext, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { CallContext, CallStatus } from '../contexts/CallProvider';
-import { WebRtcContext } from '../contexts/WebRtcProvider';
import {
ExpandableButton,
ExpandableButtonProps,
@@ -178,7 +177,7 @@
};
const useMediaDeviceExpandMenuOptions = (kind: MediaDeviceKind): ExpandMenuRadioOption[] | undefined => {
- const { mediaDevices } = useContext(WebRtcContext);
+ const { currentMediaDeviceIds, mediaDevices } = useContext(CallContext);
const options = useMemo(
() =>
@@ -189,13 +188,38 @@
[mediaDevices, kind]
);
- return options.length > 0 ? [{ options }] : undefined;
+ const currentDevice = currentMediaDeviceIds[kind];
+
+ if (options.length === 0) {
+ return undefined;
+ }
+ return [
+ {
+ options,
+ value: currentDevice.id ?? '',
+ onChange: (e: ChangeEvent<HTMLInputElement>) => {
+ currentDevice.setId(e.target.value);
+ },
+ },
+ ];
};
export const CallingVolumeButton = (props: ExpandableButtonProps) => {
const options = useMediaDeviceExpandMenuOptions('audiooutput');
+ const { remoteVideoRef } = useContext(CallContext);
- return <CallButton aria-label="volume options" Icon={VolumeIcon} expandMenuOptions={options} {...props} />;
+ // Audio out options are only available on chrome and other browsers that support `setSinkId`
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/setSinkId#browser_compatibility
+ const hasSetSinkId = remoteVideoRef.current?.setSinkId != null;
+
+ return (
+ <CallButton
+ aria-label="volume options"
+ Icon={VolumeIcon}
+ expandMenuOptions={hasSetSinkId ? options : undefined}
+ {...props}
+ />
+ );
};
export const CallingMicButton = (props: ExpandableButtonProps) => {