Skip to content

Commit

Permalink
fix: revert #1604 (#1607)
Browse files Browse the repository at this point in the history
This reverts #1604 after reports about not being able to enable
camera/mic.

Also fixes OvercontraintError not being a class on Firefox.
  • Loading branch information
myandrienko authored Nov 29, 2024
1 parent 646ae9f commit 567e4fb
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 76 deletions.
1 change: 0 additions & 1 deletion packages/client/src/devices/InputMediaDeviceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ export abstract class InputMediaDeviceManager<
await this.applySettingsToStream();
} catch (error) {
this.state.setDevice(prevDeviceId);
await this.applySettingsToStream();
throw error;
}
}
Expand Down
46 changes: 30 additions & 16 deletions packages/client/src/devices/devices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export const getAudioStream = async (
const constraints: MediaStreamConstraints = {
audio: {
...audioDeviceConstraints.audio,
...normalizeContraints(trackConstraints),
...trackConstraints,
},
};

Expand All @@ -195,6 +195,20 @@ export const getAudioStream = async (
});
return await getStream(constraints);
} catch (error) {
if (
error instanceof DOMException &&
error.name === 'OverconstrainedError' &&
trackConstraints?.deviceId
) {
const { deviceId, ...relaxedContraints } = trackConstraints;
getLogger(['devices'])(
'warn',
'Failed to get audio stream, will try again with relaxed contraints',
{ error, constraints, relaxedContraints },
);
return getAudioStream(relaxedContraints);
}

getLogger(['devices'])('error', 'Failed to get audio stream', {
error,
constraints,
Expand All @@ -217,7 +231,7 @@ export const getVideoStream = async (
const constraints: MediaStreamConstraints = {
video: {
...videoDeviceConstraints.video,
...normalizeContraints(trackConstraints),
...trackConstraints,
},
};
try {
Expand All @@ -227,6 +241,20 @@ export const getVideoStream = async (
});
return await getStream(constraints);
} catch (error) {
if (
error instanceof DOMException &&
error.name === 'OverconstrainedError' &&
trackConstraints?.deviceId
) {
const { deviceId, ...relaxedContraints } = trackConstraints;
getLogger(['devices'])(
'warn',
'Failed to get video stream, will try again with relaxed contraints',
{ error, constraints, relaxedContraints },
);
return getVideoStream(relaxedContraints);
}

getLogger(['devices'])('error', 'Failed to get video stream', {
error,
constraints,
Expand All @@ -235,20 +263,6 @@ export const getVideoStream = async (
}
};

function normalizeContraints(constraints: MediaTrackConstraints | undefined) {
if (
constraints?.deviceId === 'default' ||
(typeof constraints?.deviceId === 'object' &&
'exact' in constraints.deviceId &&
constraints.deviceId.exact === 'default')
) {
const { deviceId, ...contraintsWithoutDeviceId } = constraints;
return contraintsWithoutDeviceId;
}

return constraints;
}

/**
* Prompts the user for a permission to share a screen.
* If the user grants the permission, a screen sharing stream is returned. Throws otherwise.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
import { useCallStateHooks } from '@stream-io/video-react-bindings';
import { DeviceSelector } from './DeviceSelector';
import {
createCallControlHandler,
PropsWithErrorHandler,
} from '../../utilities/callControlHandler';

export type DeviceSelectorAudioInputProps = PropsWithErrorHandler<{
export type DeviceSelectorAudioInputProps = {
title?: string;
visualType?: 'list' | 'dropdown';
}>;
};

export const DeviceSelectorAudioInput = (
props: DeviceSelectorAudioInputProps,
) => {
export const DeviceSelectorAudioInput = ({
title,
visualType,
}: DeviceSelectorAudioInputProps) => {
const { useMicrophoneState } = useCallStateHooks();
const { microphone, selectedDevice, devices } = useMicrophoneState();
const handleChange = createCallControlHandler(
props,
async (deviceId: string) => {
await microphone.select(deviceId);
},
);

return (
<DeviceSelector
devices={devices || []}
selectedDeviceId={selectedDevice}
type="audioinput"
onChange={handleChange}
title={props.title}
visualType={props.visualType}
onChange={async (deviceId) => {
await microphone.select(deviceId);
}}
title={title}
visualType={visualType}
icon="mic"
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,28 @@
import {
createCallControlHandler,
PropsWithErrorHandler,
} from '../../utilities/callControlHandler';
import { DeviceSelector } from './DeviceSelector';
import { useCallStateHooks } from '@stream-io/video-react-bindings';

export type DeviceSelectorVideoProps = PropsWithErrorHandler<{
export type DeviceSelectorVideoProps = {
title?: string;
visualType?: 'list' | 'dropdown';
}>;
};

export const DeviceSelectorVideo = (props: DeviceSelectorVideoProps) => {
export const DeviceSelectorVideo = ({
title,
visualType,
}: DeviceSelectorVideoProps) => {
const { useCameraState } = useCallStateHooks();
const { camera, devices, selectedDevice } = useCameraState();
const handleChange = createCallControlHandler(
props,
async (deviceId: string) => {
await camera.select(deviceId);
},
);

return (
<DeviceSelector
devices={devices || []}
type="videoinput"
selectedDeviceId={selectedDevice}
onChange={handleChange}
title={props.title}
visualType={props.visualType}
onChange={async (deviceId) => {
await camera.select(deviceId);
}}
title={title}
visualType={visualType}
icon="camera"
/>
);
Expand Down
27 changes: 6 additions & 21 deletions packages/react-sdk/src/hooks/usePersistedDevicePreferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,8 @@ const usePersistDevicePreferences = (
*
* @param key the key to use for local storage.
*/
const useApplyDevicePreferences = (
key: string,
onWillApply: () => void,
onApplied: () => void,
) => {
const useApplyDevicePreferences = (key: string, onApplied: () => void) => {
const call = useCall();
const onWillApplyRef = useRef(onWillApply);
onWillApplyRef.current = onWillApply;
const onAppliedRef = useRef(onApplied);
onAppliedRef.current = onApplied;
useEffect(() => {
Expand Down Expand Up @@ -121,22 +115,17 @@ const useApplyDevicePreferences = (
console.warn('Failed to load device preferences', err);
}
if (preferences) {
await initMic(preferences.mic).catch((err) => {
console.warn('Failed to apply microphone preferences', err);
});
await initCamera(preferences.camera).catch((err) => {
console.warn('Failed to apply camera preferences', err);
});
await initMic(preferences.mic);
await initCamera(preferences.camera);
initSpeaker(preferences.speaker);
}
};

onWillApplyRef.current();
apply()
.then(() => onAppliedRef.current())
.catch((err) => {
console.warn('Failed to apply device preferences', err);
})
.then(() => onAppliedRef.current());
});

return () => {
cancel = true;
Expand All @@ -153,11 +142,7 @@ export const usePersistedDevicePreferences = (
key: string = '@stream-io/device-preferences',
) => {
const shouldPersistRef = useRef(false);
useApplyDevicePreferences(
key,
() => (shouldPersistRef.current = false),
() => (shouldPersistRef.current = true),
);
useApplyDevicePreferences(key, () => (shouldPersistRef.current = true));
usePersistDevicePreferences(key, shouldPersistRef);
};

Expand Down
8 changes: 4 additions & 4 deletions packages/react-sdk/src/utilities/callControlHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ export type PropsWithErrorHandler<T = unknown> = T & {
* @param props component props, including the onError callback
* @param handler event handler to wrap
*/
export const createCallControlHandler = <P extends unknown[]>(
export const createCallControlHandler = (
props: PropsWithErrorHandler,
handler: (...args: P) => Promise<void>,
handler: () => Promise<void>,
): (() => Promise<void>) => {
const logger = getLogger(['react-sdk']);

return async (...args: P) => {
return async () => {
try {
await handler(...args);
await handler();
} catch (error) {
if (props.onError) {
props.onError(error);
Expand Down

0 comments on commit 567e4fb

Please sign in to comment.