mirror of
https://github.com/vector-im/element-call.git
synced 2026-10-16 23:45:50 +00:00
Name the background effect pieces after background effects
- One name, as review asked: TrackProcessorContext becomes BackgroundEffectsContext, with BackgroundEffectsProvider, BackgroundEffectsState, useBackgroundEffects, useBackgroundEffectsState$ and useSyncBackgroundEffects. - The state's Behavior is backgroundEffectsState$ wherever it is passed, in place of trackProcessorState$, trackerProcessorState$ and processorState$. - Renames only: nothing changes in behaviour. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+3
-3
@@ -74,7 +74,7 @@ import {
|
|||||||
import { MediaDevicesContext } from "../src/MediaDevicesContext";
|
import { MediaDevicesContext } from "../src/MediaDevicesContext";
|
||||||
import { MediaDevices } from "../src/state/MediaDevices";
|
import { MediaDevices } from "../src/state/MediaDevices";
|
||||||
import { ObservableScope } from "../src/state/ObservableScope";
|
import { ObservableScope } from "../src/state/ObservableScope";
|
||||||
import { ProcessorProvider } from "../src/livekit/TrackProcessorContext";
|
import { BackgroundEffectsProvider } from "../src/livekit/BackgroundEffectsContext";
|
||||||
import { Config } from "../src/config/Config";
|
import { Config } from "../src/config/Config";
|
||||||
import { type ConfigOptions } from "../src/config/ConfigOptions";
|
import { type ConfigOptions } from "../src/config/ConfigOptions";
|
||||||
import { i18n } from "../src/utils/i18n";
|
import { i18n } from "../src/utils/i18n";
|
||||||
@@ -252,7 +252,7 @@ export const ElementCall: FC<ElementCallProps> = ({
|
|||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<ClientProvider client={client}>
|
<ClientProvider client={client}>
|
||||||
<MediaDevicesContext value={mediaDevices}>
|
<MediaDevicesContext value={mediaDevices}>
|
||||||
<ProcessorProvider>
|
<BackgroundEffectsProvider>
|
||||||
<CallView
|
<CallView
|
||||||
client={client}
|
client={client}
|
||||||
rtcSession={rtcSession}
|
rtcSession={rtcSession}
|
||||||
@@ -261,7 +261,7 @@ export const ElementCall: FC<ElementCallProps> = ({
|
|||||||
preload={params.preload}
|
preload={params.preload}
|
||||||
skipLobby={params.skipLobby}
|
skipLobby={params.skipLobby}
|
||||||
/>
|
/>
|
||||||
</ProcessorProvider>
|
</BackgroundEffectsProvider>
|
||||||
</MediaDevicesContext>
|
</MediaDevicesContext>
|
||||||
</ClientProvider>
|
</ClientProvider>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|||||||
+3
-3
@@ -35,7 +35,7 @@ import { ErrorPage, LoadingPage } from "./FullScreenView";
|
|||||||
import { Initializer } from "./initializer";
|
import { Initializer } from "./initializer";
|
||||||
import { type WidgetHelpers } from "./widget";
|
import { type WidgetHelpers } from "./widget";
|
||||||
import { useTheme } from "./useTheme";
|
import { useTheme } from "./useTheme";
|
||||||
import { ProcessorProvider } from "./livekit/TrackProcessorContext";
|
import { BackgroundEffectsProvider } from "./livekit/BackgroundEffectsContext";
|
||||||
import { type AppViewModel } from "./state/AppViewModel";
|
import { type AppViewModel } from "./state/AppViewModel";
|
||||||
import { MediaDevicesContext } from "./MediaDevicesContext";
|
import { MediaDevicesContext } from "./MediaDevicesContext";
|
||||||
import {
|
import {
|
||||||
@@ -148,7 +148,7 @@ export const App: FC<Props> = ({ vm, widget }) => {
|
|||||||
loaded && clientReady ? (
|
loaded && clientReady ? (
|
||||||
<ClientProvider client={widgetClient}>
|
<ClientProvider client={widgetClient}>
|
||||||
<MediaDevicesContext value={vm.mediaDevices}>
|
<MediaDevicesContext value={vm.mediaDevices}>
|
||||||
<ProcessorProvider>
|
<BackgroundEffectsProvider>
|
||||||
<Sentry.ErrorBoundary
|
<Sentry.ErrorBoundary
|
||||||
fallback={(error) => <ErrorPage error={error} />}
|
fallback={(error) => <ErrorPage error={error} />}
|
||||||
>
|
>
|
||||||
@@ -159,7 +159,7 @@ export const App: FC<Props> = ({ vm, widget }) => {
|
|||||||
<SentryRoute path="*" element={<RoomPage />} />
|
<SentryRoute path="*" element={<RoomPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Sentry.ErrorBoundary>
|
</Sentry.ErrorBoundary>
|
||||||
</ProcessorProvider>
|
</BackgroundEffectsProvider>
|
||||||
</MediaDevicesContext>
|
</MediaDevicesContext>
|
||||||
</ClientProvider>
|
</ClientProvider>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
+14
-14
@@ -16,12 +16,12 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
applyProcessor,
|
applyProcessor,
|
||||||
ProcessorProvider,
|
BackgroundEffectsProvider,
|
||||||
type ProcessorState,
|
type BackgroundEffectsState,
|
||||||
trackProcessorSync,
|
syncBackgroundEffects,
|
||||||
useTrackProcessor,
|
useBackgroundEffects,
|
||||||
useTrackProcessorSync,
|
useSyncBackgroundEffects,
|
||||||
} from "./TrackProcessorContext";
|
} from "./BackgroundEffectsContext";
|
||||||
import { backgroundBlur } from "../settings/settings";
|
import { backgroundBlur } from "../settings/settings";
|
||||||
import { constant } from "../state/Behavior";
|
import { constant } from "../state/Behavior";
|
||||||
import { flushPromises, testScope } from "../utils/test";
|
import { flushPromises, testScope } from "../utils/test";
|
||||||
@@ -112,10 +112,10 @@ describe("applyProcessor", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("trackProcessorSync", () => {
|
describe("syncBackgroundEffects", () => {
|
||||||
it("applies the processor to the current track", () => {
|
it("applies the processor to the current track", () => {
|
||||||
const track = mockTrack("live");
|
const track = mockTrack("live");
|
||||||
trackProcessorSync(
|
syncBackgroundEffects(
|
||||||
testScope(),
|
testScope(),
|
||||||
constant(track),
|
constant(track),
|
||||||
constant({ supported: true, processor }),
|
constant({ supported: true, processor }),
|
||||||
@@ -124,7 +124,7 @@ describe("trackProcessorSync", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("ProcessorProvider", () => {
|
describe("BackgroundEffectsProvider", () => {
|
||||||
/** A camera track that holds whatever processor it is given. */
|
/** A camera track that holds whatever processor it is given. */
|
||||||
function cameraTrack(): LocalVideoTrack {
|
function cameraTrack(): LocalVideoTrack {
|
||||||
let current: unknown;
|
let current: unknown;
|
||||||
@@ -142,17 +142,17 @@ describe("ProcessorProvider", () => {
|
|||||||
} as unknown as LocalVideoTrack;
|
} as unknown as LocalVideoTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
let seen: ProcessorState[];
|
let seen: BackgroundEffectsState[];
|
||||||
const Surface: FC<{ track: LocalVideoTrack | null }> = ({ track }) => {
|
const Surface: FC<{ track: LocalVideoTrack | null }> = ({ track }) => {
|
||||||
seen.push(useTrackProcessor());
|
seen.push(useBackgroundEffects());
|
||||||
useTrackProcessorSync(track);
|
useSyncBackgroundEffects(track);
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
// One component for every render, so a rerender updates the tree rather than
|
// One component for every render, so a rerender updates the tree rather than
|
||||||
// mounting a second provider with a pipeline of its own.
|
// mounting a second provider with a pipeline of its own.
|
||||||
const Surfaces: FC<{ tracks: (LocalVideoTrack | null)[] }> = ({ tracks }) =>
|
const Surfaces: FC<{ tracks: (LocalVideoTrack | null)[] }> = ({ tracks }) =>
|
||||||
createElement(
|
createElement(
|
||||||
ProcessorProvider,
|
BackgroundEffectsProvider,
|
||||||
null,
|
null,
|
||||||
createElement(
|
createElement(
|
||||||
"div",
|
"div",
|
||||||
@@ -169,7 +169,7 @@ describe("ProcessorProvider", () => {
|
|||||||
await flushPromises();
|
await flushPromises();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const latest = (): ProcessorState => seen[seen.length - 1];
|
const latest = (): BackgroundEffectsState => seen[seen.length - 1];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
seen = [];
|
seen = [];
|
||||||
@@ -35,24 +35,24 @@ import { useBehavior } from "../useBehavior";
|
|||||||
// it is a combination of exposing observable and react hooks.
|
// it is a combination of exposing observable and react hooks.
|
||||||
// preferably we should not make this a context anymore and instead just a vm?
|
// preferably we should not make this a context anymore and instead just a vm?
|
||||||
|
|
||||||
export type ProcessorState = {
|
export type BackgroundEffectsState = {
|
||||||
supported: boolean | undefined;
|
supported: boolean | undefined;
|
||||||
processor: undefined | ProcessorWrapper<BackgroundOptions>;
|
processor: undefined | ProcessorWrapper<BackgroundOptions>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ProcessorContext = createContext<BackgroundEffects | undefined>(
|
const BackgroundEffectsContext = createContext<BackgroundEffects | undefined>(
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
export function useTrackProcessor(): ProcessorState {
|
export function useBackgroundEffects(): BackgroundEffectsState {
|
||||||
return useBehavior(useTrackProcessorState$());
|
return useBehavior(useBackgroundEffectsState$());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useTrackProcessorState$(): Behavior<ProcessorState> {
|
export function useBackgroundEffectsState$(): Behavior<BackgroundEffectsState> {
|
||||||
const effects = use(ProcessorContext);
|
const effects = use(BackgroundEffectsContext);
|
||||||
if (effects === undefined)
|
if (effects === undefined)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"useTrackProcessor must be used within a ProcessorProvider",
|
"useBackgroundEffects must be used within a BackgroundEffectsProvider",
|
||||||
);
|
);
|
||||||
return effects.state$;
|
return effects.state$;
|
||||||
}
|
}
|
||||||
@@ -91,24 +91,24 @@ export function applyProcessor(
|
|||||||
/**
|
/**
|
||||||
* Updates your video tracks to always use the given processor.
|
* Updates your video tracks to always use the given processor.
|
||||||
*/
|
*/
|
||||||
export const trackProcessorSync = (
|
export const syncBackgroundEffects = (
|
||||||
scope: ObservableScope,
|
scope: ObservableScope,
|
||||||
videoTrack$: Behavior<LocalVideoTrack | null>,
|
videoTrack$: Behavior<LocalVideoTrack | null>,
|
||||||
processor$: Behavior<ProcessorState>,
|
backgroundEffectsState$: Behavior<BackgroundEffectsState>,
|
||||||
): void => {
|
): void => {
|
||||||
combineLatest([videoTrack$, processor$])
|
combineLatest([videoTrack$, backgroundEffectsState$])
|
||||||
.pipe(scope.bind())
|
.pipe(scope.bind())
|
||||||
.subscribe(([videoTrack, processorState]) => {
|
.subscribe(([videoTrack, backgroundEffectsState]) => {
|
||||||
if (!processorState) return;
|
if (!backgroundEffectsState) return;
|
||||||
if (!videoTrack) return;
|
if (!videoTrack) return;
|
||||||
applyProcessor(videoTrack, processorState.processor);
|
applyProcessor(videoTrack, backgroundEffectsState.processor);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useTrackProcessorSync = (
|
export const useSyncBackgroundEffects = (
|
||||||
videoTrack: LocalVideoTrack | null,
|
videoTrack: LocalVideoTrack | null,
|
||||||
): void => {
|
): void => {
|
||||||
const { processor } = useTrackProcessor();
|
const { processor } = useBackgroundEffects();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!videoTrack) return;
|
if (!videoTrack) return;
|
||||||
applyProcessor(videoTrack, processor);
|
applyProcessor(videoTrack, processor);
|
||||||
@@ -119,7 +119,7 @@ interface Props {
|
|||||||
children: JSX.Element;
|
children: JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProcessorProvider: FC<Props> = ({ children }) => {
|
export const BackgroundEffectsProvider: FC<Props> = ({ children }) => {
|
||||||
const [effects, setEffects] = useState<BackgroundEffects | null>(null);
|
const [effects, setEffects] = useState<BackgroundEffects | null>(null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const scope = new ObservableScope();
|
const scope = new ObservableScope();
|
||||||
@@ -137,5 +137,9 @@ export const ProcessorProvider: FC<Props> = ({ children }) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (effects === null) return null;
|
if (effects === null) return null;
|
||||||
return <ProcessorContext value={effects}>{children}</ProcessorContext>;
|
return (
|
||||||
|
<BackgroundEffectsContext value={effects}>
|
||||||
|
{children}
|
||||||
|
</BackgroundEffectsContext>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
@@ -61,7 +61,7 @@ import {
|
|||||||
} from "../HostBridge";
|
} from "../HostBridge";
|
||||||
import { type JoinCallData } from "../widget";
|
import { type JoinCallData } from "../widget";
|
||||||
import { MatrixRTCTransportMissingError } from "../utils/errors";
|
import { MatrixRTCTransportMissingError } from "../utils/errors";
|
||||||
import { ProcessorProvider } from "../livekit/TrackProcessorContext";
|
import { BackgroundEffectsProvider } from "../livekit/BackgroundEffectsContext";
|
||||||
import { MediaDevicesContext } from "../MediaDevicesContext";
|
import { MediaDevicesContext } from "../MediaDevicesContext";
|
||||||
import { constant } from "../state/Behavior";
|
import { constant } from "../state/Behavior";
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ function createCallView(
|
|||||||
<HostBridgeProvider value={hostBridge}>
|
<HostBridgeProvider value={hostBridge}>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<MediaDevicesContext value={mockMediaDevices({})}>
|
<MediaDevicesContext value={mockMediaDevices({})}>
|
||||||
<ProcessorProvider>
|
<BackgroundEffectsProvider>
|
||||||
{options.withErrorBoundary ? (
|
{options.withErrorBoundary ? (
|
||||||
<GroupCallErrorBoundary recoveryActionHandler={vi.fn()}>
|
<GroupCallErrorBoundary recoveryActionHandler={vi.fn()}>
|
||||||
{callView}
|
{callView}
|
||||||
@@ -201,7 +201,7 @@ function createCallView(
|
|||||||
) : (
|
) : (
|
||||||
callView
|
callView
|
||||||
)}
|
)}
|
||||||
</ProcessorProvider>
|
</BackgroundEffectsProvider>
|
||||||
</MediaDevicesContext>
|
</MediaDevicesContext>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</HostBridgeProvider>
|
</HostBridgeProvider>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import { MediaDevicesContext } from "../MediaDevicesContext";
|
|||||||
import { type MediaDevices as ECMediaDevices } from "../state/MediaDevices";
|
import { type MediaDevices as ECMediaDevices } from "../state/MediaDevices";
|
||||||
import { AppBar } from "../AppBar";
|
import { AppBar } from "../AppBar";
|
||||||
import { type MatrixInfo } from "./VideoPreview";
|
import { type MatrixInfo } from "./VideoPreview";
|
||||||
import { ProcessorProvider } from "../livekit/TrackProcessorContext";
|
import { BackgroundEffectsProvider } from "../livekit/BackgroundEffectsContext";
|
||||||
import { initializeWidget } from "../widget";
|
import { initializeWidget } from "../widget";
|
||||||
import { RootElementProvider } from "../RootElementContext";
|
import { RootElementProvider } from "../RootElementContext";
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ describe("ActiveCall", () => {
|
|||||||
const { findByTestId } = render(
|
const { findByTestId } = render(
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<MediaDevicesContext value={mediaDevices}>
|
<MediaDevicesContext value={mediaDevices}>
|
||||||
<ProcessorProvider>
|
<BackgroundEffectsProvider>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<RoomContext value={mockLivekitRoom({ localParticipant })}>
|
<RoomContext value={mockLivekitRoom({ localParticipant })}>
|
||||||
<ActiveCall
|
<ActiveCall
|
||||||
@@ -257,7 +257,7 @@ describe("ActiveCall", () => {
|
|||||||
/>
|
/>
|
||||||
</RoomContext>
|
</RoomContext>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ProcessorProvider>
|
</BackgroundEffectsProvider>
|
||||||
</MediaDevicesContext>
|
</MediaDevicesContext>
|
||||||
</BrowserRouter>,
|
</BrowserRouter>,
|
||||||
);
|
);
|
||||||
@@ -292,7 +292,7 @@ describe("ActiveCall", () => {
|
|||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<RootElementProvider value={root}>
|
<RootElementProvider value={root}>
|
||||||
<MediaDevicesContext value={mediaDevices}>
|
<MediaDevicesContext value={mediaDevices}>
|
||||||
<ProcessorProvider>
|
<BackgroundEffectsProvider>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<RoomContext value={mockLivekitRoom({ localParticipant })}>
|
<RoomContext value={mockLivekitRoom({ localParticipant })}>
|
||||||
<ActiveCall
|
<ActiveCall
|
||||||
@@ -307,7 +307,7 @@ describe("ActiveCall", () => {
|
|||||||
/>
|
/>
|
||||||
</RoomContext>
|
</RoomContext>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ProcessorProvider>
|
</BackgroundEffectsProvider>
|
||||||
</MediaDevicesContext>
|
</MediaDevicesContext>
|
||||||
</RootElementProvider>
|
</RootElementProvider>
|
||||||
</BrowserRouter>,
|
</BrowserRouter>,
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ import { useValueBehavior } from "../useValueBehavior.ts";
|
|||||||
import { constant } from "../state/Behavior.ts";
|
import { constant } from "../state/Behavior.ts";
|
||||||
import { Toast } from "../Toast.tsx";
|
import { Toast } from "../Toast.tsx";
|
||||||
import overlayStyles from "../Overlay.module.css";
|
import overlayStyles from "../Overlay.module.css";
|
||||||
import { useTrackProcessorState$ } from "../livekit/TrackProcessorContext.tsx";
|
import { useBackgroundEffectsState$ } from "../livekit/BackgroundEffectsContext.tsx";
|
||||||
import { type Layout } from "../state/layout-types.ts";
|
import { type Layout } from "../state/layout-types.ts";
|
||||||
import { ObservableScope } from "../state/ObservableScope.ts";
|
import { ObservableScope } from "../state/ObservableScope.ts";
|
||||||
import { CallFooter, type FooterSnapshot } from "../components/CallFooter.tsx";
|
import { CallFooter, type FooterSnapshot } from "../components/CallFooter.tsx";
|
||||||
@@ -120,7 +120,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
|
|||||||
const urlParams = useUrlParams();
|
const urlParams = useUrlParams();
|
||||||
const hostBridge = useHostBridge();
|
const hostBridge = useHostBridge();
|
||||||
const mediaDevices = useMediaDevices();
|
const mediaDevices = useMediaDevices();
|
||||||
const trackProcessorState$ = useTrackProcessorState$();
|
const backgroundEffectsState$ = useBackgroundEffectsState$();
|
||||||
// The element we have to draw the call in: the page, or the container a host
|
// The element we have to draw the call in: the page, or the container a host
|
||||||
// gave us. Its size, not the window's, decides how the call is laid out.
|
// gave us. Its size, not the window's, decides how the call is laid out.
|
||||||
const rootElement = useRootElement();
|
const rootElement = useRootElement();
|
||||||
@@ -150,7 +150,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
|
|||||||
},
|
},
|
||||||
reactionsReader.raisedHands$,
|
reactionsReader.raisedHands$,
|
||||||
reactionsReader.reactions$,
|
reactionsReader.reactions$,
|
||||||
trackProcessorState$,
|
backgroundEffectsState$,
|
||||||
);
|
);
|
||||||
// TODO move this somewhere else once we use the callViewModel in the lobby as well!
|
// TODO move this somewhere else once we use the callViewModel in the lobby as well!
|
||||||
vm.join();
|
vm.join();
|
||||||
@@ -170,7 +170,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
|
|||||||
urlParams,
|
urlParams,
|
||||||
hostBridge,
|
hostBridge,
|
||||||
mediaDevices,
|
mediaDevices,
|
||||||
trackProcessorState$,
|
backgroundEffectsState$,
|
||||||
props.client,
|
props.client,
|
||||||
rootElement,
|
rootElement,
|
||||||
]);
|
]);
|
||||||
@@ -201,7 +201,7 @@ export const ActiveCall: FC<ActiveCallProps> = (props) => {
|
|||||||
props.onLeft,
|
props.onLeft,
|
||||||
urlParams,
|
urlParams,
|
||||||
mediaDevices,
|
mediaDevices,
|
||||||
trackProcessorState$,
|
backgroundEffectsState$,
|
||||||
props.client,
|
props.client,
|
||||||
vm,
|
vm,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -14,19 +14,19 @@ import { type MatrixClient, type RoomSummary } from "matrix-js-sdk";
|
|||||||
import { KnockLobbyView } from "./KnockLobbyView";
|
import { KnockLobbyView } from "./KnockLobbyView";
|
||||||
import { LeaveToHomeProvider } from "../LeaveToHomeContext";
|
import { LeaveToHomeProvider } from "../LeaveToHomeContext";
|
||||||
import { MediaDevicesContext } from "../MediaDevicesContext";
|
import { MediaDevicesContext } from "../MediaDevicesContext";
|
||||||
import { type ProcessorState } from "../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../livekit/BackgroundEffectsContext";
|
||||||
import { mockMediaDevices } from "../utils/test";
|
import { mockMediaDevices } from "../utils/test";
|
||||||
|
|
||||||
vi.mock("@livekit/components-react", () => ({
|
vi.mock("@livekit/components-react", () => ({
|
||||||
usePreviewTracks: (): unknown[] => [],
|
usePreviewTracks: (): unknown[] => [],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../livekit/TrackProcessorContext", () => ({
|
vi.mock("../livekit/BackgroundEffectsContext", () => ({
|
||||||
useTrackProcessor: (): ProcessorState => ({
|
useBackgroundEffects: (): BackgroundEffectsState => ({
|
||||||
supported: false,
|
supported: false,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
useTrackProcessorSync: (): void => {},
|
useSyncBackgroundEffects: (): void => {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("react-use-measure", () => ({
|
vi.mock("react-use-measure", () => ({
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
} from "../utils/test";
|
} from "../utils/test";
|
||||||
import { type MediaDevices } from "../state/MediaDevices";
|
import { type MediaDevices } from "../state/MediaDevices";
|
||||||
import { MediaDevicesContext } from "../MediaDevicesContext";
|
import { MediaDevicesContext } from "../MediaDevicesContext";
|
||||||
import { type ProcessorState } from "../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../livekit/BackgroundEffectsContext";
|
||||||
import { type EncryptionSystem } from "../e2ee/sharedKeyManagement";
|
import { type EncryptionSystem } from "../e2ee/sharedKeyManagement";
|
||||||
import lobbyStyles from "./LobbyView.module.css";
|
import lobbyStyles from "./LobbyView.module.css";
|
||||||
import headerStyles from "../Header.module.css";
|
import headerStyles from "../Header.module.css";
|
||||||
@@ -41,12 +41,12 @@ vi.mock("@livekit/components-react", () => ({
|
|||||||
usePreviewTracks: (): unknown[] => [],
|
usePreviewTracks: (): unknown[] => [],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("../livekit/TrackProcessorContext", () => ({
|
vi.mock("../livekit/BackgroundEffectsContext", () => ({
|
||||||
useTrackProcessor: (): ProcessorState => ({
|
useBackgroundEffects: (): BackgroundEffectsState => ({
|
||||||
supported: false,
|
supported: false,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
useTrackProcessorSync: (): void => {},
|
useSyncBackgroundEffects: (): void => {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock("react-use-measure", () => ({
|
vi.mock("react-use-measure", () => ({
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ import { useMediaDevices } from "../MediaDevicesContext";
|
|||||||
import { ObservableScope } from "../state/ObservableScope";
|
import { ObservableScope } from "../state/ObservableScope";
|
||||||
import { useInitial } from "../useInitial";
|
import { useInitial } from "../useInitial";
|
||||||
import {
|
import {
|
||||||
useTrackProcessor,
|
useBackgroundEffects,
|
||||||
useTrackProcessorSync,
|
useSyncBackgroundEffects,
|
||||||
} from "../livekit/TrackProcessorContext";
|
} from "../livekit/BackgroundEffectsContext";
|
||||||
import { getValue } from "../utils/observable";
|
import { getValue } from "../utils/observable";
|
||||||
import { useBehavior } from "../useBehavior";
|
import { useBehavior } from "../useBehavior";
|
||||||
import { CallFooter, type FooterSnapshot } from "../components/CallFooter";
|
import { CallFooter, type FooterSnapshot } from "../components/CallFooter";
|
||||||
@@ -136,7 +136,7 @@ export const LobbyView: FC<Props> = ({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const { processor } = useTrackProcessor();
|
const { processor } = useBackgroundEffects();
|
||||||
|
|
||||||
const initialProcessor = useInitial(() => processor);
|
const initialProcessor = useInitial(() => processor);
|
||||||
const localTrackOptions = useMemo<CreateLocalTracksOptions>(
|
const localTrackOptions = useMemo<CreateLocalTracksOptions>(
|
||||||
@@ -183,7 +183,7 @@ export const LobbyView: FC<Props> = ({
|
|||||||
}
|
}
|
||||||
}, [devices, videoInputId, videoTrack]);
|
}, [devices, videoInputId, videoTrack]);
|
||||||
|
|
||||||
useTrackProcessorSync(videoTrack);
|
useSyncBackgroundEffects(videoTrack);
|
||||||
|
|
||||||
const [footerVm, setFooterVm] = useState<ViewModel<FooterSnapshot> | null>(
|
const [footerVm, setFooterVm] = useState<ViewModel<FooterSnapshot> | null>(
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
import { PreferencesSettingsTab } from "./PreferencesSettingsTab";
|
import { PreferencesSettingsTab } from "./PreferencesSettingsTab";
|
||||||
import { Slider } from "../Slider";
|
import { Slider } from "../Slider";
|
||||||
import { DeviceSelection } from "./DeviceSelection";
|
import { DeviceSelection } from "./DeviceSelection";
|
||||||
import { useTrackProcessor } from "../livekit/TrackProcessorContext";
|
import { useBackgroundEffects } from "../livekit/BackgroundEffectsContext";
|
||||||
import {
|
import {
|
||||||
DeveloperSettingsTab,
|
DeveloperSettingsTab,
|
||||||
type DeveloperSettingsSnapshot,
|
type DeveloperSettingsSnapshot,
|
||||||
@@ -81,7 +81,7 @@ export const SettingsModal: FC<Props> = ({
|
|||||||
|
|
||||||
// Generate a `Checkbox` input to turn blur on or off.
|
// Generate a `Checkbox` input to turn blur on or off.
|
||||||
const BlurCheckbox: React.FC = (): ReactNode => {
|
const BlurCheckbox: React.FC = (): ReactNode => {
|
||||||
const { supported } = useTrackProcessor();
|
const { supported } = useBackgroundEffects();
|
||||||
|
|
||||||
const [blurActive, setBlurActive] = useSetting(backgroundBlurSetting);
|
const [blurActive, setBlurActive] = useSetting(backgroundBlurSetting);
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
BackgroundEffects,
|
BackgroundEffects,
|
||||||
type BackgroundEffectsOptions,
|
type BackgroundEffectsOptions,
|
||||||
} from "./BackgroundEffects";
|
} from "./BackgroundEffects";
|
||||||
import { type ProcessorState } from "../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../livekit/BackgroundEffectsContext";
|
||||||
import { flushPromises, testScope, withTestScheduler } from "../utils/test";
|
import { flushPromises, testScope, withTestScheduler } from "../utils/test";
|
||||||
|
|
||||||
/** A pipeline that records what it is switched to. */
|
/** A pipeline that records what it is switched to. */
|
||||||
@@ -45,7 +45,7 @@ function fakePipeline(): {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** One letter per state: idle, attached. */
|
/** One letter per state: idle, attached. */
|
||||||
function letter(state: ProcessorState): string {
|
function letter(state: BackgroundEffectsState): string {
|
||||||
return state.processor === undefined ? "i" : "a";
|
return state.processor === undefined ? "i" : "a";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { deepCompare } from "matrix-js-sdk/lib/utils";
|
|||||||
|
|
||||||
import { type Behavior } from "./Behavior";
|
import { type Behavior } from "./Behavior";
|
||||||
import { type ObservableScope } from "./ObservableScope";
|
import { type ObservableScope } from "./ObservableScope";
|
||||||
import { type ProcessorState } from "../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../livekit/BackgroundEffectsContext";
|
||||||
|
|
||||||
const blurRadius = 15;
|
const blurRadius = 15;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ export interface BackgroundEffectsOptions {
|
|||||||
|
|
||||||
/** The background effect pipeline, as the camera tracks and the menus see it. */
|
/** The background effect pipeline, as the camera tracks and the menus see it. */
|
||||||
export class BackgroundEffects {
|
export class BackgroundEffects {
|
||||||
public readonly state$: Behavior<ProcessorState>;
|
public readonly state$: Behavior<BackgroundEffectsState>;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
scope: ObservableScope,
|
scope: ObservableScope,
|
||||||
@@ -38,7 +38,7 @@ export class BackgroundEffects {
|
|||||||
) {
|
) {
|
||||||
this.state$ = scope.behavior(
|
this.state$ = scope.behavior(
|
||||||
blur$.pipe(
|
blur$.pipe(
|
||||||
scan<boolean, ProcessorState>(
|
scan<boolean, BackgroundEffectsState>(
|
||||||
(previous, wanted) => {
|
(previous, wanted) => {
|
||||||
// Attached the first time an effect is wanted and never detached
|
// Attached the first time an effect is wanted and never detached
|
||||||
// after, so someone who never turns one on pays for none of it.
|
// after, so someone who never turns one on pays for none of it.
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ import { E2eeType } from "../../e2ee/e2eeType";
|
|||||||
import { MatrixKeyProvider } from "../../e2ee/matrixKeyProvider";
|
import { MatrixKeyProvider } from "../../e2ee/matrixKeyProvider";
|
||||||
import { type MuteStates } from "../MuteStates";
|
import { type MuteStates } from "../MuteStates";
|
||||||
import { HeaderStyle, type UrlParams } from "../../UrlParams";
|
import { HeaderStyle, type UrlParams } from "../../UrlParams";
|
||||||
import { type ProcessorState } from "../../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../../livekit/BackgroundEffectsContext";
|
||||||
import { type HostBridge, nullHostBridge } from "../../HostBridge";
|
import { type HostBridge, nullHostBridge } from "../../HostBridge";
|
||||||
import {
|
import {
|
||||||
layoutShallowEquals,
|
layoutShallowEquals,
|
||||||
@@ -501,7 +501,7 @@ export function createCallViewModel$(
|
|||||||
options: CallViewModelOptions,
|
options: CallViewModelOptions,
|
||||||
handsRaisedSubject$: Observable<Record<string, RaisedHandInfo>>,
|
handsRaisedSubject$: Observable<Record<string, RaisedHandInfo>>,
|
||||||
reactionsSubject$: Observable<Record<string, ReactionInfo>>,
|
reactionsSubject$: Observable<Record<string, ReactionInfo>>,
|
||||||
trackProcessorState$: Behavior<ProcessorState>,
|
backgroundEffectsState$: Behavior<BackgroundEffectsState>,
|
||||||
): CallViewModel {
|
): CallViewModel {
|
||||||
const logger = rootLogger.getChild("[CallViewModel]");
|
const logger = rootLogger.getChild("[CallViewModel]");
|
||||||
const client = matrixRoom.client;
|
const client = matrixRoom.client;
|
||||||
@@ -590,7 +590,7 @@ export function createCallViewModel$(
|
|||||||
client,
|
client,
|
||||||
matrixRoom.roomId,
|
matrixRoom.roomId,
|
||||||
mediaDevices,
|
mediaDevices,
|
||||||
trackProcessorState$,
|
backgroundEffectsState$,
|
||||||
livekitKeyProvider,
|
livekitKeyProvider,
|
||||||
controlledAudioDevices,
|
controlledAudioDevices,
|
||||||
options.livekitRoomFactory,
|
options.livekitRoomFactory,
|
||||||
@@ -645,7 +645,7 @@ export function createCallViewModel$(
|
|||||||
connection,
|
connection,
|
||||||
mediaDevices,
|
mediaDevices,
|
||||||
muteStates,
|
muteStates,
|
||||||
trackProcessorState$,
|
backgroundEffectsState$,
|
||||||
logger.getChild(
|
logger.getChild(
|
||||||
"[Publisher " + connection.transport.livekit_service_url + "]",
|
"[Publisher " + connection.transport.livekit_service_url + "]",
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import {
|
|||||||
localRtcMember,
|
localRtcMember,
|
||||||
} from "../../utils/test-fixtures";
|
} from "../../utils/test-fixtures";
|
||||||
import { type Behavior, constant } from "../Behavior";
|
import { type Behavior, constant } from "../Behavior";
|
||||||
import { type ProcessorState } from "../../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../../livekit/BackgroundEffectsContext";
|
||||||
import { type MediaDevices } from "../MediaDevices";
|
import { type MediaDevices } from "../MediaDevices";
|
||||||
import { type MatrixRTCMode } from "../../config/ConfigOptions";
|
import { type MatrixRTCMode } from "../../config/ConfigOptions";
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ export function withCallViewModel(mode: MatrixRTCMode) {
|
|||||||
},
|
},
|
||||||
raisedHands$,
|
raisedHands$,
|
||||||
reactions$,
|
reactions$,
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
supported: undefined,
|
supported: undefined,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ describe("LocalMembership", () => {
|
|||||||
leave: vi.fn(),
|
leave: vi.fn(),
|
||||||
} as unknown as MatrixRTCSession,
|
} as unknown as MatrixRTCSession,
|
||||||
muteStates: mockMuteStates(),
|
muteStates: mockMuteStates(),
|
||||||
trackProcessorState$: constant({
|
backgroundEffectsState$: constant({
|
||||||
supported: false,
|
supported: false,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
mockMediaDevices,
|
mockMediaDevices,
|
||||||
} from "../../../utils/test";
|
} from "../../../utils/test";
|
||||||
import { Publisher } from "./Publisher";
|
import { Publisher } from "./Publisher";
|
||||||
import { type ProcessorState } from "../../../livekit/TrackProcessorContext";
|
import { type BackgroundEffectsState } from "../../../livekit/BackgroundEffectsContext";
|
||||||
import { type Connection } from "../remoteMembers/Connection";
|
import { type Connection } from "../remoteMembers/Connection";
|
||||||
import { type MuteStates } from "../../MuteStates";
|
import { type MuteStates } from "../../MuteStates";
|
||||||
|
|
||||||
@@ -409,13 +409,13 @@ describe("Bug fix", () => {
|
|||||||
|
|
||||||
describe("turning the camera on with an effect chosen", () => {
|
describe("turning the camera on with an effect chosen", () => {
|
||||||
const processor = {} as ProcessorWrapper<BackgroundOptions>;
|
const processor = {} as ProcessorWrapper<BackgroundOptions>;
|
||||||
let state$: BehaviorSubject<ProcessorState>;
|
let state$: BehaviorSubject<BackgroundEffectsState>;
|
||||||
let publisher: Publisher;
|
let publisher: Publisher;
|
||||||
/** The processor the SDK would give each camera track it made. */
|
/** The processor the SDK would give each camera track it made. */
|
||||||
let madeWith: unknown[];
|
let madeWith: unknown[];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
state$ = new BehaviorSubject<ProcessorState>({
|
state$ = new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ import type { Behavior } from "../../Behavior.ts";
|
|||||||
import type { MediaDevices, SelectedDevice } from "../../MediaDevices.ts";
|
import type { MediaDevices, SelectedDevice } from "../../MediaDevices.ts";
|
||||||
import type { MuteStates } from "../../MuteStates.ts";
|
import type { MuteStates } from "../../MuteStates.ts";
|
||||||
import {
|
import {
|
||||||
type ProcessorState,
|
type BackgroundEffectsState,
|
||||||
trackProcessorSync,
|
syncBackgroundEffects,
|
||||||
} from "../../../livekit/TrackProcessorContext.tsx";
|
} from "../../../livekit/BackgroundEffectsContext.tsx";
|
||||||
|
|
||||||
import { observeTrackReference$ } from "../../observeTrackReference";
|
import { observeTrackReference$ } from "../../observeTrackReference";
|
||||||
import { type Connection } from "../remoteMembers/Connection.ts";
|
import { type Connection } from "../remoteMembers/Connection.ts";
|
||||||
@@ -54,7 +54,7 @@ export class Publisher {
|
|||||||
* @param connection - The connection to use for publishing.
|
* @param connection - The connection to use for publishing.
|
||||||
* @param devices - The media devices to use for audio and video input.
|
* @param devices - The media devices to use for audio and video input.
|
||||||
* @param muteStates - The mute states for audio and video.
|
* @param muteStates - The mute states for audio and video.
|
||||||
* @param trackerProcessorState$ - The processor state for the video track processor (e.g. background blur).
|
* @param backgroundEffectsState$ - The processor state for the video track processor (e.g. background blur).
|
||||||
* @param logger - The logger to use for logging :D.
|
* @param logger - The logger to use for logging :D.
|
||||||
* @param controlledAudioDevices - Whether the app hosting Element Call
|
* @param controlledAudioDevices - Whether the app hosting Element Call
|
||||||
* controls the audio output devices, rather than the browser.
|
* controls the audio output devices, rather than the browser.
|
||||||
@@ -63,7 +63,7 @@ export class Publisher {
|
|||||||
private connection: Pick<Connection, "livekitRoom" | "state$">, //setE2EEEnabled,
|
private connection: Pick<Connection, "livekitRoom" | "state$">, //setE2EEEnabled,
|
||||||
devices: MediaDevices,
|
devices: MediaDevices,
|
||||||
private readonly muteStates: MuteStates,
|
private readonly muteStates: MuteStates,
|
||||||
private readonly trackerProcessorState$: Behavior<ProcessorState>,
|
private readonly backgroundEffectsState$: Behavior<BackgroundEffectsState>,
|
||||||
private logger: Logger,
|
private logger: Logger,
|
||||||
controlledAudioDevices: boolean,
|
controlledAudioDevices: boolean,
|
||||||
) {
|
) {
|
||||||
@@ -73,8 +73,11 @@ export class Publisher {
|
|||||||
this.logger.error("Failed to set E2EE enabled on room", e);
|
this.logger.error("Failed to set E2EE enabled on room", e);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup track processor syncing (blur)
|
this.observeBackgroundEffects(
|
||||||
this.observeTrackProcessors(this.scope, room, this.trackerProcessorState$);
|
this.scope,
|
||||||
|
room,
|
||||||
|
this.backgroundEffectsState$,
|
||||||
|
);
|
||||||
// Observe media device changes and update LiveKit active devices accordingly
|
// Observe media device changes and update LiveKit active devices accordingly
|
||||||
this.observeMediaDevices(this.scope, devices, controlledAudioDevices);
|
this.observeMediaDevices(this.scope, devices, controlledAudioDevices);
|
||||||
|
|
||||||
@@ -412,7 +415,7 @@ export class Publisher {
|
|||||||
this.muteStates.video.setHandler(async (enable) => {
|
this.muteStates.video.setHandler(async (enable) => {
|
||||||
try {
|
try {
|
||||||
this.logger.debug(`handler: Setting LiveKit camera enabled: ${enable}`);
|
this.logger.debug(`handler: Setting LiveKit camera enabled: ${enable}`);
|
||||||
const { processor } = this.trackerProcessorState$.value;
|
const { processor } = this.backgroundEffectsState$.value;
|
||||||
if (enable && processor) await this.dropCameraWithoutEffect(lkRoom);
|
if (enable && processor) await this.dropCameraWithoutEffect(lkRoom);
|
||||||
await lkRoom.localParticipant.setCameraEnabled(enable);
|
await lkRoom.localParticipant.setCameraEnabled(enable);
|
||||||
// Unmute will restart the track if it was paused upstream,
|
// Unmute will restart the track if it was paused upstream,
|
||||||
@@ -441,10 +444,10 @@ export class Publisher {
|
|||||||
await lkRoom.localParticipant.unpublishTrack(track);
|
await lkRoom.localParticipant.unpublishTrack(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
private observeTrackProcessors(
|
private observeBackgroundEffects(
|
||||||
scope: ObservableScope,
|
scope: ObservableScope,
|
||||||
room: LivekitRoom,
|
room: LivekitRoom,
|
||||||
trackerProcessorState$: Behavior<ProcessorState>,
|
backgroundEffectsState$: Behavior<BackgroundEffectsState>,
|
||||||
): void {
|
): void {
|
||||||
const track$ = scope.behavior(
|
const track$ = scope.behavior(
|
||||||
observeTrackReference$(room.localParticipant, Track.Source.Camera).pipe(
|
observeTrackReference$(room.localParticipant, Track.Source.Camera).pipe(
|
||||||
@@ -455,11 +458,11 @@ export class Publisher {
|
|||||||
),
|
),
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
trackProcessorSync(scope, track$, trackerProcessorState$);
|
syncBackgroundEffects(scope, track$, backgroundEffectsState$);
|
||||||
// Every camera track the SDK makes, on joining or on turning the camera
|
// Every camera track the SDK makes, on joining or on turning the camera
|
||||||
// on, then starts with the pipeline on. One attached after publishing lets
|
// on, then starts with the pipeline on. One attached after publishing lets
|
||||||
// the room through while it is built.
|
// the room through while it is built.
|
||||||
trackerProcessorState$.pipe(scope.bind()).subscribe(({ processor }) => {
|
backgroundEffectsState$.pipe(scope.bind()).subscribe(({ processor }) => {
|
||||||
room.options.videoCaptureDefaults = {
|
room.options.videoCaptureDefaults = {
|
||||||
...room.options.videoCaptureDefaults,
|
...room.options.videoCaptureDefaults,
|
||||||
processor,
|
processor,
|
||||||
|
|||||||
@@ -655,7 +655,7 @@ describe("remote track logging", () => {
|
|||||||
// function createSetup(): void {
|
// function createSetup(): void {
|
||||||
// setUpPublishConnection();
|
// setUpPublishConnection();
|
||||||
|
|
||||||
// const fakeTrackProcessorSubject$ = new BehaviorSubject<ProcessorState>({
|
// const fakeTrackProcessorSubject$ = new BehaviorSubject<BackgroundEffectsState>({
|
||||||
// supported: true,
|
// supported: true,
|
||||||
// processor: undefined,
|
// processor: undefined,
|
||||||
// });
|
// });
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import type {
|
|||||||
} from "../../../livekit/openIDSFU.ts";
|
} from "../../../livekit/openIDSFU.ts";
|
||||||
import type { MediaDevices } from "../../MediaDevices.ts";
|
import type { MediaDevices } from "../../MediaDevices.ts";
|
||||||
import type { Behavior } from "../../Behavior.ts";
|
import type { Behavior } from "../../Behavior.ts";
|
||||||
import type { ProcessorState } from "../../../livekit/TrackProcessorContext.tsx";
|
import type { BackgroundEffectsState } from "../../../livekit/BackgroundEffectsContext.tsx";
|
||||||
import { getLiveKitOptions } from "../../../livekit/options.ts";
|
import { getLiveKitOptions } from "../../../livekit/options.ts";
|
||||||
import {
|
import {
|
||||||
advancedCamera,
|
advancedCamera,
|
||||||
@@ -60,7 +60,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
|||||||
* @param client - The OpenID client parts for authentication, needed to get openID and JWT tokens.
|
* @param client - The OpenID client parts for authentication, needed to get openID and JWT tokens.
|
||||||
* @param roomId - The current room ID.
|
* @param roomId - The current room ID.
|
||||||
* @param devices - Used for video/audio out/in capture options.
|
* @param devices - Used for video/audio out/in capture options.
|
||||||
* @param processorState$ - Effects like background blur (only for publishing connection?)
|
* @param backgroundEffectsState$ - Effects like background blur (only for publishing connection?)
|
||||||
* @param livekitKeyProvider - Optional key provider for end-to-end encryption.
|
* @param livekitKeyProvider - Optional key provider for end-to-end encryption.
|
||||||
* @param controlledAudioDevices - Option to indicate whether audio output device is controlled externally (native mobile app).
|
* @param controlledAudioDevices - Option to indicate whether audio output device is controlled externally (native mobile app).
|
||||||
* @param livekitRoomFactory - Optional factory function (for testing) to create LivekitRoom instances. If not provided, a default factory is used.
|
* @param livekitRoomFactory - Optional factory function (for testing) to create LivekitRoom instances. If not provided, a default factory is used.
|
||||||
@@ -69,7 +69,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
|||||||
private client: OpenIDClientParts,
|
private client: OpenIDClientParts,
|
||||||
private readonly roomId: string,
|
private readonly roomId: string,
|
||||||
private devices: MediaDevices,
|
private devices: MediaDevices,
|
||||||
private processorState$: Behavior<ProcessorState>,
|
private backgroundEffectsState$: Behavior<BackgroundEffectsState>,
|
||||||
livekitKeyProvider: BaseKeyProvider | undefined,
|
livekitKeyProvider: BaseKeyProvider | undefined,
|
||||||
private controlledAudioDevices: boolean,
|
private controlledAudioDevices: boolean,
|
||||||
livekitRoomFactory?: () => LivekitRoom,
|
livekitRoomFactory?: () => LivekitRoom,
|
||||||
@@ -77,7 +77,7 @@ export class ECConnectionFactory implements ConnectionFactory {
|
|||||||
const defaultFactory = (): LivekitRoom => {
|
const defaultFactory = (): LivekitRoom => {
|
||||||
const roomOptions = generateRoomOption({
|
const roomOptions = generateRoomOption({
|
||||||
devices: this.devices,
|
devices: this.devices,
|
||||||
processorState: this.processorState$.value,
|
backgroundEffectsState: this.backgroundEffectsState$.value,
|
||||||
e2eeLivekitOptions: livekitKeyProvider && {
|
e2eeLivekitOptions: livekitKeyProvider && {
|
||||||
keyProvider: livekitKeyProvider,
|
keyProvider: livekitKeyProvider,
|
||||||
// It's important that every room use a separate E2EE worker.
|
// It's important that every room use a separate E2EE worker.
|
||||||
@@ -129,12 +129,12 @@ export class ECConnectionFactory implements ConnectionFactory {
|
|||||||
*/
|
*/
|
||||||
function generateRoomOption({
|
function generateRoomOption({
|
||||||
devices,
|
devices,
|
||||||
processorState,
|
backgroundEffectsState,
|
||||||
e2eeLivekitOptions,
|
e2eeLivekitOptions,
|
||||||
controlledAudioDevices,
|
controlledAudioDevices,
|
||||||
}: {
|
}: {
|
||||||
devices: MediaDevices;
|
devices: MediaDevices;
|
||||||
processorState: ProcessorState;
|
backgroundEffectsState: BackgroundEffectsState;
|
||||||
e2eeLivekitOptions:
|
e2eeLivekitOptions:
|
||||||
| E2EEManagerOptions
|
| E2EEManagerOptions
|
||||||
| { e2eeManager: BaseE2EEManager }
|
| { e2eeManager: BaseE2EEManager }
|
||||||
@@ -147,7 +147,7 @@ function generateRoomOption({
|
|||||||
let videoCaptureDefaults = {
|
let videoCaptureDefaults = {
|
||||||
...liveKitOptions.videoCaptureDefaults,
|
...liveKitOptions.videoCaptureDefaults,
|
||||||
deviceId: devices.videoInput.selected$.value?.id,
|
deviceId: devices.videoInput.selected$.value?.id,
|
||||||
processor: processorState.processor,
|
processor: backgroundEffectsState.processor,
|
||||||
};
|
};
|
||||||
let publishDefaults = liveKitOptions.publishDefaults;
|
let publishDefaults = liveKitOptions.publishDefaults;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
mockMediaDevices,
|
mockMediaDevices,
|
||||||
ownMemberMock,
|
ownMemberMock,
|
||||||
} from "../../../utils/test.ts";
|
} from "../../../utils/test.ts";
|
||||||
import type { ProcessorState } from "../../../livekit/TrackProcessorContext.tsx";
|
import type { BackgroundEffectsState } from "../../../livekit/BackgroundEffectsContext.tsx";
|
||||||
import { constant } from "../../Behavior";
|
import { constant } from "../../Behavior";
|
||||||
import {
|
import {
|
||||||
echoCancellationSetting,
|
echoCancellationSetting,
|
||||||
@@ -80,7 +80,7 @@ describe("ECConnectionFactory - Audio inputs options", () => {
|
|||||||
mockClient,
|
mockClient,
|
||||||
"!roomid:example.org",
|
"!roomid:example.org",
|
||||||
mockMediaDevices({}),
|
mockMediaDevices({}),
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
@@ -128,7 +128,7 @@ describe("ECConnectionFactory - ControlledAudioDevice", () => {
|
|||||||
select: () => {},
|
select: () => {},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
@@ -163,7 +163,7 @@ describe("ECConnectionFactory - Camera quality settings", () => {
|
|||||||
mockClient,
|
mockClient,
|
||||||
"!roomid:example.org",
|
"!roomid:example.org",
|
||||||
mockMediaDevices({}),
|
mockMediaDevices({}),
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
@@ -200,7 +200,7 @@ describe("ECConnectionFactory - Camera quality settings", () => {
|
|||||||
mockClient,
|
mockClient,
|
||||||
"!roomid:example.org",
|
"!roomid:example.org",
|
||||||
mockMediaDevices({}),
|
mockMediaDevices({}),
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
@@ -238,7 +238,7 @@ describe("ECConnectionFactory - Camera quality settings", () => {
|
|||||||
mockClient,
|
mockClient,
|
||||||
"!roomid:example.org",
|
"!roomid:example.org",
|
||||||
mockMediaDevices({}),
|
mockMediaDevices({}),
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
ownMemberMock,
|
ownMemberMock,
|
||||||
withTestScheduler,
|
withTestScheduler,
|
||||||
} from "../../../utils/test.ts";
|
} from "../../../utils/test.ts";
|
||||||
import { type ProcessorState } from "../../../livekit/TrackProcessorContext.tsx";
|
import { type BackgroundEffectsState } from "../../../livekit/BackgroundEffectsContext.tsx";
|
||||||
import {
|
import {
|
||||||
areLivekitTransportsEqual,
|
areLivekitTransportsEqual,
|
||||||
createRemoteMatrixLivekitMembers$,
|
createRemoteMatrixLivekitMembers$,
|
||||||
@@ -72,7 +72,7 @@ beforeEach(() => {
|
|||||||
mockClient,
|
mockClient,
|
||||||
"!roomid:example.org",
|
"!roomid:example.org",
|
||||||
mockMediaDevices({}),
|
mockMediaDevices({}),
|
||||||
new BehaviorSubject<ProcessorState>({
|
new BehaviorSubject<BackgroundEffectsState>({
|
||||||
supported: true,
|
supported: true,
|
||||||
processor: undefined,
|
processor: undefined,
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user