mirror of
https://github.com/vector-im/element-call.git
synced 2026-01-30 03:15:55 +00:00
Disable device switching when in controlled audio devices mode (#3290)
* Disable device switching when in controlled audio devices mode * Temporarily switch matrix-js-sdk to robin/embedded-no-update-state To allow us to test this change on Element X, which does not yet support the update_state action. * Also add a check for controlled audio devices in useAudioContext * use develop branch * fix tests --------- Co-authored-by: Robin <robin@robin.town>
This commit is contained in:
@@ -42,6 +42,7 @@ import {
|
||||
} from "./TrackProcessorContext";
|
||||
import { useInitial } from "../useInitial";
|
||||
import { observeTrackReference$ } from "../state/MediaViewModel";
|
||||
import { useUrlParams } from "../UrlParams";
|
||||
|
||||
interface UseLivekitResult {
|
||||
livekitRoom?: Room;
|
||||
@@ -54,6 +55,8 @@ export function useLivekit(
|
||||
sfuConfig: SFUConfig | undefined,
|
||||
e2eeSystem: EncryptionSystem,
|
||||
): UseLivekitResult {
|
||||
const { controlledAudioDevices } = useUrlParams();
|
||||
|
||||
const e2eeOptions = useMemo((): E2EEManagerOptions | undefined => {
|
||||
if (e2eeSystem.kind === E2eeType.NONE) return undefined;
|
||||
|
||||
@@ -303,7 +306,11 @@ export function useLivekit(
|
||||
|
||||
useEffect(() => {
|
||||
// Sync the requested devices with LiveKit's devices
|
||||
if (room !== undefined && connectionState === ConnectionState.Connected) {
|
||||
if (
|
||||
room !== undefined &&
|
||||
connectionState === ConnectionState.Connected &&
|
||||
!controlledAudioDevices
|
||||
) {
|
||||
const syncDevice = (
|
||||
kind: MediaDeviceKind,
|
||||
device: MediaDeviceHandle,
|
||||
@@ -363,7 +370,7 @@ export function useLivekit(
|
||||
syncDevice("audiooutput", devices.audioOutput);
|
||||
syncDevice("videoinput", devices.videoInput);
|
||||
}
|
||||
}, [room, devices, connectionState]);
|
||||
}, [room, devices, connectionState, controlledAudioDevices]);
|
||||
|
||||
return {
|
||||
connState: connectionState,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { expect, vi, afterEach, beforeEach, test } from "vitest";
|
||||
import { type FC } from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import userEvent, { type UserEvent } from "@testing-library/user-event";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
|
||||
import { deviceStub, MediaDevicesContext } from "./livekit/MediaDevicesContext";
|
||||
import { useAudioContext } from "./useAudioContext";
|
||||
@@ -38,6 +39,13 @@ const TestComponent: FC = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
const TestComponentWrapper: FC = () => {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<TestComponent />
|
||||
</BrowserRouter>
|
||||
);
|
||||
};
|
||||
|
||||
const gainNode = vi.mocked(
|
||||
{
|
||||
@@ -94,13 +102,13 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
test("can play a single sound", async () => {
|
||||
const { findByText } = render(<TestComponent />);
|
||||
const { findByText } = render(<TestComponentWrapper />);
|
||||
await user.click(await findByText("Valid sound"));
|
||||
expect(testAudioContext.createBufferSource).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
test("will ignore sounds that are not registered", async () => {
|
||||
const { findByText } = render(<TestComponent />);
|
||||
const { findByText } = render(<TestComponentWrapper />);
|
||||
await user.click(await findByText("Invalid sound"));
|
||||
expect(testAudioContext.createBufferSource).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -122,7 +130,7 @@ test("will use the correct device", () => {
|
||||
stopUsingDeviceNames: () => {},
|
||||
}}
|
||||
>
|
||||
<TestComponent />
|
||||
<TestComponentWrapper />
|
||||
</MediaDevicesContext.Provider>,
|
||||
);
|
||||
expect(testAudioContext.createBufferSource).not.toHaveBeenCalled();
|
||||
@@ -131,7 +139,7 @@ test("will use the correct device", () => {
|
||||
|
||||
test("will use the correct volume level", async () => {
|
||||
soundEffectVolumeSetting.setValue(0.33);
|
||||
const { findByText } = render(<TestComponent />);
|
||||
const { findByText } = render(<TestComponentWrapper />);
|
||||
await user.click(await findByText("Valid sound"));
|
||||
expect(testAudioContext.gain.gain.setValueAtTime).toHaveBeenCalledWith(
|
||||
0.33,
|
||||
@@ -157,7 +165,7 @@ test("will use the pan if earpiece is selected", async () => {
|
||||
stopUsingDeviceNames: () => {},
|
||||
}}
|
||||
>
|
||||
<TestComponent />
|
||||
<TestComponentWrapper />
|
||||
</MediaDevicesContext.Provider>,
|
||||
);
|
||||
await user.click(await findByText("Valid sound"));
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
useMediaDevices,
|
||||
} from "./livekit/MediaDevicesContext";
|
||||
import { type PrefetchedSounds } from "./soundUtils";
|
||||
import { useUrlParams } from "./UrlParams";
|
||||
|
||||
/**
|
||||
* Play a sound though a given AudioContext. Will take
|
||||
@@ -71,7 +72,7 @@ export function useAudioContext<S extends string>(
|
||||
): UseAudioContext<S> | null {
|
||||
const [soundEffectVolume] = useSetting(soundEffectVolumeSetting);
|
||||
const { audioOutput } = useMediaDevices();
|
||||
|
||||
const { controlledAudioDevices } = useUrlParams();
|
||||
const [audioContext, setAudioContext] = useState<AudioContext>();
|
||||
const [audioBuffers, setAudioBuffers] = useState<Record<S, AudioBuffer>>();
|
||||
|
||||
@@ -110,14 +111,18 @@ export function useAudioContext<S extends string>(
|
||||
|
||||
// Update the sink ID whenever we change devices.
|
||||
useEffect(() => {
|
||||
if (audioContext && "setSinkId" in audioContext) {
|
||||
if (
|
||||
audioContext &&
|
||||
"setSinkId" in audioContext &&
|
||||
!controlledAudioDevices
|
||||
) {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
|
||||
// @ts-expect-error - setSinkId doesn't exist yet in types, maybe because it's not supported everywhere.
|
||||
audioContext.setSinkId(audioOutput.selectedId).catch((ex) => {
|
||||
logger.warn("Unable to change sink for audio context", ex);
|
||||
});
|
||||
}
|
||||
}, [audioContext, audioOutput.selectedId]);
|
||||
}, [audioContext, audioOutput.selectedId, controlledAudioDevices]);
|
||||
const { pan: earpiecePan, volume: earpieceVolume } = useEarpieceAudioConfig();
|
||||
|
||||
// Don't return a function until we're ready.
|
||||
|
||||
@@ -9612,7 +9612,7 @@ __metadata:
|
||||
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#head=develop":
|
||||
version: 37.6.0
|
||||
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=93982716951ce2583904bfc26b27d6a86ba17a87"
|
||||
resolution: "matrix-js-sdk@https://github.com/matrix-org/matrix-js-sdk.git#commit=bf6dc16ad32d47f2c6e167236f4c853ceef01d4f"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.12.5"
|
||||
"@matrix-org/matrix-sdk-crypto-wasm": "npm:^14.2.0"
|
||||
@@ -9629,7 +9629,7 @@ __metadata:
|
||||
sdp-transform: "npm:^2.14.1"
|
||||
unhomoglyph: "npm:^1.0.6"
|
||||
uuid: "npm:11"
|
||||
checksum: 10c0/22a28099d2deaf0ca7f609a5859fe00fbd20c314d3b607a95b4a623a8aa159e428310b1849c77ab7b9875a29fc2d924cddbb6fc83dc4e42a74c4713401dcb0be
|
||||
checksum: 10c0/2877e7c5b2779200b48f3152bb7b510e58899b1e779e7e6d2bc1a236ed178fa8858f0547b644a2029f48f55dc7cc3954f48e2598c8963d45293c8280ccc23039
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user