diff --git a/src/frontend/src/features/rooms/livekit/components/blur/BackgroundBlurTrackProcessorJsWrapper.ts b/src/frontend/src/features/rooms/livekit/components/blur/BackgroundBlurTrackProcessorJsWrapper.ts deleted file mode 100644 index 603e793b..00000000 --- a/src/frontend/src/features/rooms/livekit/components/blur/BackgroundBlurTrackProcessorJsWrapper.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - BackgroundBlur, - BackgroundTransformer, - ProcessorWrapper, -} from '@livekit/track-processors' -import { ProcessorOptions, Track } from 'livekit-client' -import { - BackgroundProcessorInterface, - BackgroundOptions, - ProcessorType, -} from '.' - -/** - * This is simply a wrapper around track-processor-js Processor - * in order to be compatible with a common interface BackgroundBlurProcessorInterface - * used across the project. - */ -export class BackgroundBlurTrackProcessorJsWrapper - implements BackgroundProcessorInterface -{ - name: string = 'blur' - - processor: ProcessorWrapper - - opts: BackgroundOptions - - constructor(opts: BackgroundOptions) { - this.processor = BackgroundBlur(opts.blurRadius) - this.opts = opts - } - - async init(opts: ProcessorOptions) { - return this.processor.init(opts) - } - - async restart(opts: ProcessorOptions) { - return this.processor.restart(opts) - } - - async destroy() { - return this.processor.destroy() - } - - update(opts: BackgroundOptions): void { - this.processor.updateTransformerOptions(opts) - } - - get processedTrack() { - return this.processor.processedTrack - } - - get options() { - return (this.processor.transformer as BackgroundTransformer).options - } - - clone() { - return new BackgroundBlurTrackProcessorJsWrapper({ - blurRadius: this.options!.blurRadius, - }) - } - - serialize() { - return { - type: ProcessorType.BLUR, - options: this.options, - } - } -} diff --git a/src/frontend/src/features/rooms/livekit/components/blur/BackgroundCustomProcessor.ts b/src/frontend/src/features/rooms/livekit/components/blur/BackgroundCustomProcessor.ts index 744a749f..fdc9fdb2 100644 --- a/src/frontend/src/features/rooms/livekit/components/blur/BackgroundCustomProcessor.ts +++ b/src/frontend/src/features/rooms/livekit/components/blur/BackgroundCustomProcessor.ts @@ -118,7 +118,7 @@ export class BackgroundCustomProcessor implements BackgroundProcessorInterface { } } - update(opts: BackgroundOptions): void { + async update(opts: BackgroundOptions): Promise { this.options = opts this._initVirtualBackgroundImage() } diff --git a/src/frontend/src/features/rooms/livekit/components/blur/BackgroundVirtualTrackProcessorJsWrapper.ts b/src/frontend/src/features/rooms/livekit/components/blur/BackgroundVirtualTrackProcessorJsWrapper.ts deleted file mode 100644 index 0a2525ad..00000000 --- a/src/frontend/src/features/rooms/livekit/components/blur/BackgroundVirtualTrackProcessorJsWrapper.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ProcessorOptions, Track } from 'livekit-client' -import { - BackgroundOptions, - BackgroundProcessorInterface, - ProcessorType, -} from '.' -import { - BackgroundTransformer, - ProcessorWrapper, - VirtualBackground, -} from '@livekit/track-processors' - -export class BackgroundVirtualTrackProcessorJsWrapper - implements BackgroundProcessorInterface -{ - name = 'virtual' - - processor: ProcessorWrapper - - opts: BackgroundOptions - - constructor(opts: BackgroundOptions) { - this.processor = VirtualBackground(opts.imagePath!) - this.opts = opts - } - - async init(opts: ProcessorOptions) { - return this.processor.init(opts) - } - - async restart(opts: ProcessorOptions) { - return this.processor.restart(opts) - } - - async destroy() { - return this.processor.destroy() - } - - update(opts: BackgroundOptions): void { - this.processor.updateTransformerOptions(opts) - } - - get processedTrack() { - return this.processor.processedTrack - } - - get options() { - return (this.processor.transformer as BackgroundTransformer).options - } - - clone() { - return new BackgroundVirtualTrackProcessorJsWrapper(this.options) - } - - serialize() { - return { - type: ProcessorType.VIRTUAL, - options: this.options, - } - } -} diff --git a/src/frontend/src/features/rooms/livekit/components/blur/UnifiedBackgroundTrackProcessor.ts b/src/frontend/src/features/rooms/livekit/components/blur/UnifiedBackgroundTrackProcessor.ts new file mode 100644 index 00000000..3c96b2de --- /dev/null +++ b/src/frontend/src/features/rooms/livekit/components/blur/UnifiedBackgroundTrackProcessor.ts @@ -0,0 +1,91 @@ +import { ProcessorOptions, Track } from 'livekit-client' +import { + BackgroundBlur, + BackgroundTransformer, + ProcessorWrapper, + VirtualBackground, +} from '@livekit/track-processors' +import { + BackgroundOptions, + BackgroundProcessorInterface, + ProcessorType, +} from '.' + +export class UnifiedBackgroundTrackProcessor + implements BackgroundProcessorInterface +{ + processor: ProcessorWrapper + opts: BackgroundOptions + processorType: ProcessorType + + constructor(opts: BackgroundOptions) { + this.opts = opts + + if (opts.imagePath) { + this.processorType = ProcessorType.VIRTUAL + this.processor = VirtualBackground(opts.imagePath) + } else if (opts.blurRadius !== undefined) { + this.processorType = ProcessorType.BLUR + this.processor = BackgroundBlur(opts.blurRadius) + } else { + throw new Error( + 'Must provide either imagePath for virtual background or blurRadius for blur' + ) + } + } + + async init(opts: ProcessorOptions) { + return this.processor.init(opts) + } + + async restart(opts: ProcessorOptions) { + return this.processor.restart(opts) + } + + async destroy() { + return this.processor.destroy() + } + + async update(opts: BackgroundOptions): Promise { + const newProcessorType = opts.imagePath + ? ProcessorType.VIRTUAL + : ProcessorType.BLUR + + let processedOpts = opts + if (newProcessorType !== this.processorType) { + this.processorType = newProcessorType + if (newProcessorType === ProcessorType.VIRTUAL) { + this.processor.name = 'virtual-background' + processedOpts = { ...opts, blurRadius: undefined } + } else { + this.processor.name = 'background-blur' + processedOpts = { ...opts, imagePath: undefined } + } + } + await this.processor.updateTransformerOptions(processedOpts) + this.opts = processedOpts + } + + get name() { + return this.processor.name + } + + get processedTrack() { + return this.processor.processedTrack + } + + get options() { + return (this.processor.transformer as BackgroundTransformer).options + } + + clone() { + return new UnifiedBackgroundTrackProcessor(this.options || this.opts) + } + + serialize() { + return { + type: this.processorType, + options: this.options, + } + } +} diff --git a/src/frontend/src/features/rooms/livekit/components/blur/index.ts b/src/frontend/src/features/rooms/livekit/components/blur/index.ts index fa74ae44..13c85c8d 100644 --- a/src/frontend/src/features/rooms/livekit/components/blur/index.ts +++ b/src/frontend/src/features/rooms/livekit/components/blur/index.ts @@ -1,8 +1,7 @@ import { ProcessorWrapper } from '@livekit/track-processors' import { Track, TrackProcessor } from 'livekit-client' -import { BackgroundBlurTrackProcessorJsWrapper } from './BackgroundBlurTrackProcessorJsWrapper' import { BackgroundCustomProcessor } from './BackgroundCustomProcessor' -import { BackgroundVirtualTrackProcessorJsWrapper } from './BackgroundVirtualTrackProcessorJsWrapper' +import { UnifiedBackgroundTrackProcessor } from './UnifiedBackgroundTrackProcessor' export type BackgroundOptions = { blurRadius?: number @@ -16,7 +15,7 @@ export interface ProcessorSerialized { export interface BackgroundProcessorInterface extends TrackProcessor { - update(opts: BackgroundOptions): void + update(opts: BackgroundOptions): Promise options: BackgroundOptions clone(): BackgroundProcessorInterface serialize(): ProcessorSerialized @@ -47,9 +46,7 @@ export class BackgroundProcessorFactory { if (!isBlur && !isVirtual) return undefined if (ProcessorWrapper.isSupported) { - return isBlur - ? new BackgroundBlurTrackProcessorJsWrapper(opts) - : new BackgroundVirtualTrackProcessorJsWrapper(opts) + return new UnifiedBackgroundTrackProcessor(opts) } if (BackgroundCustomProcessor.isSupported) { diff --git a/src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx b/src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx index 9542a056..ea408338 100644 --- a/src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx +++ b/src/frontend/src/features/rooms/livekit/components/effects/EffectsConfiguration.tsx @@ -2,13 +2,13 @@ import { LocalVideoTrack, Track } from 'livekit-client' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { + BackgroundOptions, BackgroundProcessorFactory, BackgroundProcessorInterface, ProcessorType, - BackgroundOptions, } from '../blur' import { css } from '@/styled-system/css' -import { Text, P, ToggleButton, H } from '@/primitives' +import { H, P, Text, ToggleButton } from '@/primitives' import { styled } from '@/styled-system/jsx' import { BlurOn } from '@/components/icons/BlurOn' import { BlurOnStrong } from '@/components/icons/BlurOnStrong' @@ -105,7 +105,11 @@ export const EffectsConfiguration = ({ if (isSelected(type, options)) { // Stop processor. await clearEffect() - } else if (!processor || processor.serialize().type !== type) { + } else if ( + !processor || + (processor.serialize().type !== type && + !BackgroundProcessorFactory.hasModernApiSupport()) + ) { // Change processor. const newProcessor = BackgroundProcessorFactory.getProcessor( type, @@ -121,8 +125,7 @@ export const EffectsConfiguration = ({ await videoTrack.setProcessor(newProcessor) onSubmit?.(newProcessor) } else { - // Update processor. - processor?.update(options) + await processor?.update(options) // We want to trigger onSubmit when options changes so the parent component is aware of it. onSubmit?.(processor) }