diff --git a/embedded/web/package.json b/embedded/web/package.json index e7dfcc2e..b0e03a9c 100644 --- a/embedded/web/package.json +++ b/embedded/web/package.json @@ -1,6 +1,6 @@ { "name": "@lotusguild/element-call-embedded", - "version": "0.25.0-lotus.2", + "version": "0.25.0-lotus.3", "files": [ "README.md", "LICENSE-AGPL-3.0", diff --git a/src/lotus/lotusAudioConstraints.test.ts b/src/lotus/lotusAudioConstraints.test.ts index 90d66591..effac8d0 100644 --- a/src/lotus/lotusAudioConstraints.test.ts +++ b/src/lotus/lotusAudioConstraints.test.ts @@ -88,6 +88,16 @@ afterEach(() => { }); describe("[lotus] audio-capture URL param overrides", () => { + test("mic capture is always requested mono (stereo interfaces on Firefox published L-only)", () => { + getUrlParams.mockReturnValue({ + echoCancellation: false, + noiseSuppression: false, + autoGainControl: false, + }); + createRoom(); + expect(capturedAudioDefaults()).toMatchObject({ channelCount: 1 }); + }); + test("with params defaulted to true, the Settings govern (upstream behaviour)", () => { getUrlParams.mockReturnValue({ echoCancellation: true, diff --git a/src/state/CallViewModel/remoteMembers/ConnectionFactory.ts b/src/state/CallViewModel/remoteMembers/ConnectionFactory.ts index c8aae360..b4c083a4 100644 --- a/src/state/CallViewModel/remoteMembers/ConnectionFactory.ts +++ b/src/state/CallViewModel/remoteMembers/ConnectionFactory.ts @@ -183,6 +183,13 @@ function generateRoomOption({ audioCaptureDefaults: { ...liveKitOptions.audioCaptureDefaults, deviceId: devices.audioInput.selected$.value?.id, + // [lotus] Voice is mono. Without this, Firefox captures a 2-channel + // audio interface (e.g. a Scarlett Solo with one XLR mic on input 1) as + // stereo and, with browser audio processing off, publishes it that way — + // peers hear the speaker in the left ear only. Chrome downmixes such + // captures itself, which is why it only showed on Firefox. Screenshare + // audio is captured separately and is unaffected. + channelCount: 1, echoCancellation: echoCancellationSetting.getValue() && getUrlParams().echoCancellation !== false,