From 02bf5f89e02b083d42b088fd7a4254d7dfda5024 Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 19 Sep 2023 12:40:53 +0200 Subject: [PATCH] only on FF + code cleanup Signed-off-by: Timo K --- src/livekit/MediaDevicesContext.tsx | 24 +++++++++++++++++------- src/settings/useSetting.ts | 4 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/livekit/MediaDevicesContext.tsx b/src/livekit/MediaDevicesContext.tsx index 6e376a34..ea50f4d9 100644 --- a/src/livekit/MediaDevicesContext.tsx +++ b/src/livekit/MediaDevicesContext.tsx @@ -26,6 +26,7 @@ import { } from "react"; import { createMediaDeviceObserver } from "@livekit/components-core"; import { Observable } from "rxjs"; +import { isFireFox } from "livekit-client/dist/src/room/utils"; import { useAudioInput, @@ -124,7 +125,14 @@ interface Props { export const MediaDevicesProvider: FC = ({ children }) => { // Counts the number of callers currently using device names const [numCallersUsingNames, setNumCallersUsingNames] = useState(0); - const usingNames = numCallersUsingNames > 0; + const usingNames = numCallersUsingNames > 0 && !isFireFox(); + + // Use output device names for output devices on all platforms except FF. + const useOutputNames = usingNames && !isFireFox(); + + // Setting the audio device to sth. else than 'undefined' breaks echo-cancellation + // and even can introduce multiple different output devices for one call. + const alwaysUseDefaultAudio = isFireFox(); const [audioInputSetting, setAudioInputSetting] = useAudioInput(); const [audioOutputSetting, setAudioOutputSetting] = useAudioOutput(); @@ -138,8 +146,8 @@ export const MediaDevicesProvider: FC = ({ children }) => { const audioOutput = useMediaDevice( "audiooutput", audioOutputSetting, - false, - true + useOutputNames, + alwaysUseDefaultAudio ); const videoInput = useMediaDevice( "videoinput", @@ -152,10 +160,12 @@ export const MediaDevicesProvider: FC = ({ children }) => { setAudioInputSetting(audioInput.selectedId); }, [setAudioInputSetting, audioInput.selectedId]); - // useEffect(() => { - // if (audioOutput.selectedId !== undefined) - // setAudioOutputSetting(audioOutput.selectedId); - // }, [setAudioOutputSetting, audioOutput.selectedId]); + useEffect(() => { + // Skip setting state for ff output. Redundent since it is set to always return 'undefined' + // But makes it clear while debugging that this is not happening on FF. + perf ;) + if (audioOutput.selectedId !== undefined && !isFireFox()) + setAudioOutputSetting(audioOutput.selectedId); + }, [setAudioOutputSetting, audioOutput.selectedId]); useEffect(() => { if (videoInput.selectedId !== undefined) diff --git a/src/settings/useSetting.ts b/src/settings/useSetting.ts index 53253116..d3407c6c 100644 --- a/src/settings/useSetting.ts +++ b/src/settings/useSetting.ts @@ -16,6 +16,7 @@ limitations under the License. import { useCallback, useMemo } from "react"; import { isE2EESupported } from "livekit-client"; +import { isFireFox } from "livekit-client/dist/src/room/utils"; import { PosthogAnalytics } from "../analytics/PosthogAnalytics"; import { @@ -59,7 +60,6 @@ export const setSetting = (name: string, newValue: T) => setLocalStorageItem(getSettingKey(name), JSON.stringify(newValue)); const canEnableSpatialAudio = () => { - const { userAgent } = navigator; // Spatial audio means routing audio through audio contexts. On Chrome, // this bypasses the AEC processor and so breaks echo cancellation. // We only allow spatial audio to be enabled on Firefox which we know @@ -69,7 +69,7 @@ const canEnableSpatialAudio = () => { // widely enough, we can allow spatial audio everywhere. It's currently in a // chrome flag, so we could enable this in Electron if we enabled the chrome flag // in the Electron wrapper. - return userAgent.includes("Firefox"); + return isFireFox(); }; export const useSpatialAudio = (): DisableableSetting => {