@pexip/media-processor 20.3.5 → 22.0.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.
Files changed (201) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/README.md +17 -10
  3. package/api-docs/README.mdx +69 -23
  4. package/api-docs/functions/assertMediaStreamVideoTrack.mdx +13 -0
  5. package/api-docs/functions/createBenchmark.mdx +17 -5
  6. package/api-docs/functions/createFrameCallbackRequest.mdx +8 -2
  7. package/api-docs/functions/createMediaStreamTrackInputProcessAdaptor.mdx +10 -0
  8. package/api-docs/functions/createReadWritableStreamFallbackInputProcessAdaptor.mdx +17 -0
  9. package/api-docs/functions/createReadWritableStreamInputProcessAdaptor.mdx +10 -0
  10. package/api-docs/functions/createVideoProcessor.mdx +3 -3
  11. package/api-docs/functions/createWindowedStats.mdx +23 -0
  12. package/api-docs/functions/getDefaultInputProcessAdaptor.mdx +17 -0
  13. package/api-docs/functions/iou.mdx +19 -0
  14. package/api-docs/functions/isMediaStreamVideoTrack.mdx +13 -0
  15. package/api-docs/functions/labelComponents.mdx +20 -0
  16. package/api-docs/functions/nearestPowerOfTwo.mdx +21 -0
  17. package/api-docs/functions/playVideo.mdx +16 -0
  18. package/api-docs/functions/scoreComponent.mdx +22 -0
  19. package/api-docs/functions/setVideoElementSrc.mdx +14 -0
  20. package/api-docs/interfaces/Analyzer.mdx +4 -0
  21. package/api-docs/interfaces/Benchmark.mdx +26 -2
  22. package/api-docs/interfaces/FrameTransformStats.mdx +9 -0
  23. package/api-docs/interfaces/Gain.mdx +4 -0
  24. package/api-docs/interfaces/ImageSegmenterOptions.mdx +0 -2
  25. package/api-docs/interfaces/InputProcessAdaptor.mdx +28 -0
  26. package/api-docs/interfaces/Process.mdx +8 -3
  27. package/api-docs/interfaces/ProcessEventMute.mdx +6 -0
  28. package/api-docs/interfaces/ProcessWorkerEventOpened.mdx +7 -0
  29. package/api-docs/interfaces/ProcessWorkerEventStats.mdx +6 -0
  30. package/api-docs/interfaces/ProcessWorkerEventUpdated.mdx +7 -0
  31. package/api-docs/interfaces/ProcessorEvent.mdx +1 -1
  32. package/api-docs/interfaces/ProcessorOptions.mdx +0 -1
  33. package/api-docs/interfaces/ProcessorProcessOptions.mdx +3 -1
  34. package/api-docs/interfaces/ProcessorUpdateOptions.mdx +15 -0
  35. package/api-docs/interfaces/ReadWritableStream.mdx +12 -0
  36. package/api-docs/interfaces/Renderer.mdx +2 -2
  37. package/api-docs/interfaces/RendererOptions.mdx +25 -12
  38. package/api-docs/interfaces/Segmenter.mdx +89 -10
  39. package/api-docs/interfaces/SegmenterOptions.mdx +0 -1
  40. package/api-docs/interfaces/SelectionOptions.mdx +15 -0
  41. package/api-docs/interfaces/Stats.mdx +11 -0
  42. package/api-docs/interfaces/VideoProcessor.mdx +49 -5
  43. package/api-docs/interfaces/Weights.mdx +12 -0
  44. package/api-docs/type-aliases/OptionalKeys.mdx +10 -0
  45. package/api-docs/type-aliases/ProcessEvents.mdx +1 -0
  46. package/api-docs/type-aliases/ProcessInputType.mdx +3 -1
  47. package/api-docs/type-aliases/ProcessWorkerEvents.mdx +6 -4
  48. package/api-docs/type-aliases/ProcessorWorkerEvents.mdx +1 -1
  49. package/api-docs/type-aliases/Struct.mdx +9 -0
  50. package/api-docs/variables/BACKGROUND_THRESHOLD.mdx +3 -0
  51. package/api-docs/variables/DOWN_SAMPLE_FACTOR.mdx +3 -0
  52. package/api-docs/variables/EDGE_BLUR_AMOUNT.mdx +1 -1
  53. package/api-docs/variables/EXCLUDE_BYSTANDERS.mdx +3 -0
  54. package/api-docs/variables/FOREGROUND_THRESHOLD.mdx +1 -1
  55. package/api-docs/variables/FRAME_RATE.mdx +1 -1
  56. package/api-docs/variables/ImageFetchError.mdx +3 -0
  57. package/api-docs/variables/LIGHT_WRAP_BLUR_AMOUNT.mdx +3 -0
  58. package/api-docs/variables/LIGHT_WRAP_EDGE_BAND.mdx +3 -0
  59. package/api-docs/variables/LIGHT_WRAP_INTENSITY.mdx +3 -0
  60. package/api-docs/variables/LIGHT_WRAP_TIGHTNESS.mdx +3 -0
  61. package/api-docs/variables/MASK_COMBINE_RATIO.mdx +1 -1
  62. package/api-docs/variables/MORPH_DILATE_RADIUS_PX.mdx +3 -0
  63. package/api-docs/variables/MORPH_ERODE_RADIUS_PX.mdx +3 -0
  64. package/api-docs/variables/MORPH_PASS.mdx +3 -0
  65. package/api-docs/variables/MediaStreamTrackTransferable.mdx +5 -0
  66. package/api-docs/variables/PERSON_CENTER.mdx +3 -0
  67. package/api-docs/variables/RENDERER_OPTIONS_STRUCT.mdx +3 -0
  68. package/api-docs/variables/SIGMA_RANGE.mdx +3 -0
  69. package/api-docs/variables/SIGMA_SPACE.mdx +3 -0
  70. package/api-docs/variables/STRONG_EDGE_BLUR_AMOUNT.mdx +3 -0
  71. package/api-docs/variables/cloneImageRecord.mdx +19 -0
  72. package/api-docs/variables/compareImageRecords.mdx +18 -0
  73. package/api-docs/variables/createRemoteImageBitmap.mdx +1 -1
  74. package/api-docs/variables/getCanvasRenderingContext2D.mdx +14 -0
  75. package/api-docs/variables/getImageSize.mdx +13 -0
  76. package/api-docs/variables/isRenderOptionsKey.mdx +13 -0
  77. package/api-docs/variables/isValidGpuAPI.mdx +13 -0
  78. package/dist/common/backends/webgl/binaryMask.d.ts +8 -0
  79. package/dist/common/backends/webgl/binaryMask.js +95 -0
  80. package/dist/common/backends/webgl/blender.d.ts +2 -1
  81. package/dist/common/backends/webgl/blender.js +18 -15
  82. package/dist/common/backends/webgl/blur.d.ts +1 -1
  83. package/dist/common/backends/webgl/blur.js +23 -16
  84. package/dist/common/backends/webgl/canvas.js +9 -4
  85. package/dist/common/backends/webgl/diffAbsMask.d.ts +10 -0
  86. package/dist/common/backends/webgl/diffAbsMask.js +103 -0
  87. package/dist/common/backends/webgl/geodesicReconstruction.d.ts +13 -0
  88. package/dist/common/backends/webgl/geodesicReconstruction.js +176 -0
  89. package/dist/common/backends/webgl/jointBilateralFilter.d.ts +12 -0
  90. package/dist/common/backends/webgl/jointBilateralFilter.js +108 -0
  91. package/dist/common/backends/webgl/morphErode.d.ts +13 -0
  92. package/dist/common/backends/webgl/morphErode.js +121 -0
  93. package/dist/common/backends/webgl/renderer.js +194 -44
  94. package/dist/common/backends/webgl/replace.d.ts +17 -0
  95. package/dist/common/backends/webgl/replace.js +126 -0
  96. package/dist/common/backends/webgl/selectComponent.d.ts +15 -0
  97. package/dist/common/backends/webgl/selectComponent.js +102 -0
  98. package/dist/common/backends/webgl/smoothingMask.d.ts +3 -3
  99. package/dist/common/backends/webgl/smoothingMask.js +22 -21
  100. package/dist/common/backends/webgl/tentBlur.d.ts +9 -0
  101. package/dist/common/backends/webgl/tentBlur.js +118 -0
  102. package/dist/common/backends/webgl/texture.d.ts +2 -3
  103. package/dist/common/backends/webgl/texture.js +21 -19
  104. package/dist/common/backends/webgl/textureToTexture.d.ts +1 -1
  105. package/dist/common/backends/webgl/textureToTexture.js +19 -16
  106. package/dist/common/backends/webgl/webglUtils.d.ts +7 -1
  107. package/dist/common/backends/webgl/webglUtils.js +72 -10
  108. package/dist/common/backends/webgpu/blender.d.ts +6 -1
  109. package/dist/common/backends/webgpu/blender.js +96 -51
  110. package/dist/common/backends/webgpu/constants.js +1 -1
  111. package/dist/common/backends/webgpu/dualFilterBlur.d.ts +2 -3
  112. package/dist/common/backends/webgpu/dualFilterBlur.js +146 -140
  113. package/dist/common/backends/webgpu/jointBilateralFilter.d.ts +7 -0
  114. package/dist/common/backends/webgpu/jointBilateralFilter.js +162 -0
  115. package/dist/common/backends/webgpu/renderer.js +205 -43
  116. package/dist/common/backends/webgpu/replace.d.ts +11 -0
  117. package/dist/common/backends/webgpu/replace.js +175 -0
  118. package/dist/common/backends/webgpu/resize.d.ts +4 -0
  119. package/dist/common/backends/webgpu/resize.js +76 -0
  120. package/dist/common/backends/webgpu/smoothingMask.d.ts +2 -2
  121. package/dist/common/backends/webgpu/smoothingMask.js +74 -40
  122. package/dist/common/backends/webgpu/tentBlur.d.ts +5 -0
  123. package/dist/common/backends/webgpu/tentBlur.js +131 -0
  124. package/dist/common/backends/webgpu/texture.d.ts +2 -3
  125. package/dist/common/backends/webgpu/texture.js +29 -20
  126. package/dist/common/backends/webgpu/textureToTexture.d.ts +1 -1
  127. package/dist/common/backends/webgpu/textureToTexture.js +28 -15
  128. package/dist/common/backends/webgpu/types.d.ts +2 -0
  129. package/dist/common/backends/webgpu/webgpuUtils.d.ts +24 -4
  130. package/dist/common/backends/webgpu/webgpuUtils.js +60 -11
  131. package/dist/common/constants.d.ts +22 -5
  132. package/dist/common/constants.js +23 -5
  133. package/dist/common/index.d.ts +2 -0
  134. package/dist/common/index.js +2 -0
  135. package/dist/common/tsconfig.tsbuildinfo +1 -1
  136. package/dist/common/typeGuards.d.ts +2 -0
  137. package/dist/common/typeGuards.js +7 -0
  138. package/dist/common/types/media.d.ts +5 -1
  139. package/dist/common/types/messageEvents.d.ts +31 -4
  140. package/dist/common/types/processor.d.ts +6 -4
  141. package/dist/common/types/render.d.ts +147 -15
  142. package/dist/common/types/render.js +23 -1
  143. package/dist/common/types/segmentation.d.ts +0 -12
  144. package/dist/common/types/utils.d.ts +21 -0
  145. package/dist/common/utils.d.ts +29 -2
  146. package/dist/common/utils.js +206 -10
  147. package/dist/main/audio.js +3 -3
  148. package/dist/main/benchUtils.d.ts +35 -3
  149. package/dist/main/benchUtils.js +149 -15
  150. package/dist/main/index.d.ts +1 -1
  151. package/dist/main/index.js +1 -1
  152. package/dist/main/tsconfig.tsbuildinfo +1 -1
  153. package/dist/main/types.d.ts +0 -6
  154. package/dist/main/utils.d.ts +4 -0
  155. package/dist/main/utils.js +31 -0
  156. package/dist/main/video/constants.d.ts +1 -4
  157. package/dist/main/video/constants.js +1 -5
  158. package/dist/main/video/index.d.ts +3 -4
  159. package/dist/main/video/index.js +3 -4
  160. package/dist/main/video/inputProcessAdaptor.d.ts +30 -0
  161. package/dist/main/video/inputProcessAdaptor.js +198 -0
  162. package/dist/main/video/segmenter.d.ts +35 -0
  163. package/dist/main/video/{segmenters/mediapipe.js → segmenter.js} +93 -53
  164. package/dist/main/video/typeGuards.d.ts +2 -0
  165. package/dist/main/video/typeGuards.js +8 -1
  166. package/dist/main/video/types.d.ts +36 -16
  167. package/dist/main/video/utils.d.ts +5 -4
  168. package/dist/main/video/utils.js +49 -44
  169. package/dist/main/video/video.d.ts +29 -7
  170. package/dist/main/video/video.js +323 -28
  171. package/dist/workers/mediaWorker.js +35 -162
  172. package/dist/workers/tsconfig.tsbuildinfo +1 -1
  173. package/dist/worklets/tsconfig.tsbuildinfo +1 -1
  174. package/package.json +13 -12
  175. package/api-docs/functions/createCanvasTransform.mdx +0 -14
  176. package/api-docs/functions/createVideoTrackProcessor.mdx +0 -9
  177. package/api-docs/functions/createVideoTrackProcessorWithFallback.mdx +0 -15
  178. package/api-docs/interfaces/Detector.mdx +0 -81
  179. package/api-docs/interfaces/SegmentationParams.mdx +0 -18
  180. package/api-docs/interfaces/Transform.mdx +0 -62
  181. package/api-docs/type-aliases/ProcessVideoTrack.mdx +0 -15
  182. package/api-docs/type-aliases/SegmentationTransform.mdx +0 -3
  183. package/dist/common/backends/webgl/shaders/blendFragmentShader.d.ts +0 -1
  184. package/dist/common/backends/webgl/shaders/blendFragmentShader.js +0 -21
  185. package/dist/common/backends/webgl/shaders/dualFilterBlurFragmentShader.d.ts +0 -1
  186. package/dist/common/backends/webgl/shaders/dualFilterBlurFragmentShader.js +0 -45
  187. package/dist/common/backends/webgl/shaders/smoothingMaskFragmentShader.d.ts +0 -1
  188. package/dist/common/backends/webgl/shaders/smoothingMaskFragmentShader.js +0 -57
  189. package/dist/common/backends/webgl/shaders/textureFragmentShader.d.ts +0 -1
  190. package/dist/common/backends/webgl/shaders/textureFragmentShader.js +0 -16
  191. package/dist/common/backends/webgl/shaders/vertexShader.d.ts +0 -1
  192. package/dist/common/backends/webgl/shaders/vertexShader.js +0 -19
  193. package/dist/main/transformer.d.ts +0 -1
  194. package/dist/main/transformer.js +0 -4
  195. package/dist/main/video/canvasTransform.d.ts +0 -17
  196. package/dist/main/video/canvasTransform.js +0 -253
  197. package/dist/main/video/segmenters/mediapipe.d.ts +0 -22
  198. package/dist/main/video/transformer.d.ts +0 -9
  199. package/dist/main/video/transformer.js +0 -68
  200. package/dist/main/video/videoStreamTrackProcessor.d.ts +0 -20
  201. package/dist/main/video/videoStreamTrackProcessor.js +0 -86
