From 025a2dc2a9ff5bad814b08abbbaf4689cdb102c2 Mon Sep 17 00:00:00 2001 From: Timo Date: Tue, 3 Jun 2025 13:26:00 +0200 Subject: [PATCH] Improvements to audio renderer codebase. --- src/livekit/MatrixAudioRenderer.test.tsx | 14 ++++++++++++++ src/livekit/MatrixAudioRenderer.tsx | 13 ++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/livekit/MatrixAudioRenderer.test.tsx b/src/livekit/MatrixAudioRenderer.test.tsx index 637e02ed..05051fca 100644 --- a/src/livekit/MatrixAudioRenderer.test.tsx +++ b/src/livekit/MatrixAudioRenderer.test.tsx @@ -58,6 +58,7 @@ it("should render for member", () => { expect(container).toBeTruthy(); expect(queryAllByTestId("audio")).toHaveLength(1); }); + it("should not render without member", () => { const { container, queryAllByTestId } = render( { expect(queryAllByTestId("audio")).toHaveLength(0); }); +it("should not render without member", () => { + const memberships = [ + { sender: "othermember", deviceId: "123" }, + ] as CallMembership[]; + const { container, queryAllByTestId } = render( + , + ); + expect(container).toBeTruthy(); + expect(queryAllByTestId("audio")).toHaveLength(0); + +}); + it("should not setup audioContext gain and pan if there is no need to.", () => { render( { expect(testAudioContext.gain.gain.value).toEqual(1); expect(testAudioContext.pan.pan.value).toEqual(0); }); + it("should setup audioContext gain and pan", () => { vi.spyOn(MediaDevicesContext, "useEarpieceAudioConfig").mockReturnValue({ pan: 1, diff --git a/src/livekit/MatrixAudioRenderer.tsx b/src/livekit/MatrixAudioRenderer.tsx index 3e7a3e89..ee4062c4 100644 --- a/src/livekit/MatrixAudioRenderer.tsx +++ b/src/livekit/MatrixAudioRenderer.tsx @@ -14,11 +14,13 @@ import { type AudioTrackProps, } from "@livekit/components-react"; import { type CallMembership } from "matrix-js-sdk/lib/matrixrtc"; -import { logger } from "matrix-js-sdk/lib/logger"; +import { logger as rootLogger } from "matrix-js-sdk/lib/logger"; import { useEarpieceAudioConfig } from "./MediaDevicesContext"; import { useReactiveState } from "../useReactiveState"; import * as controls from "../controls"; + +const logger = rootLogger.getChild("[MatrixAudioRenderer]"); export interface MatrixAudioRendererProps { /** * The list of participants to render audio for. @@ -59,6 +61,7 @@ export function MatrixAudioRenderer({ ); const loggedInvalidIdentities = useRef(new Set()); + /** * Log an invalid livekit track identity. * A invalid identity is one that does not match any of the matrix rtc members. @@ -96,6 +99,14 @@ export function MatrixAudioRenderer({ isValid ); }); + useEffect(() => { + if (!tracks.some((t) => !validIdentities.has(t.participant.identity))) { + logger.debug( + `All audio tracks have a matching matrix call member identity.`, + ); + loggedInvalidIdentities.current.clear(); + } + }, [tracks, validIdentities]); // This component is also (in addition to the "only play audio for connected members" logic above) // responsible for mimicking earpiece audio on iPhones.