Tidy the background effect pipeline after review

- The Vite transform wrapper takes Vite's own types, with no cast.
- The pipeline's options are compared with deepCompare, not as JSON.
- Renames `attached` to `enable` and shortens the pipeline's doc comment.
- Drops a comment that blamed an ended track on the pipeline's queue.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
fkwp
2026-10-08 12:22:34 +02:00
co-authored by Claude Opus 5.5
parent e2b89a64b9
commit ce41fee6ff
3 changed files with 11 additions and 21 deletions
-2
View File
@@ -76,8 +76,6 @@ export function applyProcessor(
} }
const track = videoTrack.mediaStreamTrack; const track = videoTrack.mediaStreamTrack;
videoTrack.setProcessor(processor).catch((e) => { videoTrack.setProcessor(processor).catch((e) => {
// The pipeline builds one track at a time, so a track can end while its
// build waits a turn. The camera's next track attaches it again.
if (track.readyState === "ended") if (track.readyState === "ended")
logger.debug("Video processor not attached: the track ended first"); logger.debug("Video processor not attached: the track ended first");
else logger.warn("Failed to attach video processor", e); else logger.warn("Failed to attach video processor", e);
+5 -8
View File
@@ -11,6 +11,7 @@ import {
type SwitchBackgroundProcessorOptions, type SwitchBackgroundProcessorOptions,
} from "@livekit/track-processors"; } from "@livekit/track-processors";
import { logger } from "matrix-js-sdk/lib/logger"; import { logger } from "matrix-js-sdk/lib/logger";
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";
@@ -23,11 +24,7 @@ export interface BackgroundEffectsOptions {
supported: boolean; supported: boolean;
/** Whether blur is chosen. */ /** Whether blur is chosen. */
blur$: Behavior<boolean>; blur$: Behavior<boolean>;
/** /** The background processor pipeline to be switched between effects. */
* Shared by the pre-join preview and the call. Building or destroying it is
* what primes it, and a primed pipeline lets its next frame through
* untouched, so it is switched rather than rebuilt.
*/
pipeline: BackgroundProcessorWrapper; pipeline: BackgroundProcessorWrapper;
} }
@@ -45,9 +42,9 @@ export class BackgroundEffects {
(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.
const attached = const enable =
previous.processor !== undefined || (supported && wanted); previous.processor !== undefined || (supported && wanted);
return { supported, processor: attached ? pipeline : undefined }; return { supported, processor: enable ? pipeline : undefined };
}, },
{ supported, processor: undefined }, { supported, processor: undefined },
), ),
@@ -61,7 +58,7 @@ export class BackgroundEffects {
map(([, blur]): SwitchBackgroundProcessorOptions => map(([, blur]): SwitchBackgroundProcessorOptions =>
blur ? { mode: "background-blur", blurRadius } : { mode: "disabled" }, blur ? { mode: "background-blur", blurRadius } : { mode: "disabled" },
), ),
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)), distinctUntilChanged(deepCompare),
scope.bind(), scope.bind(),
) )
.subscribe((options) => { .subscribe((options) => {
+6 -11
View File
@@ -7,6 +7,7 @@ Please see LICENSE in the repository root for full details.
import { import {
loadEnv, loadEnv,
type Plugin,
type PluginOption, type PluginOption,
searchForWorkspaceRoot, searchForWorkspaceRoot,
type ConfigEnv, type ConfigEnv,
@@ -196,19 +197,13 @@ function exceptMediaPipeWasm(plugins: PluginOption): PluginOption {
) )
return plugin; return plugin;
const transform = plugin.transform; const transform = plugin.transform;
return { const wrapped: Plugin = {
...plugin, ...plugin,
transform(this: unknown, code: string, id: string, options: unknown) { transform(code, id, options) {
if (isLoader(id)) return null; if (isLoader(id)) return null;
return ( return transform.call(this, code, id, options);
transform as (
this: unknown,
c: string,
i: string,
o: unknown,
) => unknown
).call(this, code, id, options);
}, },
} as PluginOption; };
return wrapped;
}); });
} }