@stream-io/video-filters-web 0.8.7 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { BackgroundOptions, VideoTrackProcessorHooks } from './types';
1
+ import { BackgroundEffectOptions, BackgroundOptions, VideoTrackProcessorHooks } from './types';
2
2
  import { BaseVideoProcessor } from './BaseVideoProcessor';
3
3
  /**
4
4
  * Wraps a video MediaStreamTrack in a real-time processing pipeline.
@@ -6,7 +6,7 @@ import { BaseVideoProcessor } from './BaseVideoProcessor';
6
6
  * on a new MediaStreamVideoTrack for downstream consumption.
7
7
  */
8
8
  export declare class VirtualBackground extends BaseVideoProcessor {
9
- private readonly options;
9
+ private options;
10
10
  private segmenter;
11
11
  private isSegmenterReady;
12
12
  private webGlRenderer;
@@ -15,6 +15,7 @@ export declare class VirtualBackground extends BaseVideoProcessor {
15
15
  private latestConfidenceMask;
16
16
  private lastFrameTime;
17
17
  constructor(track: MediaStreamVideoTrack, options?: BackgroundOptions, hooks?: VideoTrackProcessorHooks);
18
+ updateOptions(options: BackgroundEffectOptions): Promise<void>;
18
19
  protected initialize(): Promise<void>;
19
20
  private initializeSegmenter;
20
21
  protected transform(frame: VideoFrame): Promise<VideoFrame>;
@@ -43,17 +43,19 @@ export interface SegmenterOptions {
43
43
  isSelfieMode: boolean;
44
44
  segmentationOptions?: SegmentationOptions;
45
45
  }
46
+ export interface BackgroundEffectOptions {
47
+ backgroundFilter?: BackgroundFilter;
48
+ backgroundBlurLevel?: BackgroundBlurLevel;
49
+ backgroundImage?: string | undefined;
50
+ segmentationOptions?: SegmentationOptions;
51
+ }
46
52
  /**
47
53
  * Static configuration for the processor, defining which background
48
54
  * effect should be applied and how it should behave.
49
55
  */
50
- export interface BackgroundOptions {
56
+ export interface BackgroundOptions extends BackgroundEffectOptions {
51
57
  basePath?: string;
52
58
  modelPath?: string;
53
- backgroundFilter?: BackgroundFilter;
54
- backgroundBlurLevel?: BackgroundBlurLevel;
55
- backgroundImage?: string | undefined;
56
- segmentationOptions?: SegmentationOptions;
57
59
  }
58
60
  /**
59
61
  * Performance statistics for video processing.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-filters-web",
3
- "version": "0.8.7",
3
+ "version": "0.9.0",
4
4
  "main": "./dist/index.cjs.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  BACKGROUND_BLUR_MAP,
3
+ BackgroundEffectOptions,
3
4
  BackgroundOptions,
4
5
  SegmenterOptions,
5
6
  VideoTrackProcessorHooks,
@@ -27,12 +28,35 @@ export class VirtualBackground extends BaseVideoProcessor {
27
28
 
28
29
  constructor(
29
30
  track: MediaStreamVideoTrack,
30
- private readonly options: BackgroundOptions = {},
31
+ private options: BackgroundOptions = {},
31
32
  hooks: VideoTrackProcessorHooks = {},
32
33
  ) {
33
34
  super(track, hooks);
34
35
  }
35
36
 
37
+ async updateOptions(options: BackgroundEffectOptions): Promise<void> {
38
+ const { basePath, modelPath } = this.options;
39
+ const previous = this.options;
40
+ const next = { basePath, modelPath, ...options };
41
+ this.options = next;
42
+ try {
43
+ const opts = await this.initializeSegmenterOptions();
44
+ if (this.options === next) {
45
+ const previousMedia = this.opts?.backgroundSource?.media;
46
+ this.opts = opts;
47
+ if (
48
+ previousMedia instanceof ImageBitmap &&
49
+ previousMedia !== opts.backgroundSource?.media
50
+ ) {
51
+ previousMedia.close();
52
+ }
53
+ }
54
+ } catch (error) {
55
+ if (this.options === next) this.options = previous;
56
+ throw error;
57
+ }
58
+ }
59
+
36
60
  protected async initialize(): Promise<void> {
37
61
  this.webGlRenderer = new WebGLRenderer(this.canvas);
38
62
 
@@ -146,6 +170,10 @@ export class VirtualBackground extends BaseVideoProcessor {
146
170
 
147
171
  private async loadBackground(url?: string) {
148
172
  if (!url) return null;
173
+
174
+ const current = this.opts?.backgroundSource;
175
+ if (current?.url === url) return current;
176
+
149
177
  const result = await fetch(url, { signal: this.abortController.signal });
150
178
  if (!result.ok) {
151
179
  throw new Error(
package/src/types.ts CHANGED
@@ -47,17 +47,20 @@ export interface SegmenterOptions {
47
47
  isSelfieMode: boolean;
48
48
  segmentationOptions?: SegmentationOptions;
49
49
  }
50
+ export interface BackgroundEffectOptions {
51
+ backgroundFilter?: BackgroundFilter;
52
+ backgroundBlurLevel?: BackgroundBlurLevel;
53
+ backgroundImage?: string | undefined;
54
+ segmentationOptions?: SegmentationOptions;
55
+ }
56
+
50
57
  /**
51
58
  * Static configuration for the processor, defining which background
52
59
  * effect should be applied and how it should behave.
53
60
  */
54
- export interface BackgroundOptions {
61
+ export interface BackgroundOptions extends BackgroundEffectOptions {
55
62
  basePath?: string;
56
63
  modelPath?: string;
57
- backgroundFilter?: BackgroundFilter;
58
- backgroundBlurLevel?: BackgroundBlurLevel;
59
- backgroundImage?: string | undefined;
60
- segmentationOptions?: SegmentationOptions;
61
64
  }
62
65
 
63
66
  /**