diff --git a/.changeset/sour-starfishes-act.md b/.changeset/sour-starfishes-act.md new file mode 100644 index 0000000000..a0a9aca46e --- /dev/null +++ b/.changeset/sour-starfishes-act.md @@ -0,0 +1,5 @@ +--- +"livekit-client": patch +--- + +Fix trackProcessor creation from LocalParticipant.createTracks diff --git a/src/room/participant/LocalParticipant.ts b/src/room/participant/LocalParticipant.ts index f0f32eff78..729707c2ff 100644 --- a/src/room/participant/LocalParticipant.ts +++ b/src/room/participant/LocalParticipant.ts @@ -31,6 +31,7 @@ import LocalTrack from '../track/LocalTrack'; import LocalTrackPublication from '../track/LocalTrackPublication'; import LocalVideoTrack, { videoLayersFromEncodings } from '../track/LocalVideoTrack'; import { Track } from '../track/Track'; +import { extractProcessorsFromOptions } from '../track/create'; import type { AudioCaptureOptions, BackupVideoCodec, @@ -40,7 +41,6 @@ import type { VideoCaptureOptions, } from '../track/options'; import { ScreenSharePresets, VideoPresets, isBackupCodec } from '../track/options'; -import type { TrackProcessor } from '../track/processor/types'; import { constraintsForOptions, getLogContextFromTrack, @@ -486,6 +486,9 @@ export default class LocalParticipant extends Participant { * @returns */ async createTracks(options?: CreateLocalTracksOptions): Promise { + options ??= {}; + const { audioProcessor, videoProcessor } = extractProcessorsFromOptions(options); + const mergedOptions = mergeDefaultOptions( options, this.roomOptions?.audioCaptureDefaults, @@ -540,12 +543,10 @@ export default class LocalParticipant extends Participant { track.setAudioContext(this.audioContext); } track.mediaStream = stream; - if (trackOptions.processor) { - if (track instanceof LocalAudioTrack) { - await track.setProcessor(trackOptions.processor as TrackProcessor); - } else { - await track.setProcessor(trackOptions.processor as TrackProcessor); - } + if (track instanceof LocalAudioTrack && audioProcessor) { + await track.setProcessor(audioProcessor); + } else if (track instanceof LocalVideoTrack && videoProcessor) { + await track.setProcessor(videoProcessor); } return track; }), diff --git a/src/room/track/create.ts b/src/room/track/create.ts index e8a9fa7022..8914bdf91f 100644 --- a/src/room/track/create.ts +++ b/src/room/track/create.ts @@ -14,13 +14,32 @@ import type { VideoCaptureOptions, } from './options'; import { ScreenSharePresets } from './options'; -import type { TrackProcessor } from './processor/types'; +import type { + AudioProcessorOptions, + TrackProcessor, + VideoProcessorOptions, +} from './processor/types'; import { constraintsForOptions, mergeDefaultOptions, screenCaptureToDisplayMediaStreamOptions, } from './utils'; +/** @internal */ +export function extractProcessorsFromOptions(options: CreateLocalTracksOptions) { + let audioProcessor: TrackProcessor | undefined; + let videoProcessor: TrackProcessor | undefined; + + if (typeof options.audio === 'object' && options.audio.processor) { + audioProcessor = options.audio.processor; + } + if (typeof options.video === 'object' && options.video.processor) { + videoProcessor = options.video.processor; + } + + return { audioProcessor, videoProcessor }; +} + /** * Creates a local video and audio track at the same time. When acquiring both * audio and video tracks together, it'll display a single permission prompt to @@ -35,6 +54,7 @@ export async function createLocalTracks( options.audio ??= true; options.video ??= true; + const { audioProcessor, videoProcessor } = extractProcessorsFromOptions(options); const opts = mergeDefaultOptions(options, audioDefaults, videoDefaults); const constraints = constraintsForOptions(opts); @@ -55,7 +75,7 @@ export async function createLocalTracks( return Promise.all( stream.getTracks().map(async (mediaStreamTrack) => { const isAudio = mediaStreamTrack.kind === 'audio'; - let trackOptions = isAudio ? options!.audio : options!.video; + let trackOptions = isAudio ? opts!.audio : opts!.video; if (typeof trackOptions === 'boolean' || !trackOptions) { trackOptions = {}; } @@ -80,13 +100,12 @@ export async function createLocalTracks( track.source = Track.Source.Microphone; } track.mediaStream = stream; - if (trackOptions.processor) { - if (track instanceof LocalAudioTrack) { - await track.setProcessor(trackOptions.processor as TrackProcessor); - } else if (track instanceof LocalVideoTrack) { - await track.setProcessor(trackOptions.processor as TrackProcessor); - } + if (track instanceof LocalAudioTrack && audioProcessor) { + await track.setProcessor(audioProcessor); + } else if (track instanceof LocalVideoTrack && videoProcessor) { + await track.setProcessor(videoProcessor); } + return track; }), );