Skip to content

Commit ec41a93

Browse files
authored
Make processor initialization work on track create (#1039)
1 parent 9e055f0 commit ec41a93

File tree

8 files changed

+50
-7
lines changed

8 files changed

+50
-7
lines changed

.changeset/eight-turtles-tell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@livekit/components-react": patch
3+
---
4+
5+
Make processor initialization work on track create

examples/nextjs/pages/e2ee.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { generateRandomUserId } from '../lib/helper';
99
const E2EEExample: NextPage = () => {
1010
const params = typeof window !== 'undefined' ? new URLSearchParams(location.search) : null;
1111
const roomName = params?.get('room') ?? 'test-room';
12-
const userIdentity = params?.get('user') ?? generateRandomUserId();
12+
const userIdentity = React.useMemo(() => params?.get('user') ?? generateRandomUserId(), []);
1313
setLogLevel('warn', { liveKitClientLogLevel: 'debug' });
1414

1515
const token = useToken(process.env.NEXT_PUBLIC_LK_TOKEN_ENDPOINT, roomName, {

examples/nextjs/pages/prejoin.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,24 @@
33
import * as React from 'react';
44
import { PreJoin, setLogLevel } from '@livekit/components-react';
55
import type { NextPage } from 'next';
6+
import { Track, TrackProcessor } from 'livekit-client';
7+
import { BackgroundBlur } from '@livekit/track-processors';
68

79
const PreJoinExample: NextPage = () => {
810
setLogLevel('debug', { liveKitClientLogLevel: 'warn' });
911

12+
const [backgroundBlur, setBackgroundBlur] = React.useState<
13+
TrackProcessor<Track.Kind.Video> | undefined
14+
>(undefined);
15+
16+
React.useEffect(() => {
17+
setBackgroundBlur(BackgroundBlur());
18+
}, []);
19+
1020
return (
1121
<div data-lk-theme="default" style={{ height: '100vh' }}>
1222
<PreJoin
23+
videoProcessor={backgroundBlur}
1324
defaults={{ videoDeviceId: '' }}
1425
onSubmit={(values) => {
1526
values.audioDeviceId;

examples/nextjs/pages/processors.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from '@livekit/components-react';
1414
import type { NextPage } from 'next';
1515
import { ControlBarControls } from '@livekit/components-react';
16-
import { LocalVideoTrack, Track } from 'livekit-client';
16+
import { LocalVideoTrack, Track, TrackProcessor } from 'livekit-client';
1717
import { BackgroundBlur } from '@livekit/track-processors';
1818

1919
function Stage() {
@@ -23,14 +23,15 @@ function Stage() {
2323
const [blurEnabled, setBlurEnabled] = React.useState(false);
2424
const [processorPending, setProcessorPending] = React.useState(false);
2525
const { cameraTrack } = useLocalParticipant();
26+
const [blur] = React.useState(BackgroundBlur());
2627

2728
React.useEffect(() => {
2829
const localCamTrack = cameraTrack?.track as LocalVideoTrack | undefined;
2930
if (localCamTrack) {
3031
setProcessorPending(true);
3132
try {
3233
if (blurEnabled && !localCamTrack.getProcessor()) {
33-
localCamTrack.setProcessor(BackgroundBlur());
34+
localCamTrack.setProcessor(blur);
3435
} else if (!blurEnabled) {
3536
localCamTrack.stopProcessor();
3637
}

packages/react/etc/components-react.api.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { ScreenShareCaptureOptions } from 'livekit-client';
3434
import { setLogLevel as setLogLevel_2 } from 'livekit-client';
3535
import { SVGProps } from 'react';
3636
import { Track } from 'livekit-client';
37+
import { TrackProcessor } from 'livekit-client';
3738
import { TrackPublication } from 'livekit-client';
3839
import { TrackPublishOptions } from 'livekit-client';
3940
import { TranscriptionSegment } from 'livekit-client';
@@ -546,7 +547,7 @@ export interface ParticipantTileProps extends React_2.HTMLAttributes<HTMLDivElem
546547
export type PinState = TrackReferenceOrPlaceholder[];
547548

548549
// @public
549-
export function PreJoin({ defaults, onValidate, onSubmit, onError, debug, joinLabel, micLabel, camLabel, userLabel, persistUserChoices, ...htmlProps }: PreJoinProps): React_2.JSX.Element;
550+
export function PreJoin({ defaults, onValidate, onSubmit, onError, debug, joinLabel, micLabel, camLabel, userLabel, persistUserChoices, videoProcessor, ...htmlProps }: PreJoinProps): React_2.JSX.Element;
550551

551552
// @public
552553
export interface PreJoinProps extends Omit<React_2.HTMLAttributes<HTMLDivElement>, 'onSubmit' | 'onError'> {
@@ -566,6 +567,8 @@ export interface PreJoinProps extends Omit<React_2.HTMLAttributes<HTMLDivElement
566567
persistUserChoices?: boolean;
567568
// (undocumented)
568569
userLabel?: string;
570+
// (undocumented)
571+
videoProcessor?: TrackProcessor<Track.Kind.Video>;
569572
}
570573

571574
// Warning: (ae-internal-missing-underscore) The name "QualityExcellentIcon" should be prefixed with an underscore because the declaration is marked as @internal

packages/react/src/hooks/useLiveKitRoom.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { HTMLAttributes } from 'react';
66

77
import type { LiveKitRoomProps } from '../components';
88
import { mergeProps } from '../mergeProps';
9+
import { roomOptionsStringifyReplacer } from '../utils';
910

1011
const defaultRoomProps: Partial<LiveKitRoomProps> = {
1112
connect: true,
@@ -60,7 +61,7 @@ export function useLiveKitRoom<T extends HTMLElement>(
6061

6162
React.useEffect(() => {
6263
setRoom(passedRoom ?? new Room(options));
63-
}, [passedRoom]);
64+
}, [passedRoom, JSON.stringify(options, roomOptionsStringifyReplacer)]);
6465

6566
const htmlProps = React.useMemo(() => {
6667
const { className } = setupLiveKitRoom();

packages/react/src/prefabs/PreJoin.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
LocalAudioTrack,
44
LocalTrack,
55
LocalVideoTrack,
6+
TrackProcessor,
67
} from 'livekit-client';
78
import {
89
createLocalAudioTrack,
@@ -22,6 +23,7 @@ import { ParticipantPlaceholder } from '../assets/images';
2223
import { useMediaDevices, usePersistentUserChoices } from '../hooks';
2324
import { useWarnAboutMissingStyles } from '../hooks/useWarnAboutMissingStyles';
2425
import { defaultUserChoices } from '@livekit/components-core';
26+
import { roomOptionsStringifyReplacer } from '../utils';
2527

2628
/**
2729
* Props for the PreJoin component.
@@ -50,6 +52,7 @@ export interface PreJoinProps
5052
* @alpha
5153
*/
5254
persistUserChoices?: boolean;
55+
videoProcessor?: TrackProcessor<Track.Kind.Video>;
5356
}
5457

5558
/** @alpha */
@@ -92,7 +95,7 @@ export function usePreviewTracks(
9295
track.stop();
9396
});
9497
};
95-
}, [JSON.stringify(options), onError, trackLock]);
98+
}, [JSON.stringify(options, roomOptionsStringifyReplacer), onError, trackLock]);
9699

97100
return tracks;
98101
}
@@ -222,6 +225,7 @@ export function PreJoin({
222225
camLabel = 'Camera',
223226
userLabel = 'Username',
224227
persistUserChoices = true,
228+
videoProcessor,
225229
...htmlProps
226230
}: PreJoinProps) {
227231
const [userChoices, setUserChoices] = React.useState(defaultUserChoices);
@@ -279,7 +283,9 @@ export function PreJoin({
279283
const tracks = usePreviewTracks(
280284
{
281285
audio: audioEnabled ? { deviceId: initialUserChoices.audioDeviceId } : false,
282-
video: videoEnabled ? { deviceId: initialUserChoices.videoDeviceId } : false,
286+
video: videoEnabled
287+
? { deviceId: initialUserChoices.videoDeviceId, processor: videoProcessor }
288+
: false,
283289
},
284290
onError,
285291
);

packages/react/src/utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,19 @@ export function warnAboutMissingStyles(el?: HTMLElement) {
6060
}
6161
}
6262
}
63+
64+
/**
65+
*
66+
* @internal
67+
* used to stringify room options to detect dependency changes for react hooks.
68+
* Replaces processors and e2ee options with strings.
69+
*/
70+
export function roomOptionsStringifyReplacer(key: string, val: unknown) {
71+
if (key === 'processor' && val && typeof val === 'object' && 'name' in val) {
72+
return val.name;
73+
}
74+
if (key === 'e2ee' && val) {
75+
return 'e2ee-enabled';
76+
}
77+
return val;
78+
}

0 commit comments

Comments
 (0)