@@ -1,21 +0,0 @@
1
- export const blendFragmentShaderSource = `#version 300 es
2
- precision mediump float;
3
-
4
- // our textures
5
- uniform sampler2D u_mask;
6
- uniform sampler2D u_frame_foreground;
7
- uniform sampler2D u_frame_background;
8
-
9
- in vec2 v_texCoord;
10
-
11
- // we need to declare an output for the fragment shader
12
- out vec4 outColor;
13
-
14
- void main() {
15
- vec4 background = texture(u_frame_background, v_texCoord);
16
- vec4 foreground = texture(u_frame_foreground, v_texCoord);
17
- float filteredMask = texture(u_mask, v_texCoord).r;
18
-
19
- outColor = mix(background, foreground, filteredMask);
20
- }
21
- `;
@@ -1 +0,0 @@
1
- export declare const dualFilterBlurFragmentShaderSource = "#version 300 es\nprecision mediump float;\n\n// our textures\nuniform sampler2D u_frame;\n\n// control flags\nuniform int u_downsampling;\n\nin vec2 v_texCoord;\n\n// we need to declare an output for the fragment shader\nout vec4 outColor;\n\nvec4 Downsample(sampler2D image, vec2 uv, vec2 halfpixel) {\n vec4 sum = texture(image, uv) * 4.0;\n sum += texture(image, uv - halfpixel.xy);\n sum += texture(image, uv + halfpixel.xy);\n sum += texture(image, uv + vec2(halfpixel.x, -halfpixel.y));\n sum += texture(image, uv - vec2(halfpixel.x, -halfpixel.y));\n return sum / 8.0;\n}\n\nvec4 Upsample(sampler2D image, vec2 uv, vec2 halfpixel) {\n vec4 sum = texture(image, uv + vec2(-halfpixel.x * 2.0, 0.0));\n sum += texture(image, uv + vec2(-halfpixel.x, halfpixel.y)) * 2.0;\n sum += texture(image, uv + vec2(0.0, halfpixel.y * 2.0));\n sum += texture(image, uv + vec2(halfpixel.x, halfpixel.y)) * 2.0;\n sum += texture(image, uv + vec2(halfpixel.x * 2.0, 0.0));\n sum += texture(image, uv + vec2(halfpixel.x, -halfpixel.y)) * 2.0;\n sum += texture(image, uv + vec2(0.0, -halfpixel.y * 2.0));\n sum += texture(image, uv + vec2(-halfpixel.x, -halfpixel.y)) * 2.0;\n return sum / 12.0;\n}\n\nvoid main() {\n vec2 halfpixel = 0.5 / vec2(textureSize(u_frame, 0));\n\n if (u_downsampling == 1) {\n outColor = Downsample(u_frame, v_texCoord, halfpixel);\n return;\n }\n outColor = Upsample(u_frame, v_texCoord, halfpixel);\n}\n";
@@ -1,45 +0,0 @@
1
- export const dualFilterBlurFragmentShaderSource = `#version 300 es
2
- precision mediump float;
3
-
4
- // our textures
5
- uniform sampler2D u_frame;
6
-
7
- // control flags
8
- uniform int u_downsampling;
9
-
10
- in vec2 v_texCoord;
11
-
12
- // we need to declare an output for the fragment shader
13
- out vec4 outColor;
14
-
15
- vec4 Downsample(sampler2D image, vec2 uv, vec2 halfpixel) {
16
- vec4 sum = texture(image, uv) * 4.0;
17
- sum += texture(image, uv - halfpixel.xy);
18
- sum += texture(image, uv + halfpixel.xy);
19
- sum += texture(image, uv + vec2(halfpixel.x, -halfpixel.y));
20
- sum += texture(image, uv - vec2(halfpixel.x, -halfpixel.y));
21
- return sum / 8.0;
22
- }
23
-
24
- vec4 Upsample(sampler2D image, vec2 uv, vec2 halfpixel) {
25
- vec4 sum = texture(image, uv + vec2(-halfpixel.x * 2.0, 0.0));
26
- sum += texture(image, uv + vec2(-halfpixel.x, halfpixel.y)) * 2.0;
27
- sum += texture(image, uv + vec2(0.0, halfpixel.y * 2.0));
28
- sum += texture(image, uv + vec2(halfpixel.x, halfpixel.y)) * 2.0;
29
- sum += texture(image, uv + vec2(halfpixel.x * 2.0, 0.0));
30
- sum += texture(image, uv + vec2(halfpixel.x, -halfpixel.y)) * 2.0;
31
- sum += texture(image, uv + vec2(0.0, -halfpixel.y * 2.0));
32
- sum += texture(image, uv + vec2(-halfpixel.x, -halfpixel.y)) * 2.0;
33
- return sum / 12.0;
34
- }
35
-
36
- void main() {
37
- vec2 halfpixel = 0.5 / vec2(textureSize(u_frame, 0));
38
-
39
- if (u_downsampling == 1) {
40
- outColor = Downsample(u_frame, v_texCoord, halfpixel);
41
- return;
42
- }
43
- outColor = Upsample(u_frame, v_texCoord, halfpixel);
44
- }
45
- `;
@@ -1 +0,0 @@
1
- export declare const smoothingMaskFragmentShaderSource = "#version 300 es\nprecision mediump float;\n\n// our textures\nuniform sampler2D u_mask;\nuniform sampler2D u_mask_prev;\n\n// control flags\nuniform float u_mask_combine_ratio;\nuniform float u_foreground_threshold;\n\nin vec2 v_texCoord;\n\n// we need to declare an output for the fragment shader\nout vec4 outColor;\n\n// Source: https://github.com/google/mediapipe/blob/8750c3dca1bc00fbe47acf501b7c9c61f3f3bd3f/mediapipe/calculators/image/segmentation_smoothing_calculator.cc#L377\nfloat SmoothingMask(sampler2D prevMask, sampler2D currMask, vec2 uv, float ratio) {\n float prevMaskValue = texture(prevMask, uv).r;\n float newMaskValue = texture(currMask, uv).r;\n\n /*\n * Assume p := newMaskValue\n * H(p) := 1 + (p * log(p) + (1-p) * log(1-p)) / log(2)\n * uncertainty alpha(p) =\n * Clamp(1 - (1 - H(p)) * (1 - H(p)), 0, 1) [squaring the\n * uncertainty]\n *\n * The following polynomial approximates uncertainty alpha as a\n * function of (p + 0.5):\n */\n const float c1 = 5.68842;\n const float c2 = -0.748699;\n const float c3 = -57.8051;\n const float c4 = 291.309;\n const float c5 = -624.717;\n float t = newMaskValue - 0.5;\n float x = t * t;\n\n float uncertainty =\n 1.0 - min(1.0, x * (c1 + x * (c2 + x * (c3 + x * (c4 + x * c5)))));\n\n float outputValue = newMaskValue + (prevMaskValue - newMaskValue) *\n (uncertainty * ratio);\n return outputValue;\n}\n\nvoid main() {\n float maskAlpha = SmoothingMask(u_mask_prev, u_mask, v_texCoord, u_mask_combine_ratio);\n float backgroundMask = maskAlpha;\n if (backgroundMask < u_foreground_threshold) {\n backgroundMask = 0.0;\n }\n\n outColor = vec4(backgroundMask, backgroundMask, backgroundMask, backgroundMask);\n}\n";
@@ -1,57 +0,0 @@
1
- export const smoothingMaskFragmentShaderSource = `#version 300 es
2
- precision mediump float;
3
-
4
- // our textures
5
- uniform sampler2D u_mask;
6
- uniform sampler2D u_mask_prev;
7
-
8
- // control flags
9
- uniform float u_mask_combine_ratio;
10
- uniform float u_foreground_threshold;
11
-
12
- in vec2 v_texCoord;
13
-
14
- // we need to declare an output for the fragment shader
15
- out vec4 outColor;
16
-
17
- // Source: https://github.com/google/mediapipe/blob/8750c3dca1bc00fbe47acf501b7c9c61f3f3bd3f/mediapipe/calculators/image/segmentation_smoothing_calculator.cc#L377
18
- float SmoothingMask(sampler2D prevMask, sampler2D currMask, vec2 uv, float ratio) {
19
- float prevMaskValue = texture(prevMask, uv).r;
20
- float newMaskValue = texture(currMask, uv).r;
21
-
22
- /*
23
- * Assume p := newMaskValue
24
- * H(p) := 1 + (p * log(p) + (1-p) * log(1-p)) / log(2)
25
- * uncertainty alpha(p) =
26
- * Clamp(1 - (1 - H(p)) * (1 - H(p)), 0, 1) [squaring the
27
- * uncertainty]
28
- *
29
- * The following polynomial approximates uncertainty alpha as a
30
- * function of (p + 0.5):
31
- */
32
- const float c1 = 5.68842;
33
- const float c2 = -0.748699;
34
- const float c3 = -57.8051;
35
- const float c4 = 291.309;
36
- const float c5 = -624.717;
37
- float t = newMaskValue - 0.5;
38
- float x = t * t;
39
-
40
- float uncertainty =
41
- 1.0 - min(1.0, x * (c1 + x * (c2 + x * (c3 + x * (c4 + x * c5)))));
42
-
43
- float outputValue = newMaskValue + (prevMaskValue - newMaskValue) *
44
- (uncertainty * ratio);
45
- return outputValue;
46
- }
47
-
48
- void main() {
49
- float maskAlpha = SmoothingMask(u_mask_prev, u_mask, v_texCoord, u_mask_combine_ratio);
50
- float backgroundMask = maskAlpha;
51
- if (backgroundMask < u_foreground_threshold) {
52
- backgroundMask = 0.0;
53
- }
54
-
55
- outColor = vec4(backgroundMask, backgroundMask, backgroundMask, backgroundMask);
56
- }
57
- `;
@@ -1 +0,0 @@
1
- export declare const textureFragmentShaderSource = "#version 300 es\nprecision mediump float;\n\n// Passed in from the vertex shader.\nin vec2 v_texCoord;\n\n// The texture.\nuniform sampler2D u_texture;\n\n// we need to declare an output for the fragment shader\nout vec4 outColor;\n\nvoid main() {\n outColor = texture(u_texture, v_texCoord);\n}\n";
@@ -1,16 +0,0 @@
1
- export const textureFragmentShaderSource = `#version 300 es
2
- precision mediump float;
3
-
4
- // Passed in from the vertex shader.
5
- in vec2 v_texCoord;
6
-
7
- // The texture.
8
- uniform sampler2D u_texture;
9
-
10
- // we need to declare an output for the fragment shader
11
- out vec4 outColor;
12
-
13
- void main() {
14
- outColor = texture(u_texture, v_texCoord);
15
- }
16
- `;
@@ -1 +0,0 @@
1
- export declare const vertexShaderSource = "#version 300 es\n// an attribute is an input (in) to a vertex shader.\n// It will receive data from a buffer\nin vec2 a_position;\nin vec2 a_texCoord;\n\n// Used to pass in the resolution of the canvas\nuniform mat3 u_matrix;\n\n// Used to pass the texture coordinates to the fragment shader\nout vec2 v_texCoord;\n\nvoid main() {\n gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);\n\n // pass the texCoord to the fragment shader\n v_texCoord = a_texCoord;\n}\n";
@@ -1,19 +0,0 @@
1
- export const vertexShaderSource = `#version 300 es
2
- // an attribute is an input (in) to a vertex shader.
3
- // It will receive data from a buffer
4
- in vec2 a_position;
5
- in vec2 a_texCoord;
6
-
7
- // Used to pass in the resolution of the canvas
8
- uniform mat3 u_matrix;
9
-
10
- // Used to pass the texture coordinates to the fragment shader
11
- out vec2 v_texCoord;
12
-
13
- void main() {
14
- gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
15
-
16
- // pass the texCoord to the fragment shader
17
- v_texCoord = a_texCoord;
18
- }
19
- `;
@@ -1 +0,0 @@
1
- export declare const createStreamTransformer: <I, O>(transformer?: Transformer<I, O>, writableStrategy?: QueuingStrategy<I>, readableStrategy?: QueuingStrategy<O>) => TransformStream<I, O>;
@@ -1,4 +0,0 @@
1
- export const createStreamTransformer = (transformer, writableStrategy, readableStrategy) => {
2
- const transformStream = new TransformStream(transformer, writableStrategy, readableStrategy);
3
- return transformStream;
4
- };
@@ -1,17 +0,0 @@
1
- import type { ImageRecord } from '../../common/types/media';
2
- import type { RendererOptions } from '../../common/types/render';
3
- import type { Segmenter, SegmentationTransform } from './types';
4
- interface Options extends RendererOptions {
5
- selfManageSegmenter?: boolean;
6
- outputCanvas?: HTMLCanvasElement;
7
- outputDelegate?: OffscreenCanvas;
8
- backgroundImage?: ImageRecord;
9
- width?: number;
10
- height?: number;
11
- }
12
- export declare const createTransform: (segmenter: Segmenter, { width, height, foregroundThreshold, backgroundBlurAmount, edgeBlurAmount, maskCombineRatio, backgroundImageUrl, effects, backend, selfManageSegmenter, ...options }?: Partial<Options>) => SegmentationTransform & {
13
- outputCanvas: HTMLCanvasElement | undefined;
14
- outputDelegate: OffscreenCanvas | undefined;
15
- backgroundImage?: ImageRecord;
16
- };
17
- export {};
@@ -1,253 +0,0 @@
1
- import { PROCESSING_HEIGHT, PROCESSING_WIDTH, FOREGROUND_THRESHOLD, BACKGROUND_BLUR_AMOUNT, EDGE_BLUR_AMOUNT, MASK_COMBINE_RATIO, } from '../../common/constants';
2
- import { createCanvasRenderUtils } from '../../common/canvasRenderUtils';
3
- import { clamping, createObjectUpdater } from '../../common/utils';
4
- import { assert } from '@pexip/utils';
5
- const clampInRangeFrom0To1 = clamping(0, 1);
6
- const clampInRangeFrom0To9 = clamping(0, 9);
7
- export const createTransform = (segmenter, { width = PROCESSING_WIDTH, height = PROCESSING_HEIGHT, foregroundThreshold = FOREGROUND_THRESHOLD, backgroundBlurAmount = BACKGROUND_BLUR_AMOUNT, edgeBlurAmount = EDGE_BLUR_AMOUNT, maskCombineRatio = MASK_COMBINE_RATIO, backgroundImageUrl = '', effects = 'none', backend = 'webgl', selfManageSegmenter, ...options } = {}) => {
8
- const props = {
9
- segmenter,
10
- processingWidth: width,
11
- processingHeight: height,
12
- foregroundThreshold,
13
- backgroundBlurAmount,
14
- edgeBlurAmount,
15
- utils: undefined,
16
- effects,
17
- maskCombineRatio,
18
- backgroundImage: options.backgroundImage,
19
- status: 'new',
20
- backgroundImageUrl,
21
- outputCanvas: options.outputCanvas,
22
- outputDelegate: options.outputDelegate,
23
- backend,
24
- unsubscribe: null,
25
- };
26
- const updateProps = createObjectUpdater(props);
27
- const handleContextRestored = () => {
28
- assert(props.utils);
29
- props.utils.reset();
30
- };
31
- const toVideoFrameLike = (input) => {
32
- // Standardize the input
33
- assert(props.utils);
34
- const image = input instanceof ImageData
35
- ? props.utils.renderImageDataToOffScreenCanvas(input, 'drawImageDataCanvas')
36
- : input;
37
- // Pre-precessing the input to resize to the processing size
38
- const canvas = props.utils.renderImageToOffScreenCanvas(image, 'inputCanvas');
39
- if ('close' in input) {
40
- input.close();
41
- }
42
- return {
43
- frame: canvas.transferToImageBitmap(),
44
- width: props.processingWidth,
45
- height: props.processingHeight,
46
- timestamp: performance.now(),
47
- };
48
- };
49
- const processInput = async (input) => {
50
- const renderOptions = {
51
- foregroundThreshold: props.foregroundThreshold,
52
- backgroundBlurAmount: props.backgroundBlurAmount,
53
- edgeBlurAmount: props.edgeBlurAmount,
54
- maskCombineRatio: props.maskCombineRatio,
55
- backgroundImageUrl: props.backgroundImageUrl,
56
- effects: props.effects,
57
- backend: props.backend,
58
- };
59
- if (props.segmenter.status === 'new' ||
60
- props.segmenter.status === 'closed') {
61
- await props.segmenter.open({
62
- output: props.outputDelegate,
63
- processingWidth: props.processingWidth,
64
- processingHeight: props.processingHeight,
65
- backgroundImage: props.backgroundImage,
66
- renderOptions,
67
- });
68
- }
69
- if (!props.utils) {
70
- props.utils = createCanvasRenderUtils(props.processingWidth, props.processingHeight);
71
- }
72
- if (props.segmenter.status === 'opening') {
73
- return undefined;
74
- }
75
- const inputFrame = toVideoFrameLike(input);
76
- return props.segmenter.process(inputFrame, renderOptions);
77
- };
78
- const canUpdate = () => props.segmenter.status !== 'new' &&
79
- props.segmenter.status !== 'closed' &&
80
- props.segmenter.status !== 'closing';
81
- const updateProcessingDimensions = (width, height) => {
82
- let newDimensions = false;
83
- if (width && props.processingWidth !== width) {
84
- props.processingWidth = width;
85
- newDimensions = true;
86
- }
87
- if (height && props.processingHeight !== height) {
88
- props.processingHeight = height;
89
- newDimensions = true;
90
- }
91
- if (newDimensions) {
92
- props.utils = createCanvasRenderUtils(props.processingWidth, props.processingHeight);
93
- }
94
- };
95
- return {
96
- get width() {
97
- return props.processingWidth;
98
- },
99
- get height() {
100
- return props.processingHeight;
101
- },
102
- get status() {
103
- return props.status;
104
- },
105
- get foregroundThreshold() {
106
- return props.foregroundThreshold;
107
- },
108
- get backgroundBlurAmount() {
109
- return props.backgroundBlurAmount;
110
- },
111
- get edgeBlurAmount() {
112
- return props.edgeBlurAmount;
113
- },
114
- get effects() {
115
- return props.effects;
116
- },
117
- get maskCombineRatio() {
118
- return props.maskCombineRatio;
119
- },
120
- get backend() {
121
- return props.backend;
122
- },
123
- set foregroundThreshold(value) {
124
- props.foregroundThreshold = clampInRangeFrom0To1(value);
125
- },
126
- set backgroundBlurAmount(value) {
127
- props.backgroundBlurAmount = clampInRangeFrom0To9(value);
128
- },
129
- set edgeBlurAmount(value) {
130
- props.edgeBlurAmount = clampInRangeFrom0To9(value);
131
- },
132
- set effects(value) {
133
- props.effects = value;
134
- },
135
- set backgroundImageUrl(value) {
136
- props.backgroundImageUrl = value;
137
- },
138
- get backgroundImageUrl() {
139
- return props.backgroundImageUrl;
140
- },
141
- set maskCombineRatio(value) {
142
- props.maskCombineRatio = clampInRangeFrom0To1(value);
143
- },
144
- get outputCanvas() {
145
- return props.outputCanvas;
146
- },
147
- get backgroundImage() {
148
- return props.backgroundImage;
149
- },
150
- set backgroundImage(image) {
151
- if (image &&
152
- image.key !== props.backgroundImage?.key &&
153
- image.image !== props.backgroundImage?.image) {
154
- props.backgroundImage = image;
155
- if (canUpdate()) {
156
- void props.segmenter.update({ backgroundImage: image });
157
- }
158
- }
159
- },
160
- set outputCanvas(canvas) {
161
- props.outputCanvas = canvas;
162
- },
163
- get outputDelegate() {
164
- return props.outputDelegate;
165
- },
166
- set outputDelegate(canvas) {
167
- props.outputDelegate = canvas;
168
- },
169
- get segmenter() {
170
- return props.segmenter;
171
- },
172
- set segmenter(value) {
173
- if (value !== props.segmenter) {
174
- props.segmenter = value;
175
- }
176
- },
177
- set backend(value) {
178
- if (value === props.backend) {
179
- return;
180
- }
181
- props.backend = value;
182
- if (canUpdate()) {
183
- segmenter.update({
184
- renderOptions: {
185
- backend: props.backend,
186
- backgroundImageUrl: props.backgroundImageUrl,
187
- foregroundThreshold: props.foregroundThreshold,
188
- backgroundBlurAmount: props.backgroundBlurAmount,
189
- edgeBlurAmount: props.edgeBlurAmount,
190
- maskCombineRatio: props.maskCombineRatio,
191
- effects: props.effects,
192
- },
193
- });
194
- }
195
- },
196
- init: (options = {}) => {
197
- updateProps(options);
198
- props.status = 'opened';
199
- props.unsubscribe = segmenter.subscribe('ContextRestored', handleContextRestored);
200
- return Promise.resolve();
201
- },
202
- update: async (options) => {
203
- updateProcessingDimensions(options.processingWidth, options.processingHeight);
204
- // update props needs to happen after dimension comparison
205
- updateProps(options);
206
- if (canUpdate()) {
207
- await segmenter.update(options);
208
- }
209
- },
210
- transform: async (videoFrame, controller) => {
211
- switch (props.effects) {
212
- case 'overlay':
213
- case 'blur': {
214
- const result = await processInput(videoFrame);
215
- const processedFrame = props.outputCanvas ?? result?.frame;
216
- if (props.status === 'closed' ||
217
- // Avoid processing disposed frame
218
- !processedFrame ||
219
- ('displayWidth' in processedFrame &&
220
- processedFrame.displayWidth === 0) ||
221
- ('width' in processedFrame &&
222
- processedFrame.width === 0)) {
223
- break;
224
- }
225
- if ('close' in videoFrame) {
226
- videoFrame.close();
227
- }
228
- controller.enqueue(props.outputCanvas ?? result?.frame);
229
- result?.frame.close();
230
- break;
231
- }
232
- case 'none': {
233
- controller.enqueue(videoFrame);
234
- break;
235
- }
236
- }
237
- props.status = 'processing';
238
- },
239
- close: () => {
240
- if (!selfManageSegmenter) {
241
- segmenter.close();
242
- }
243
- props.unsubscribe?.();
244
- props.status = 'closed';
245
- },
246
- destroy: async () => {
247
- if (!selfManageSegmenter) {
248
- await segmenter.destroy();
249
- }
250
- props.status = 'destroyed';
251
- },
252
- };
253
- };
@@ -1,22 +0,0 @@
1
- import type { Segmenter } from '../types';
2
- import type { Delegate, SegmenterOptions, ImageSegmenterOptions, SegmentationModelAsset } from '../../../common/types/segmentation';
3
- interface Options extends Omit<ImageSegmenterOptions, 'delegate'> {
4
- /**
5
- * The URL for the worker script.
6
- */
7
- workerScriptUrl?: URL;
8
- /**
9
- * Request Credentials for the worker.
10
- *
11
- * @defaultValue 'same-origin'
12
- */
13
- credentials?: RequestCredentials;
14
- /**
15
- * @see `SegmentationModelAsset`
16
- */
17
- modelAsset: SegmentationModelAsset;
18
- delegate?: () => Delegate;
19
- log?: (message: string, meta?: unknown) => void;
20
- }
21
- export declare const createSegmenter: (basePath?: SegmenterOptions["basePath"], { workerScriptUrl, credentials, delegate, log, ...options }?: Options) => Segmenter;
22
- export {};
@@ -1,9 +0,0 @@
1
- import type { InputFrame } from './types';
2
- export declare const nullTransformController: (controller: Pick<TransformStreamDefaultController<CanvasImageSource>, "enqueue" | "terminate">) => TransformStreamDefaultController<CanvasImageSource>;
3
- export declare const adaptInputFrameTransformer: (transformer: Transformer<InputFrame, InputFrame>) => {
4
- transform: (frame: VideoFrame, controller: TransformStreamDefaultController<VideoFrame>) => void | PromiseLike<void> | undefined;
5
- flush?: TransformerFlushCallback<InputFrame> | undefined;
6
- readableType?: undefined;
7
- start?: TransformerStartCallback<InputFrame> | undefined;
8
- writableType?: undefined;
9
- };
@@ -1,68 +0,0 @@
1
- const wrapTransformController = (videoFrame, controller) => {
2
- return {
3
- get desiredSize() {
4
- return controller.desiredSize;
5
- },
6
- enqueue: frame => {
7
- if (!frame) {
8
- return;
9
- }
10
- if (frame instanceof VideoFrame) {
11
- return controller.enqueue(frame);
12
- }
13
- if (('OffscreenCanvas' in window &&
14
- frame instanceof OffscreenCanvas) ||
15
- frame instanceof HTMLCanvasElement ||
16
- frame instanceof HTMLVideoElement ||
17
- frame instanceof HTMLImageElement ||
18
- frame instanceof ImageBitmap) {
19
- const timestamp = videoFrame.timestamp ?? 0;
20
- try {
21
- // Constructing a new VideoFrame with the modified frame
22
- // could throw an error
23
- const newFrame = new VideoFrame(frame, {
24
- timestamp,
25
- alpha: 'discard',
26
- });
27
- controller.enqueue(newFrame);
28
- videoFrame.close();
29
- }
30
- catch {
31
- controller.enqueue(videoFrame);
32
- }
33
- return;
34
- }
35
- throw new Error('Unexpected input frame');
36
- },
37
- error: reason => controller.error(reason),
38
- terminate: () => controller.terminate(),
39
- };
40
- };
41
- export const nullTransformController = (controller) => {
42
- return {
43
- get desiredSize() {
44
- return 0;
45
- },
46
- enqueue: frame => {
47
- if (('OffscreenCanvas' in window &&
48
- frame instanceof OffscreenCanvas) ||
49
- frame instanceof HTMLCanvasElement ||
50
- frame instanceof HTMLVideoElement ||
51
- frame instanceof HTMLImageElement ||
52
- frame instanceof ImageBitmap) {
53
- return controller.enqueue(frame);
54
- }
55
- throw new Error('Unexpected input frame');
56
- },
57
- error: reason => {
58
- throw new Error(reason);
59
- },
60
- terminate: () => controller.terminate(),
61
- };
62
- };
63
- export const adaptInputFrameTransformer = (transformer) => {
64
- const transform = (frame, controller) => {
65
- return transformer.transform?.(frame, wrapTransformController(frame, controller));
66
- };
67
- return { ...transformer, transform };
68
- };
@@ -1,20 +0,0 @@
1
- import type { InputFrame } from './types';
2
- type Track = MediaStreamVideoTrack | MediaStreamVideoTrackGenerator;
3
- interface Options {
4
- signal?: AbortSignal;
5
- }
6
- export type ProcessVideoTrack = (track: MediaStreamVideoTrack, transformers: Transformer<InputFrame, InputFrame>[], options?: Options) => Promise<Track>;
7
- /**
8
- * Video track processor using MediaStreamTrackProcessor API
9
- */
10
- export declare const createVideoTrackProcessor: () => ProcessVideoTrack;
11
- interface FallbackOptions {
12
- width?: number;
13
- height?: number;
14
- frameRate?: number;
15
- }
16
- /**
17
- * Video track processor using Canvas[captureStream] API
18
- */
19
- export declare const createVideoTrackProcessorWithFallback: ({ width, height, frameRate, }?: FallbackOptions) => ProcessVideoTrack;
20
- export {};
@@ -1,86 +0,0 @@
1
- import { assert } from '@pexip/utils';
2
- import { createMediaStreamTrackProcessor } from '../processor';
3
- import { createMediaStreamTrackGenerator } from '../generator';
4
- import { createStreamTransformer } from '../transformer';
5
- import { stopStreamTracks } from '../utils';
6
- import { PROCESSING_HEIGHT, PROCESSING_WIDTH } from '../../common/constants';
7
- import { getImageSize } from '../../common/canvasRenderUtils';
8
- import { adaptInputFrameTransformer, nullTransformController, } from './transformer';
9
- import { toVideoElement, playVideo, createFrameCallbackRequest, createCanvas, getCanvasRenderingContext2D, } from './utils';
10
- import { AbortReason, FRAME_RATE } from './constants';
11
- /**
12
- * Video track processor using MediaStreamTrackProcessor API
13
- */
14
- export const createVideoTrackProcessor = () => (track, transformers, { signal } = {}) => {
15
- if (!transformers.length) {
16
- return Promise.resolve(track);
17
- }
18
- const processor = createMediaStreamTrackProcessor({ track });
19
- const trackGenerator = createMediaStreamTrackGenerator({ kind: 'video' });
20
- let readable = processor.readable;
21
- for (const transformer of transformers) {
22
- readable = readable.pipeThrough(createStreamTransformer(adaptInputFrameTransformer(transformer)), { signal });
23
- }
24
- // Promise returned from `ReadableStream['pipeTo']` is only resolved
25
- // when the streaming is finished
26
- readable
27
- .pipeTo(trackGenerator.writable, {
28
- signal,
29
- })
30
- .catch(error => {
31
- // Ignore abort error
32
- if (signal &&
33
- !(signal.aborted &&
34
- (signal.reason === AbortReason.Close ||
35
- // AbortSignal['reason'] is only supported from Chromium v98 or Firefox v97
36
- !('reason' in AbortSignal.prototype)))) {
37
- throw error;
38
- }
39
- });
40
- return Promise.resolve(trackGenerator);
41
- };
42
- /**
43
- * Video track processor using Canvas[captureStream] API
44
- */
45
- export const createVideoTrackProcessorWithFallback = ({ width = PROCESSING_WIDTH, height = PROCESSING_HEIGHT, frameRate = FRAME_RATE, } = {}) => async (track, transformers, { signal } = {}) => {
46
- const [transformer] = transformers;
47
- if (!transformer?.transform) {
48
- return track;
49
- }
50
- assert(transformers.length <= 1, 'Multi-transformer is NOT supported');
51
- const outputCanvas = createCanvas(width, height);
52
- const ctx = getCanvasRenderingContext2D(outputCanvas, { alpha: false });
53
- const render = (input) => {
54
- assert(transformer.transform);
55
- return Promise.resolve(transformer.transform(input, nullTransformController({
56
- enqueue: frame => {
57
- if (!frame) {
58
- return;
59
- }
60
- const frameSize = getImageSize(frame);
61
- if (frameSize.height !== outputCanvas.height ||
62
- frameSize.width !== outputCanvas.width) {
63
- outputCanvas.height = frameSize.height;
64
- outputCanvas.width = frameSize.width;
65
- }
66
- ctx.drawImage(frame, 0, 0, outputCanvas.width, outputCanvas.height);
67
- },
68
- terminate: () => {
69
- stop();
70
- },
71
- })));
72
- };
73
- const runner = createFrameCallbackRequest(render, frameRate);
74
- const videoElement = toVideoElement(new MediaStream([track]), width, height);
75
- await playVideo(videoElement);
76
- await runner.start(videoElement);
77
- const stream = outputCanvas.captureStream(frameRate);
78
- const [trackGenerated] = stream.getVideoTracks();
79
- assert(trackGenerated, 'Canvas captureStream returns no video track');
80
- const stop = () => {
81
- stopStreamTracks(stream);
82
- runner.stop();
83
- };
84
- signal?.addEventListener('abort', stop);
85
- return trackGenerated;
86
- };