Always publish microphone track when joining

This commit is contained in:
David Baker 2023-09-08 17:22:02 +01:00
parent c0443288c5
commit 2c1692bd4f
2 changed files with 59 additions and 4 deletions

View File

@ -14,7 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { ConnectionState, Room, RoomEvent } from "livekit-client"; import {
AudioCaptureOptions,
ConnectionState,
Room,
RoomEvent,
} from "livekit-client";
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
@ -42,7 +47,28 @@ function sfuConfigValid(sfuConfig?: SFUConfig): boolean {
return Boolean(sfuConfig?.url) && Boolean(sfuConfig?.jwt); return Boolean(sfuConfig?.url) && Boolean(sfuConfig?.jwt);
} }
async function doConnect(
livekitRoom: Room,
sfuConfig: SFUConfig,
audioEnabled: boolean,
audioOptions: AudioCaptureOptions
): Promise<void> {
await livekitRoom!.connect(sfuConfig!.url, sfuConfig!.jwt);
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;
}
if (!audioEnabled) await audioTracks[0].mute();
await livekitRoom?.localParticipant.publishTrack(audioTracks[0]);
}
export function useECConnectionState( export function useECConnectionState(
initialAudioOptions: AudioCaptureOptions,
initialAudioEnabled: boolean,
livekitRoom?: Room, livekitRoom?: Room,
sfuConfig?: SFUConfig sfuConfig?: SFUConfig
): ECConnectionState { ): ECConnectionState {
@ -89,12 +115,33 @@ export function useECConnectionState(
(async () => { (async () => {
setSwitchingFocus(true); setSwitchingFocus(true);
await livekitRoom?.disconnect(); await livekitRoom?.disconnect();
await livekitRoom?.connect(sfuConfig!.url, sfuConfig!.jwt); await doConnect(
livekitRoom!,
sfuConfig!,
initialAudioEnabled,
initialAudioOptions
);
})(); })();
} else if (
!sfuConfigValid(currentSFUConfig.current) &&
sfuConfigValid(sfuConfig)
) {
// if we're transitioning from an invalid config to a valid one (ie. connecting)
// then do an initial connection, including publishing the microphone track:
// livekit (by default) keeps the mic track open when you mute, but if you start muted,
// doesn't publish it until you unmute. We want to publish it from the start so we're
// always capturing audio: it helps keep bluetooth headsets in the right mode and
// mobile browsers to know we're doing a call.
doConnect(
livekitRoom!,
sfuConfig!,
initialAudioEnabled,
initialAudioOptions
);
} }
currentSFUConfig.current = Object.assign({}, sfuConfig); currentSFUConfig.current = Object.assign({}, sfuConfig);
}, [sfuConfig, livekitRoom]); }, [sfuConfig, livekitRoom, initialAudioOptions, initialAudioEnabled]);
return isSwitchingFocus ? ECAddonConnectionState.ECSwitchingFocus : connState; return isSwitchingFocus ? ECAddonConnectionState.ECSwitchingFocus : connState;
} }

View File

@ -108,9 +108,17 @@ export function useLiveKit(
audio: initialMuteStates.current.audio.enabled, audio: initialMuteStates.current.audio.enabled,
video: initialMuteStates.current.video.enabled, video: initialMuteStates.current.video.enabled,
room: roomWithoutProps, room: roomWithoutProps,
connect: false,
}); });
const connectionState = useECConnectionState(room, sfuConfig); const connectionState = useECConnectionState(
{
deviceId: initialDevices.current.audioOutput.selectedId,
},
initialMuteStates.current.audio.enabled,
room,
sfuConfig
);
useEffect(() => { useEffect(() => {
// Sync the requested mute states with LiveKit's mute states. We do it this // Sync the requested mute states with LiveKit's mute states. We do it this