Firefox audio output issues fix (#1510)
--------- Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
@@ -28,6 +28,7 @@ import { createMediaDeviceObserver } from "@livekit/components-core";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import {
|
||||
isFirefox,
|
||||
useAudioInput,
|
||||
useAudioOutput,
|
||||
useVideoInput,
|
||||
@@ -65,7 +66,8 @@ function useObservableState<T>(
|
||||
function useMediaDevice(
|
||||
kind: MediaDeviceKind,
|
||||
fallbackDevice: string | undefined,
|
||||
usingNames: boolean
|
||||
usingNames: boolean,
|
||||
alwaysDefault: boolean = false
|
||||
): MediaDevice {
|
||||
// Make sure we don't needlessly reset to a device observer without names,
|
||||
// once permissions are already given
|
||||
@@ -86,18 +88,19 @@ function useMediaDevice(
|
||||
const available = useObservableState(deviceObserver, []);
|
||||
const [selectedId, select] = useState(fallbackDevice);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
return useMemo(() => {
|
||||
const devId = available.some((d) => d.deviceId === selectedId)
|
||||
? selectedId
|
||||
: available.some((d) => d.deviceId === fallbackDevice)
|
||||
? fallbackDevice
|
||||
: available.at(0)?.deviceId;
|
||||
|
||||
return {
|
||||
available,
|
||||
selectedId: available.some((d) => d.deviceId === selectedId)
|
||||
? selectedId
|
||||
: available.some((d) => d.deviceId === fallbackDevice)
|
||||
? fallbackDevice
|
||||
: available.at(0)?.deviceId,
|
||||
selectedId: alwaysDefault ? undefined : devId,
|
||||
select,
|
||||
}),
|
||||
[available, selectedId, fallbackDevice, select]
|
||||
);
|
||||
};
|
||||
}, [available, selectedId, fallbackDevice, select, alwaysDefault]);
|
||||
}
|
||||
|
||||
const deviceStub: MediaDevice = {
|
||||
@@ -120,10 +123,17 @@ interface Props {
|
||||
}
|
||||
|
||||
export const MediaDevicesProvider: FC<Props> = ({ children }) => {
|
||||
// Counts the number of callers currently using device names
|
||||
// Counts the number of callers currently using device names.
|
||||
const [numCallersUsingNames, setNumCallersUsingNames] = useState(0);
|
||||
const usingNames = numCallersUsingNames > 0;
|
||||
|
||||
// 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();
|
||||
const [videoInputSetting, setVideoInputSetting] = useVideoInput();
|
||||
@@ -136,7 +146,8 @@ export const MediaDevicesProvider: FC<Props> = ({ children }) => {
|
||||
const audioOutput = useMediaDevice(
|
||||
"audiooutput",
|
||||
audioOutputSetting,
|
||||
usingNames
|
||||
useOutputNames,
|
||||
alwaysUseDefaultAudio
|
||||
);
|
||||
const videoInput = useMediaDevice(
|
||||
"videoinput",
|
||||
@@ -150,7 +161,9 @@ export const MediaDevicesProvider: FC<Props> = ({ children }) => {
|
||||
}, [setAudioInputSetting, audioInput.selectedId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (audioOutput.selectedId !== undefined)
|
||||
// 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]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user