@stream-io/video-filters-web 0.7.1 → 0.7.3
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.
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs.js +20 -31
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +20 -31
- package/dist/index.es.js.map +1 -1
- package/dist/src/BaseVideoProcessor.d.ts +1 -1
- package/dist/src/VirtualBackground.d.ts +0 -1
- package/dist/src/WebGLRenderer.d.ts +5 -0
- package/dist/src/types.d.ts +35 -4
- package/package.json +1 -1
- package/src/BaseVideoProcessor.ts +1 -4
- package/src/VirtualBackground.ts +13 -13
- package/src/WebGLRenderer.ts +17 -3
- package/src/types.ts +41 -16
|
@@ -29,7 +29,7 @@ export declare abstract class BaseVideoProcessor {
|
|
|
29
29
|
protected constructor(track: MediaStreamVideoTrack, hooks?: VideoTrackProcessorHooks);
|
|
30
30
|
start(): Promise<MediaStreamTrack>;
|
|
31
31
|
stop(): void;
|
|
32
|
-
|
|
32
|
+
protected updateStats(delay: number): void;
|
|
33
33
|
protected abstract initialize(): Promise<void>;
|
|
34
34
|
protected abstract transform(frame: VideoFrame): Promise<VideoFrame>;
|
|
35
35
|
protected onFlush(): void;
|
|
@@ -14,7 +14,6 @@ export declare class VirtualBackground extends BaseVideoProcessor {
|
|
|
14
14
|
private latestCategoryMask;
|
|
15
15
|
private latestConfidenceMask;
|
|
16
16
|
private lastFrameTime;
|
|
17
|
-
private count;
|
|
18
17
|
constructor(track: MediaStreamVideoTrack, options?: BackgroundOptions, hooks?: VideoTrackProcessorHooks);
|
|
19
18
|
protected initialize(): Promise<void>;
|
|
20
19
|
private initializeSegmenter;
|
|
@@ -75,6 +75,11 @@ export declare class WebGLRenderer {
|
|
|
75
75
|
bgBlur: number;
|
|
76
76
|
bgBlurRadius: number;
|
|
77
77
|
isSelfieMode: boolean;
|
|
78
|
+
segmentationOptions?: {
|
|
79
|
+
smoothingFactor?: number;
|
|
80
|
+
smoothstepMin?: number;
|
|
81
|
+
smoothstepMax?: number;
|
|
82
|
+
};
|
|
78
83
|
}, categoryTexture?: WebGLTexture, confidenceTexture?: WebGLTexture): void;
|
|
79
84
|
close(): void;
|
|
80
85
|
}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -7,11 +7,41 @@ export type BackgroundSource = {
|
|
|
7
7
|
};
|
|
8
8
|
export type BackgroundFilter = 'blur' | 'image';
|
|
9
9
|
export type BackgroundBlurLevel = 'low' | 'medium' | 'high' | number;
|
|
10
|
+
/**
|
|
11
|
+
* Options for controlling the segmentation mask smoothing.
|
|
12
|
+
* These values are passed to the WebGL shader that blends
|
|
13
|
+
* consecutive segmentation masks over time.
|
|
14
|
+
*/
|
|
15
|
+
export interface SegmentationOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Controls how fast the mask adapts to new segmentation results.
|
|
18
|
+
* Higher values make the mask react faster but may cause flickering.
|
|
19
|
+
* Lower values produce smoother transitions but increase latency.
|
|
20
|
+
* Value should be between 0 and 1.
|
|
21
|
+
* @default 0.8
|
|
22
|
+
*/
|
|
23
|
+
smoothingFactor?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Lower edge of the smoothstep function applied to the confidence mask.
|
|
26
|
+
* Confidence values below this are mapped to 0 (background).
|
|
27
|
+
* Value should be between 0 and 1, and less than smoothstepMax.
|
|
28
|
+
* @default 0.6
|
|
29
|
+
*/
|
|
30
|
+
smoothstepMin?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Upper edge of the smoothstep function applied to the confidence mask.
|
|
33
|
+
* Confidence values above this are mapped to 1 (foreground).
|
|
34
|
+
* Value should be between 0 and 1, and greater than smoothstepMin.
|
|
35
|
+
* @default 0.9
|
|
36
|
+
*/
|
|
37
|
+
smoothstepMax?: number;
|
|
38
|
+
}
|
|
10
39
|
export interface SegmenterOptions {
|
|
11
40
|
backgroundSource?: BackgroundSource | null;
|
|
12
41
|
bgBlur: number;
|
|
13
42
|
bgBlurRadius: number;
|
|
14
43
|
isSelfieMode: boolean;
|
|
44
|
+
segmentationOptions?: SegmentationOptions;
|
|
15
45
|
}
|
|
16
46
|
/**
|
|
17
47
|
* Static configuration for the processor, defining which background
|
|
@@ -23,6 +53,7 @@ export interface BackgroundOptions {
|
|
|
23
53
|
backgroundFilter?: BackgroundFilter;
|
|
24
54
|
backgroundBlurLevel?: BackgroundBlurLevel;
|
|
25
55
|
backgroundImage?: string | undefined;
|
|
56
|
+
segmentationOptions?: SegmentationOptions;
|
|
26
57
|
}
|
|
27
58
|
/**
|
|
28
59
|
* Performance statistics for video processing.
|
|
@@ -39,7 +70,7 @@ export interface VideoTrackProcessorHooks {
|
|
|
39
70
|
onError?: (error: unknown) => void;
|
|
40
71
|
onStats?: (stats: PerformanceStats) => void;
|
|
41
72
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Maps blur level to blur strength values.
|
|
75
|
+
*/
|
|
76
|
+
export declare const BACKGROUND_BLUR_MAP: Record<'low' | 'medium' | 'high', number>;
|
package/package.json
CHANGED
|
@@ -64,11 +64,8 @@ export abstract class BaseVideoProcessor {
|
|
|
64
64
|
this.canvas.height = frame.displayHeight;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const start = performance.now();
|
|
68
67
|
const processed = await this.transform(frame);
|
|
69
|
-
const delay = performance.now() - start;
|
|
70
68
|
|
|
71
|
-
this.updateStats(delay);
|
|
72
69
|
controller.enqueue(processed);
|
|
73
70
|
} catch (e) {
|
|
74
71
|
this.hooks.onError?.(e);
|
|
@@ -98,7 +95,7 @@ export abstract class BaseVideoProcessor {
|
|
|
98
95
|
this.onStop();
|
|
99
96
|
}
|
|
100
97
|
|
|
101
|
-
|
|
98
|
+
protected updateStats(delay: number): void {
|
|
102
99
|
this.frames++;
|
|
103
100
|
this.delayTotal += delay;
|
|
104
101
|
|
package/src/VirtualBackground.ts
CHANGED
|
@@ -24,7 +24,6 @@ export class VirtualBackground extends BaseVideoProcessor {
|
|
|
24
24
|
private latestCategoryMask: WebGLTexture | undefined = undefined;
|
|
25
25
|
private latestConfidenceMask: WebGLTexture | undefined = undefined;
|
|
26
26
|
private lastFrameTime = -1;
|
|
27
|
-
private count = 0;
|
|
28
27
|
|
|
29
28
|
constructor(
|
|
30
29
|
track: MediaStreamVideoTrack,
|
|
@@ -71,10 +70,12 @@ export class VirtualBackground extends BaseVideoProcessor {
|
|
|
71
70
|
|
|
72
71
|
protected async transform(frame: VideoFrame): Promise<VideoFrame> {
|
|
73
72
|
const currentTime = frame.timestamp;
|
|
74
|
-
const hasNewFrame = currentTime
|
|
73
|
+
const hasNewFrame = currentTime - this.lastFrameTime > 1_000;
|
|
75
74
|
this.lastFrameTime = currentTime;
|
|
76
75
|
|
|
77
76
|
if (hasNewFrame && this.isSegmenterReady && this.segmenter) {
|
|
77
|
+
const start = performance.now();
|
|
78
|
+
|
|
78
79
|
await this.runSegmentation(frame);
|
|
79
80
|
|
|
80
81
|
this.webGlRenderer.render(
|
|
@@ -83,6 +84,8 @@ export class VirtualBackground extends BaseVideoProcessor {
|
|
|
83
84
|
this.latestCategoryMask,
|
|
84
85
|
this.latestConfidenceMask,
|
|
85
86
|
);
|
|
87
|
+
|
|
88
|
+
this.updateStats(performance.now() - start);
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
return new VideoFrame(this.canvas, { timestamp: frame.timestamp });
|
|
@@ -121,25 +124,22 @@ export class VirtualBackground extends BaseVideoProcessor {
|
|
|
121
124
|
bgBlur: 0,
|
|
122
125
|
bgBlurRadius: 0,
|
|
123
126
|
isSelfieMode,
|
|
127
|
+
segmentationOptions: this.options.segmentationOptions,
|
|
124
128
|
};
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
const blurLevel = this.options.backgroundBlurLevel;
|
|
132
|
+
const strength =
|
|
133
|
+
typeof blurLevel === 'string'
|
|
134
|
+
? BACKGROUND_BLUR_MAP[blurLevel]
|
|
135
|
+
: Math.round(blurLevel ?? 5);
|
|
128
136
|
|
|
129
|
-
if (typeof blurLevel === 'string') {
|
|
130
|
-
return {
|
|
131
|
-
...BACKGROUND_BLUR_MAP[blurLevel],
|
|
132
|
-
backgroundSource: undefined,
|
|
133
|
-
isSelfieMode,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const numeric = blurLevel ?? 5;
|
|
138
137
|
return {
|
|
139
138
|
backgroundSource: undefined,
|
|
140
|
-
bgBlur: Math.min(
|
|
141
|
-
bgBlurRadius: Math.min(
|
|
139
|
+
bgBlur: Math.min(strength * 1.5, 20),
|
|
140
|
+
bgBlurRadius: Math.min(strength, 10),
|
|
142
141
|
isSelfieMode,
|
|
142
|
+
segmentationOptions: this.options.segmentationOptions,
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
145
|
|
package/src/WebGLRenderer.ts
CHANGED
|
@@ -754,6 +754,11 @@ export class WebGLRenderer {
|
|
|
754
754
|
bgBlur: number;
|
|
755
755
|
bgBlurRadius: number;
|
|
756
756
|
isSelfieMode: boolean;
|
|
757
|
+
segmentationOptions?: {
|
|
758
|
+
smoothingFactor?: number;
|
|
759
|
+
smoothstepMin?: number;
|
|
760
|
+
smoothstepMax?: number;
|
|
761
|
+
};
|
|
757
762
|
},
|
|
758
763
|
categoryTexture?: WebGLTexture,
|
|
759
764
|
confidenceTexture?: WebGLTexture,
|
|
@@ -864,9 +869,18 @@ export class WebGLRenderer {
|
|
|
864
869
|
gl.bindTexture(gl.TEXTURE_2D, prevStateTexture);
|
|
865
870
|
gl.uniform1i(stateUpdateLocations.prevStateTexture, 2);
|
|
866
871
|
|
|
867
|
-
gl.uniform1f(
|
|
868
|
-
|
|
869
|
-
|
|
872
|
+
gl.uniform1f(
|
|
873
|
+
stateUpdateLocations.smoothingFactor,
|
|
874
|
+
options.segmentationOptions?.smoothingFactor ?? 0.8,
|
|
875
|
+
);
|
|
876
|
+
gl.uniform1f(
|
|
877
|
+
stateUpdateLocations.smoothstepMin,
|
|
878
|
+
options.segmentationOptions?.smoothstepMin ?? 0.6,
|
|
879
|
+
);
|
|
880
|
+
gl.uniform1f(
|
|
881
|
+
stateUpdateLocations.smoothstepMax,
|
|
882
|
+
options.segmentationOptions?.smoothstepMax ?? 0.9,
|
|
883
|
+
);
|
|
870
884
|
|
|
871
885
|
gl.uniform1i(
|
|
872
886
|
stateUpdateLocations.selfieModel,
|
package/src/types.ts
CHANGED
|
@@ -8,11 +8,44 @@ export type BackgroundSource = {
|
|
|
8
8
|
export type BackgroundFilter = 'blur' | 'image';
|
|
9
9
|
export type BackgroundBlurLevel = 'low' | 'medium' | 'high' | number;
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Options for controlling the segmentation mask smoothing.
|
|
13
|
+
* These values are passed to the WebGL shader that blends
|
|
14
|
+
* consecutive segmentation masks over time.
|
|
15
|
+
*/
|
|
16
|
+
export interface SegmentationOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Controls how fast the mask adapts to new segmentation results.
|
|
19
|
+
* Higher values make the mask react faster but may cause flickering.
|
|
20
|
+
* Lower values produce smoother transitions but increase latency.
|
|
21
|
+
* Value should be between 0 and 1.
|
|
22
|
+
* @default 0.8
|
|
23
|
+
*/
|
|
24
|
+
smoothingFactor?: number;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Lower edge of the smoothstep function applied to the confidence mask.
|
|
28
|
+
* Confidence values below this are mapped to 0 (background).
|
|
29
|
+
* Value should be between 0 and 1, and less than smoothstepMax.
|
|
30
|
+
* @default 0.6
|
|
31
|
+
*/
|
|
32
|
+
smoothstepMin?: number;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Upper edge of the smoothstep function applied to the confidence mask.
|
|
36
|
+
* Confidence values above this are mapped to 1 (foreground).
|
|
37
|
+
* Value should be between 0 and 1, and greater than smoothstepMin.
|
|
38
|
+
* @default 0.9
|
|
39
|
+
*/
|
|
40
|
+
smoothstepMax?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
11
43
|
export interface SegmenterOptions {
|
|
12
44
|
backgroundSource?: BackgroundSource | null;
|
|
13
45
|
bgBlur: number;
|
|
14
46
|
bgBlurRadius: number;
|
|
15
47
|
isSelfieMode: boolean;
|
|
48
|
+
segmentationOptions?: SegmentationOptions;
|
|
16
49
|
}
|
|
17
50
|
/**
|
|
18
51
|
* Static configuration for the processor, defining which background
|
|
@@ -24,6 +57,7 @@ export interface BackgroundOptions {
|
|
|
24
57
|
backgroundFilter?: BackgroundFilter;
|
|
25
58
|
backgroundBlurLevel?: BackgroundBlurLevel;
|
|
26
59
|
backgroundImage?: string | undefined;
|
|
60
|
+
segmentationOptions?: SegmentationOptions;
|
|
27
61
|
}
|
|
28
62
|
|
|
29
63
|
/**
|
|
@@ -43,20 +77,11 @@ export interface VideoTrackProcessorHooks {
|
|
|
43
77
|
onStats?: (stats: PerformanceStats) => void;
|
|
44
78
|
}
|
|
45
79
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
> = {
|
|
50
|
-
low:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
},
|
|
54
|
-
medium: {
|
|
55
|
-
bgBlur: 15,
|
|
56
|
-
bgBlurRadius: 4,
|
|
57
|
-
},
|
|
58
|
-
high: {
|
|
59
|
-
bgBlur: 30,
|
|
60
|
-
bgBlurRadius: 5,
|
|
61
|
-
},
|
|
80
|
+
/**
|
|
81
|
+
* Maps blur level to blur strength values.
|
|
82
|
+
*/
|
|
83
|
+
export const BACKGROUND_BLUR_MAP: Record<'low' | 'medium' | 'high', number> = {
|
|
84
|
+
low: 3,
|
|
85
|
+
medium: 5,
|
|
86
|
+
high: 7,
|
|
62
87
|
};
|