From 861d8ec016fc09a07b9b5e3c13a456eb0774581b Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 20 Nov 2023 18:49:08 +0000 Subject: [PATCH] Fix joining calls with no media permission You can still try to unmute your media in the preview screen and the button will show unmuted, but then mute again once you actually join, so not 100% perfect but better. Fixes https://github.com/vector-im/element-call/issues/1907 Fixes https://github.com/vector-im/element-call/issues/1661 --- src/livekit/useECConnectionState.ts | 34 +++++++++++++++-------------- src/livekit/useLiveKit.ts | 24 +++++++++++++++----- src/room/VideoPreview.tsx | 2 ++ 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/livekit/useECConnectionState.ts b/src/livekit/useECConnectionState.ts index 0bc6b1146..64e8ca0d2 100644 --- a/src/livekit/useECConnectionState.ts +++ b/src/livekit/useECConnectionState.ts @@ -72,35 +72,37 @@ async function doConnect( } logger.info("Pre-creating microphone track"); - const audioTracks = await livekitRoom!.localParticipant.createTracks({ - audio: audioOptions, - }); - if (audioTracks.length < 1) { - logger.info("Tried to pre-create local audio track but got no tracks"); - return; + let preCreatedAudioTrack: LocalTrack | undefined; + try { + const audioTracks = await livekitRoom!.localParticipant.createTracks({ + audio: audioOptions, + }); + if (audioTracks.length < 1) { + logger.info("Tried to pre-create local audio track but got no tracks"); + } else { + preCreatedAudioTrack = audioTracks[0]; + } + logger.info("Pre-created microphone track"); + } catch (e) { + logger.error("Failed to pre-create microphone track", e); } - if (!audioEnabled) await audioTracks[0].mute(); - logger.info("Pre-created microphone track"); + if (!audioEnabled) await preCreatedAudioTrack?.mute(); // check again having awaited for the track to create if (livekitRoom!.localParticipant.getTrack(Track.Source.Microphone)) { logger.warn( - "Publishing pre-created audio track but participant already appears to have an microphone track: this shouldn't happen!", + "Pre-created audio track but participant already appears to have an microphone track: this shouldn't happen!", ); - for (const t of audioTracks) { - t.stop(); - } + preCreatedAudioTrack?.stop(); return; } logger.info("Connecting & publishing"); try { - await connectAndPublish(livekitRoom, sfuConfig, audioTracks[0], []); + await connectAndPublish(livekitRoom, sfuConfig, preCreatedAudioTrack, []); } catch (e) { - for (const t of audioTracks) { - t.stop(); - } + preCreatedAudioTrack?.stop(); } } diff --git a/src/livekit/useLiveKit.ts b/src/livekit/useLiveKit.ts index 50921b93d..b584649b8 100644 --- a/src/livekit/useLiveKit.ts +++ b/src/livekit/useLiveKit.ts @@ -245,11 +245,25 @@ export function useLiveKit( ); } } catch (e) { - logger.error( - "Failed to sync audio mute state with LiveKit (will retry to sync in 1s):", - e, - ); - setTimeout(() => syncMuteState(iterCount + 1, type), 1000); + if ((e as DOMException).name === "NotAllowedError") { + logger.error( + "Fatal errror while syncing mute state: resetting", + e, + ); + if (type === MuteDevice.Microphone) { + audioMuteUpdating.current = false; + muteStates.audio.setEnabled?.(false); + } else { + videoMuteUpdating.current = false; + muteStates.video.setEnabled?.(false); + } + } else { + logger.error( + "Failed to sync audio mute state with LiveKit (will retry to sync in 1s):", + e, + ); + setTimeout(() => syncMuteState(iterCount + 1, type), 1000); + } } } }; diff --git a/src/room/VideoPreview.tsx b/src/room/VideoPreview.tsx index d218ca7d3..fd2cde170 100644 --- a/src/room/VideoPreview.tsx +++ b/src/room/VideoPreview.tsx @@ -82,6 +82,8 @@ export const VideoPreview: FC = ({ }, (error) => { logger.error("Error while creating preview Tracks:", error); + muteStates.audio.setEnabled?.(false); + muteStates.video.setEnabled?.(false); }, ); const videoTrack = useMemo(