mirror of
https://github.com/vector-im/element-call.git
synced 2026-02-02 04:05:56 +00:00
Merge branch 'livekit' into robin/behaviors
This commit is contained in:
@@ -323,16 +323,18 @@ export function useLivekit(
|
||||
|
||||
useEffect(() => {
|
||||
// Sync the requested devices with LiveKit's devices
|
||||
if (
|
||||
room !== undefined &&
|
||||
connectionState === ConnectionState.Connected &&
|
||||
!controlledAudioDevices
|
||||
) {
|
||||
if (room !== undefined && connectionState === ConnectionState.Connected) {
|
||||
const syncDevice = (
|
||||
kind: MediaDeviceKind,
|
||||
selected$: Observable<SelectedDevice | undefined>,
|
||||
): Subscription =>
|
||||
selected$.subscribe((device) => {
|
||||
logger.info(
|
||||
"[LivekitRoom] syncDevice room.getActiveDevice(kind) !== d.id :",
|
||||
room.getActiveDevice(kind),
|
||||
" !== ",
|
||||
device?.id,
|
||||
);
|
||||
if (
|
||||
device !== undefined &&
|
||||
room.getActiveDevice(kind) !== device.id
|
||||
@@ -347,7 +349,9 @@ export function useLivekit(
|
||||
|
||||
const subscriptions = [
|
||||
syncDevice("audioinput", devices.audioInput.selected$),
|
||||
syncDevice("audiooutput", devices.audioOutput.selected$),
|
||||
!controlledAudioDevices
|
||||
? syncDevice("audiooutput", devices.audioOutput.selected$)
|
||||
: undefined,
|
||||
syncDevice("videoinput", devices.videoInput.selected$),
|
||||
// Restart the audio input track whenever we detect that the active media
|
||||
// device has changed to refer to a different hardware device. We do this
|
||||
@@ -387,7 +391,7 @@ export function useLivekit(
|
||||
];
|
||||
|
||||
return (): void => {
|
||||
for (const s of subscriptions) s.unsubscribe();
|
||||
for (const s of subscriptions) s?.unsubscribe();
|
||||
};
|
||||
}
|
||||
}, [room, devices, connectionState, controlledAudioDevices]);
|
||||
|
||||
@@ -86,6 +86,14 @@ export function useMuteStates(isJoined: boolean): MuteStates {
|
||||
const audio = useMuteState(devices.audioInput, () => {
|
||||
return Config.get().media_devices.enable_audio && !skipLobby && !isJoined;
|
||||
});
|
||||
useEffect(() => {
|
||||
// If audio is enabled, we need to request the device names again,
|
||||
// because iOS will not be able to switch to the correct device after un-muting.
|
||||
// This is one of the main changes that makes iOS work with bluetooth audio devices.
|
||||
if (audio.enabled) {
|
||||
devices.requestDeviceNames();
|
||||
}
|
||||
}, [audio.enabled, devices]);
|
||||
const isEarpiece = useIsEarpiece();
|
||||
const video = useMuteState(
|
||||
devices.videoInput,
|
||||
|
||||
@@ -1326,7 +1326,7 @@ export class CallViewModel extends ViewModel {
|
||||
(available, selected) => {
|
||||
const selectionType = selected && available.get(selected.id)?.type;
|
||||
|
||||
// If we are in any output mode other than spaeker switch to speaker.
|
||||
// If we are in any output mode other than speaker switch to speaker.
|
||||
const newSelectionType: "earpiece" | "speaker" =
|
||||
selectionType === "speaker" ? "earpiece" : "speaker";
|
||||
const newSelection = [...available].find(
|
||||
|
||||
@@ -258,6 +258,15 @@ class AudioOutput
|
||||
class ControlledAudioOutput
|
||||
implements MediaDevice<AudioOutputDeviceLabel, SelectedAudioOutputDevice>
|
||||
{
|
||||
// We need to subscribe to the raw devices so that the OS does update the input
|
||||
// back to what it was before. otherwise we will switch back to the default
|
||||
// whenever we allocate a new stream.
|
||||
public readonly availableRaw$ = availableRawDevices$(
|
||||
"audiooutput",
|
||||
this.usingNames$,
|
||||
this.scope,
|
||||
);
|
||||
|
||||
public readonly available$ = this.scope.behavior(
|
||||
combineLatest(
|
||||
[controlledAvailableOutputDevices$.pipe(startWith([])), iosDeviceMenu$],
|
||||
@@ -309,14 +318,17 @@ class ControlledAudioOutput
|
||||
),
|
||||
);
|
||||
|
||||
public constructor(private readonly scope: ObservableScope) {
|
||||
public constructor(
|
||||
private readonly usingNames$: Behavior<boolean>,
|
||||
private readonly scope: ObservableScope,
|
||||
) {
|
||||
this.selected$.subscribe((device) => {
|
||||
// Let the hosting application know which output device has been selected.
|
||||
// This information is probably only of interest if the earpiece mode has
|
||||
// been selected - for example, Element X iOS listens to this to determine
|
||||
// whether it should enable the proximity sensor.
|
||||
if (device !== undefined) {
|
||||
logger.info("[controlled-output] setAudioDeviceSelect called:", device);
|
||||
logger.info("[controlled-output] onAudioDeviceSelect called:", device);
|
||||
window.controls.onAudioDeviceSelect?.(device.id);
|
||||
// Also invoke the deprecated callback for backward compatibility
|
||||
window.controls.onOutputDeviceSelect?.(device.id);
|
||||
@@ -325,6 +337,9 @@ class ControlledAudioOutput
|
||||
this.available$.subscribe((available) => {
|
||||
logger.info("[controlled-output] available devices:", available);
|
||||
});
|
||||
this.availableRaw$.subscribe((availableRaw) => {
|
||||
logger.info("[controlled-output] available raw devices:", availableRaw);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +400,7 @@ export class MediaDevices {
|
||||
AudioOutputDeviceLabel,
|
||||
SelectedAudioOutputDevice
|
||||
> = getUrlParams().controlledAudioDevices
|
||||
? new ControlledAudioOutput(this.scope)
|
||||
? new ControlledAudioOutput(this.usingNames$, this.scope)
|
||||
: new AudioOutput(this.usingNames$, this.scope);
|
||||
|
||||
public readonly videoInput: MediaDevice<DeviceLabel, SelectedDevice> =
|
||||
|
||||
Reference in New Issue
Block a user