@stream-io/video-filters-web 0.1.1 → 0.1.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 +14 -0
- package/dist/index.cjs.js +30 -15
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +30 -15
- package/dist/index.es.js.map +1 -1
- package/dist/src/createRenderer.d.ts +2 -2
- package/dist/src/tflite.d.ts +0 -1
- package/package.json +3 -3
- package/src/createRenderer.ts +9 -4
- package/src/webgl2/backgroundBlurStage.ts +19 -11
- package/src/webgl2/webgl2Pipeline.ts +1 -0
package/dist/index.es.js
CHANGED
|
@@ -131,11 +131,21 @@ function buildBackgroundBlurStage(gl, vertexShader, positionBuffer, texCoordBuff
|
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
133
|
function buildBlurPass(gl, vertexShader, positionBuffer, texCoordBuffer, personMaskTexture, canvas, blurLevel) {
|
|
134
|
-
const
|
|
135
|
-
?
|
|
136
|
-
: blurLevel === '
|
|
137
|
-
?
|
|
138
|
-
:
|
|
134
|
+
const sigma = typeof blurLevel === 'number'
|
|
135
|
+
? blurLevel
|
|
136
|
+
: blurLevel === 'low'
|
|
137
|
+
? 2
|
|
138
|
+
: blurLevel === 'medium'
|
|
139
|
+
? 4
|
|
140
|
+
: 6;
|
|
141
|
+
const windowSize = Math.max(1, Math.floor(sigma * 3));
|
|
142
|
+
const offset = new Array(windowSize).fill(0).map((v, index) => index);
|
|
143
|
+
const variance = sigma ** 2;
|
|
144
|
+
const weights = offset.map((x) => {
|
|
145
|
+
var m = sigma * Math.sqrt(2 * Math.PI);
|
|
146
|
+
var e = Math.exp(-(x ** 2) / (2 * variance));
|
|
147
|
+
return e / m;
|
|
148
|
+
});
|
|
139
149
|
const fragmentShaderSource = glsl `#version 300 es
|
|
140
150
|
|
|
141
151
|
precision highp float;
|
|
@@ -147,10 +157,8 @@ function buildBlurPass(gl, vertexShader, positionBuffer, texCoordBuffer, personM
|
|
|
147
157
|
in vec2 v_texCoord;
|
|
148
158
|
out vec4 outColor;
|
|
149
159
|
|
|
150
|
-
const float offset[
|
|
151
|
-
const float weight[
|
|
152
|
-
${weights.join(',')}
|
|
153
|
-
);
|
|
160
|
+
const float offset[${windowSize}] = float[](${offset.map((i) => i.toFixed(10)).join(', ')});
|
|
161
|
+
const float weight[${windowSize}] = float[](${weights.map((i) => i.toFixed(10)).join(', ')});
|
|
154
162
|
|
|
155
163
|
void main() {
|
|
156
164
|
vec4 centerColor = texture(u_inputFrame, v_texCoord);
|
|
@@ -158,7 +166,7 @@ function buildBlurPass(gl, vertexShader, positionBuffer, texCoordBuffer, personM
|
|
|
158
166
|
|
|
159
167
|
vec4 frameColor = centerColor * weight[0] * (1.0 - personMask);
|
|
160
168
|
|
|
161
|
-
for (int i = 1; i <
|
|
169
|
+
for (int i = 1; i < ${windowSize}; i++) {
|
|
162
170
|
vec2 offset = vec2(offset[i]) * u_texelSize;
|
|
163
171
|
|
|
164
172
|
vec2 texCoord = v_texCoord + offset;
|
|
@@ -665,6 +673,8 @@ function buildWebGL2Pipeline(videoSource, backgroundImage, blurLevel, background
|
|
|
665
673
|
const gl = canvas.getContext('webgl2');
|
|
666
674
|
if (!gl)
|
|
667
675
|
throw new Error('WebGL2 is not supported');
|
|
676
|
+
if (gl.isContextLost())
|
|
677
|
+
throw new Error('WebGL2 context was lost');
|
|
668
678
|
const { width: frameWidth, height: frameHeight } = videoSource;
|
|
669
679
|
const { width: segmentationWidth, height: segmentationHeight } = segmentationConfig;
|
|
670
680
|
const vertexShaderSource = glsl `#version 300 es
|
|
@@ -767,16 +777,21 @@ const getSegmentationParams = (level) => {
|
|
|
767
777
|
return { width: 160, height: 96 };
|
|
768
778
|
};
|
|
769
779
|
|
|
770
|
-
function createRenderer(tflite, videoSource, targetCanvas, options) {
|
|
780
|
+
function createRenderer(tflite, videoSource, targetCanvas, options, onError) {
|
|
771
781
|
const { backgroundFilter, backgroundImage, backgroundBlurLevel, segmentationLevel = SegmentationLevel.HIGH, fps = 30, } = options;
|
|
772
782
|
if (backgroundFilter === 'image' && !backgroundImage) {
|
|
773
783
|
throw new Error(`backgroundImage element is required when backgroundFilter is image`);
|
|
774
784
|
}
|
|
775
785
|
const pipeline = buildWebGL2Pipeline(videoSource, backgroundImage, backgroundBlurLevel, backgroundFilter, targetCanvas, tflite, getSegmentationParams(segmentationLevel));
|
|
776
786
|
const id = setInterval(() => {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
787
|
+
try {
|
|
788
|
+
pipeline.render();
|
|
789
|
+
if (backgroundFilter === 'image') {
|
|
790
|
+
pipeline.updatePostProcessingConfig();
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
catch (error) {
|
|
794
|
+
onError?.(error);
|
|
780
795
|
}
|
|
781
796
|
}, 1000 / (fps <= 0 ? 30 : fps));
|
|
782
797
|
return {
|
|
@@ -1521,7 +1536,7 @@ const createTFLiteSIMDModule = (__Module) => {
|
|
|
1521
1536
|
return __Module.ready;
|
|
1522
1537
|
};
|
|
1523
1538
|
|
|
1524
|
-
const version = "0.1.
|
|
1539
|
+
const version = "0.1.3" ;
|
|
1525
1540
|
const packageName = "@stream-io/video-filters-web" ;
|
|
1526
1541
|
|
|
1527
1542
|
// @ts-expect-error - module is not declared
|