@pexip/media 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,111 @@
1
1
  # @pexip/media
2
2
 
3
+ ## 22.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 498ff3b: - **`createVideoStreamProcess` refactored**:
8
+ - No longer accepts `segmenters`, `transformer`, `trackProcessorAPI`, or
9
+ `videoSegmentationModel`.
10
+ - Now requires a `getVideoProcessor: () => VideoProcessor` factory.
11
+ - All render option updates go through
12
+ `videoProcessor.update({renderOptions})` instead of direct transformer
13
+ property mutation.
14
+ - `applyFeatures` is now `async`.
15
+ - **`videoSegmentationModel` removed** from constraints, settings, and types.
16
+ - **`Segmenters` type removed**.
17
+ - **`isVideoStreamTrackProcessorAPIs` removed**
18
+
19
+ ### Minor Changes
20
+
21
+ - 7d986cc: - Adds new optional `stopVideoTrackAsMute` prop to
22
+ `PreviewStreamParams` of `previewController.ts`. This is forwarded to
23
+ `createGetUserMediaProcess`, defaults to `() => false`
24
+ - Preview controller always syncs current video track mute state with new one
25
+ after it is acquired unless explicitly forced to not do so.
26
+
27
+ ### Patch Changes
28
+
29
+ - f8bd1c5: Fix VideoProcessor and Segment open/update behavior
30
+ - d2fd777: Fix `mapSettingsToFeatures` and `mapFeatureToSettings` Proxy handlers
31
+ to include `ownKeys`, `has`, and `getOwnPropertyDescriptor` traps. Previously,
32
+ the proxies wrapped an empty object, causing `Object.keys()`, `for...in`,
33
+ `hasOwn()`, and `isEmpty()` to see no properties. This could silently skip
34
+ constraint application and cause downstream logic to receive incorrect values.
35
+ - fb41d4d: Changes related to Typescript V6 Upgrade
36
+ - Updated dependencies [f8bd1c5]
37
+ - Updated dependencies [498ff3b]
38
+ - Updated dependencies [498ff3b]
39
+ - Updated dependencies [498ff3b]
40
+ - Updated dependencies [925cce6]
41
+ - Updated dependencies [fb41d4d]
42
+ - Updated dependencies [fe0a0a4]
43
+ - Updated dependencies [b99c070]
44
+ - @pexip/media-processor@22.0.0
45
+ - @pexip/utils@17.3.0
46
+ - @pexip/media-control@22.0.0
47
+ - @pexip/signal@16.9.5
48
+
49
+ ## 21.0.0
50
+
51
+ ### Major Changes
52
+
53
+ - 2606fa4: Fix blur normalize function
54
+
55
+ ### Minor Changes
56
+
57
+ - 1786b2d: Get correct stream status when only one input kind is requested
58
+ - a004e3c: Introduce new `renderParams` that can be applied via the video
59
+ constraints:
60
+ - `backgroundThreshold` - Segmentation threshold for classifying pixels as
61
+ background (lower values include more background).
62
+ - `downSampleFactor` - Factor for downsampling the video frame before
63
+ processing (higher values improve performance but reduce quality).
64
+ - `lightWrapBlurAmount` - Amount of blur applied to the light wrap effect
65
+ around the subject's edges.
66
+ - `lightWrapEdgeBand` - Width of the edge band in pixels where the light wrap
67
+ effect is applied.
68
+ - `lightWrapIntensity` - Intensity/strength of the light wrap effect (0.0 to
69
+ 1.0).
70
+ - `lightWrapTightness` - Controls how tightly the light wrap effect hugs the
71
+ subject's edges.
72
+ - `morphDilateRadiusPx` - Radius in pixels for morphological dilation
73
+ operation on the segmentation mask.
74
+ - `morphErodeRadiusPx` - Radius in pixels for morphological erosion operation
75
+ on the segmentation mask.
76
+ - `morphPass` - Number of morphological filter passes to apply for mask
77
+ refinement.
78
+ - `personCenterX` - X-coordinate (0.0 to 1.0) of the expected center position
79
+ of the person in the frame for segmentation optimization.
80
+ - `personCenterY` - Y-coordinate (0.0 to 1.0) of the expected center position
81
+ of the person in the frame for segmentation optimization.
82
+ - `sigmaRangeHi` - Bilateral filter: upper bound of sigma in color space for
83
+ edge-preserving smoothing.
84
+ - `sigmaRangeLo` - Bilateral filter: lower bound of sigma in color space for
85
+ edge-preserving smoothing.
86
+ - `sigmaSpace` - Bilateral filter: sigma in pixel space for mask edge
87
+ snapping.
88
+
89
+ ### Patch Changes
90
+
91
+ - c10f5b6: Normalise initial `lightWrapBlurAmount` and `edgeBlurAmount` values
92
+ - Updated dependencies [24bc717]
93
+ - Updated dependencies [1786b2d]
94
+ - Updated dependencies [872971f]
95
+ - Updated dependencies [2e895ac]
96
+ - Updated dependencies [3963c2e]
97
+ - Updated dependencies [1fff975]
98
+ - Updated dependencies [3963c2e]
99
+ - Updated dependencies [762ebd2]
100
+ - Updated dependencies [4eaf9d7]
101
+ - Updated dependencies [4d2da34]
102
+ - Updated dependencies [a004e3c]
103
+ - Updated dependencies [4cc4701]
104
+ - @pexip/media-processor@21.0.0
105
+ - @pexip/media-control@21.0.0
106
+ - @pexip/utils@17.2.0
107
+ - @pexip/signal@16.9.4
108
+
3
109
  ## 20.3.5
4
110
 
5
111
  ### Patch Changes
package/README.md CHANGED
@@ -11,7 +11,7 @@ create a streamlined media process
11
11
 
12
12
  ### `createMedia`
13
13
 
14
- It create's an object to interact with the media stream, which is usually used
14
+ It creates an object to interact with the media stream, which is usually used
15
15
  for our main stream.
16
16
 
17
17
  Its major features:
@@ -67,11 +67,6 @@ export interface InputConstraintSet extends MediaTrackConstraints {
67
67
  * segment. Available effects are `none`, `blur`, `overlay` or `remove`
68
68
  */
69
69
  videoSegmentation?: ConstrainDOMString;
70
- /**
71
- * Segmentation model to be used for video segmentation, currently only
72
- * supports `mediapipeSelfie` and `personify`
73
- */
74
- videoSegmentationModel?: ConstrainDOMString;
75
70
  /**
76
71
  * Whether or not using our own noise suppression
77
72
  */
@@ -133,12 +128,8 @@ export interface InputConstraintSet extends MediaTrackConstraints {
133
128
 
134
129
  ```typescript
135
130
  import {createMedia, createMediaSignals, UserMediaStatus} from '@pexip/media';
136
- import type {RenderEffects, Segmenters, Media} from '@pexip/media';
137
- import {
138
- createSegmenter,
139
- createCanvasTransform,
140
- createVideoProcessor,
141
- } from '@pexip/media-processor';
131
+ import type {RenderEffects, Media} from '@pexip/media';
132
+ import {createSegmenter, createVideoProcessor} from '@pexip/media-processor';
142
133
 
143
134
  // App states
144
135
  const states: {
@@ -186,32 +177,29 @@ const modelAsset = {
186
177
  modelName: 'selfie' as const,
187
178
  };
188
179
 
189
- const segmenter = createSegmenter(tasksVisionBasePath, {modelAssets});
190
- // Create a processing transformer and set the effects to `blur`
191
- const transformer = createCanvasTransform(segmenter, {
192
- effects: states.effects,
193
- foregroundThreshold: states.foregroundThreshold,
194
- backgroundBlurAmount: states.backgroundBlurAmount,
195
- maskCombineRatio: states.maskCombineRatio,
196
- backgroundImageUrl: states.backgroundImageUrl,
197
- });
198
-
199
- const selfie = createSegmenter(taskVisionBasePath, {
180
+ const selfie = createSegmenter(tasksVisionBasePath, {
200
181
  modelAsset,
201
182
  delegate: () => 'GPU', // Use GPU
202
183
  });
203
184
 
204
- export const segmenters: Partial<Segmenters> = {
205
- selfie,
206
- };
207
-
208
- const videoProcessor = createVideoProcessor([transformer]);
209
-
210
185
  const videoStreamProcessor = createVideoStreamProcess({
211
186
  shouldEnable: () => true, // Always Process Video Track
212
- segmenters,
213
- transformer,
214
- videoProcessor,
187
+ getVideoProcessor: () => {
188
+ return createVideoProcessor(
189
+ selfie,
190
+ getDefaultInputProcessAdaptor(
191
+ chooseVideoProcessorAPI() === 'stream',
192
+ FRAME_RATE,
193
+ ),
194
+ );
195
+ },
196
+ videoSegmentation: states.effects,
197
+ foregroundThreshold: states.foregroundThreshold,
198
+ backgroundBlurAmount: states.backgroundBlurAmount,
199
+ maskCombineRatio: states.maskCombineRatio,
200
+ backgroundImageUrl: states.backgroundImageUrl,
201
+ processingWidth: 640,
202
+ processingHeight: 480,
215
203
  });
216
204
 
217
205
  // Instantiate the media object
@@ -11,7 +11,7 @@ create a streamlined media process
11
11
 
12
12
  ### `createMedia`
13
13
 
14
- It create's an object to interact with the media stream, which is usually used
14
+ It creates an object to interact with the media stream, which is usually used
15
15
  for our main stream.
16
16
 
17
17
  Its major features:
@@ -67,11 +67,6 @@ export interface InputConstraintSet extends MediaTrackConstraints {
67
67
  * segment. Available effects are `none`, `blur`, `overlay` or `remove`
68
68
  */
69
69
  videoSegmentation?: ConstrainDOMString;
70
- /**
71
- * Segmentation model to be used for video segmentation, currently only
72
- * supports `mediapipeSelfie` and `personify`
73
- */
74
- videoSegmentationModel?: ConstrainDOMString;
75
70
  /**
76
71
  * Whether or not using our own noise suppression
77
72
  */
@@ -133,12 +128,8 @@ export interface InputConstraintSet extends MediaTrackConstraints {
133
128
 
134
129
  ```typescript
135
130
  import {createMedia, createMediaSignals, UserMediaStatus} from '@pexip/media';
136
- import type {RenderEffects, Segmenters, Media} from '@pexip/media';
137
- import {
138
- createSegmenter,
139
- createCanvasTransform,
140
- createVideoProcessor,
141
- } from '@pexip/media-processor';
131
+ import type {RenderEffects, Media} from '@pexip/media';
132
+ import {createSegmenter, createVideoProcessor} from '@pexip/media-processor';
142
133
 
143
134
  // App states
144
135
  const states: {
@@ -186,32 +177,29 @@ const modelAsset = {
186
177
  modelName: 'selfie' as const,
187
178
  };
188
179
 
189
- const segmenter = createSegmenter(tasksVisionBasePath, {modelAssets});
190
- // Create a processing transformer and set the effects to `blur`
191
- const transformer = createCanvasTransform(segmenter, {
192
- effects: states.effects,
193
- foregroundThreshold: states.foregroundThreshold,
194
- backgroundBlurAmount: states.backgroundBlurAmount,
195
- maskCombineRatio: states.maskCombineRatio,
196
- backgroundImageUrl: states.backgroundImageUrl,
197
- });
198
-
199
- const selfie = createSegmenter(taskVisionBasePath, {
180
+ const selfie = createSegmenter(tasksVisionBasePath, {
200
181
  modelAsset,
201
182
  delegate: () => 'GPU', // Use GPU
202
183
  });
203
184
 
204
- export const segmenters: Partial<Segmenters> = {
205
- selfie,
206
- };
207
-
208
- const videoProcessor = createVideoProcessor([transformer]);
209
-
210
185
  const videoStreamProcessor = createVideoStreamProcess({
211
186
  shouldEnable: () => true, // Always Process Video Track
212
- segmenters,
213
- transformer,
214
- videoProcessor,
187
+ getVideoProcessor: () => {
188
+ return createVideoProcessor(
189
+ selfie,
190
+ getDefaultInputProcessAdaptor(
191
+ chooseVideoProcessorAPI() === 'stream',
192
+ FRAME_RATE,
193
+ ),
194
+ );
195
+ },
196
+ videoSegmentation: states.effects,
197
+ foregroundThreshold: states.foregroundThreshold,
198
+ backgroundBlurAmount: states.backgroundBlurAmount,
199
+ maskCombineRatio: states.maskCombineRatio,
200
+ backgroundImageUrl: states.backgroundImageUrl,
201
+ processingWidth: 640,
202
+ processingHeight: 480,
215
203
  });
216
204
 
217
205
  // Instantiate the media object
@@ -328,12 +316,10 @@ await mediaController.media.applyConstraints({
328
316
  | [Process](type-aliases/Process.mdx) | - |
329
317
  | [TrackProcessor](type-aliases/TrackProcessor.mdx) | - |
330
318
  | [GetUserMediaProcess](type-aliases/GetUserMediaProcess.mdx) | - |
331
- | [VideoStreamTrackProcessorAPIs](type-aliases/VideoStreamTrackProcessorAPIs.mdx) | Use which processor API to process the stream track `stream` - Use `MediaStreamTrackProcessor`, when available `canvas` - Use Canvas |
332
319
  | [VideoRenderParams](type-aliases/VideoRenderParams.mdx) | - |
333
320
  | [MediaSignalsOptional](type-aliases/MediaSignalsOptional.mdx) | - |
334
321
  | [MediaSignalsRequired](type-aliases/MediaSignalsRequired.mdx) | - |
335
322
  | [MediaSignals](type-aliases/MediaSignals.mdx) | - |
336
- | [Segmenters](type-aliases/Segmenters.mdx) | - |
337
323
  | [AudioContentHint](type-aliases/AudioContentHint.mdx) | - |
338
324
  | [VideoContentHint](type-aliases/VideoContentHint.mdx) | - |
339
325
 
@@ -386,6 +372,7 @@ await mediaController.media.applyConstraints({
386
372
  | [createAudioStreamProcess](functions/createAudioStreamProcess.mdx) | Create an Audio Stream Processor and will own the stream passed-in |
387
373
  | [createGetDisplayMedia](functions/createGetDisplayMedia.mdx) | - |
388
374
  | [setLogger](functions/setLogger.mdx) | - |
375
+ | [proxyWithLog](functions/proxyWithLog.mdx) | - |
389
376
  | [createMedia](functions/createMedia.mdx) | Create an object to interact with the media scream, which is usually used for our main stream. |
390
377
  | [createPreviewStreamController](functions/createPreviewStreamController.mdx) | - |
391
378
  | [createMediaSignal](functions/createMediaSignal.mdx) | Create a general signal with consistent scoped name |
@@ -399,6 +386,7 @@ await mediaController.media.applyConstraints({
399
386
  | [isAnalyzerNodeInitProp](functions/isAnalyzerNodeInitProp.mdx) | - |
400
387
  | [isAudioContentHint](functions/isAudioContentHint.mdx) | - |
401
388
  | [isVideoContentHint](functions/isVideoContentHint.mdx) | - |
402
- | [isVideoStreamTrackProcessorAPIs](functions/isVideoStreamTrackProcessorAPIs.mdx) | - |
389
+ | [getBlurKernelSize](functions/getBlurKernelSize.mdx) | A function to get the blur kernel size of image height based on Kawase blur algorithm |
390
+ | [getTentBlurSize](functions/getTentBlurSize.mdx) | A function to get the Tent blur size of image height |
403
391
  | [applyContentHint](functions/applyContentHint.mdx) | Apply the content hint to the track |
404
392
  | [createVideoStreamProcess](functions/createVideoStreamProcess.mdx) | - |
@@ -0,0 +1,25 @@
1
+ ```ts
2
+ function getBlurKernelSize(
3
+ norm,
4
+ heightRef,
5
+ height,
6
+ max): number;
7
+ ```
8
+
9
+ A function to get the blur kernel size of image height based on
10
+ Kawase blur algorithm
11
+
12
+ ## Parameters
13
+
14
+ | Parameter | Type | Description |
15
+ | ------ | ------ | ------ |
16
+ | `norm` | `number` | [0-100] The normalized blur amount |
17
+ | `heightRef` | `number` | The reference image height |
18
+ | `height` | `number` | The current image height |
19
+ | `max` | `number` | The upper bound |
20
+
21
+ ## Returns
22
+
23
+ `number`
24
+
25
+ blur kernel size
@@ -0,0 +1,24 @@
1
+ ```ts
2
+ function getTentBlurSize(
3
+ norm,
4
+ heightRef,
5
+ height,
6
+ max): number;
7
+ ```
8
+
9
+ A function to get the Tent blur size of image height
10
+
11
+ ## Parameters
12
+
13
+ | Parameter | Type | Default value | Description |
14
+ | ------ | ------ | ------ | ------ |
15
+ | `norm` | `number` | `undefined` | [0-100] The normalized blur amount |
16
+ | `heightRef` | `number` | `undefined` | The reference image height |
17
+ | `height` | `number` | `undefined` | The current image height |
18
+ | `max` | `number` | `MAX_TENT_BLUR_SIZE` | The upper bound |
19
+
20
+ ## Returns
21
+
22
+ `number`
23
+
24
+ tent blur size
@@ -0,0 +1,33 @@
1
+ ```ts
2
+ function proxyWithLog(logger, scope): <T>(obj, name) => T;
3
+ ```
4
+
5
+ ## Parameters
6
+
7
+ | Parameter | Type |
8
+ | ------ | ------ |
9
+ | `logger` | `Logger` |
10
+ | `scope` | `string` |
11
+
12
+ ## Returns
13
+
14
+ ```ts
15
+ <T>(obj, name): T;
16
+ ```
17
+
18
+ ### Type Parameters
19
+
20
+ | Type Parameter |
21
+ | ------ |
22
+ | `T` *extends* `object` |
23
+
24
+ ### Parameters
25
+
26
+ | Parameter | Type |
27
+ | ------ | ------ |
28
+ | `obj` | `T` |
29
+ | `name` | `string` |
30
+
31
+ ### Returns
32
+
33
+ `T`
@@ -17,17 +17,19 @@
17
17
  | <a id="maskcombineratio"></a> `maskCombineRatio?` | `number` | - | - |
18
18
  | <a id="foregroundthreshold"></a> `foregroundThreshold?` | `number` | - | - |
19
19
  | <a id="videosegmentation"></a> `videoSegmentation?` | `"none"` \| `"blur"` \| `"overlay"` | - | - |
20
- | <a id="videosegmentationmodel"></a> `videoSegmentationModel?` | `SegmentationModel` | - | - |
21
- | <a id="pan"></a> `pan?` | `boolean` | - | - |
22
- | <a id="tilt"></a> `tilt?` | `boolean` | - | - |
23
- | <a id="zoom"></a> `zoom?` | `boolean` | - | - |
20
+ | <a id="panenabled"></a> `panEnabled?` | `boolean` | - | - |
21
+ | <a id="tiltenabled"></a> `tiltEnabled?` | `boolean` | - | - |
22
+ | <a id="zoomenabled"></a> `zoomEnabled?` | `boolean` | - | - |
23
+ | <a id="pan"></a> `pan?` | `number` | - | - |
24
+ | <a id="tilt"></a> `tilt?` | `number` | - | - |
25
+ | <a id="zoom"></a> `zoom?` | `number` | `MediaTrackSettings.zoom` | - |
24
26
  | <a id="contenthint"></a> `contentHint?` | \| `""` \| `"speech"` \| `"speech-recognition"` \| `"music"` \| `"motion"` \| `"detail"` \| `"text"` | - | - |
25
27
  | <a id="aspectratio"></a> `aspectRatio?` | `number` | - | `MediaTrackSettings.aspectRatio` |
26
28
  | <a id="autogaincontrol"></a> `autoGainControl?` | `boolean` | - | `MediaTrackSettings.autoGainControl` |
27
29
  | <a id="backgroundblur"></a> `backgroundBlur?` | `boolean` | - | `MediaTrackSettings.backgroundBlur` |
28
30
  | <a id="deviceid"></a> `deviceId?` | `string` | - | `MediaTrackSettings.deviceId` |
29
31
  | <a id="displaysurface"></a> `displaySurface?` | `string` | - | `MediaTrackSettings.displaySurface` |
30
- | <a id="echocancellation"></a> `echoCancellation?` | `boolean` | - | `MediaTrackSettings.echoCancellation` |
32
+ | <a id="echocancellation"></a> `echoCancellation?` | `string` \| `boolean` | - | `MediaTrackSettings.echoCancellation` |
31
33
  | <a id="facingmode"></a> `facingMode?` | `string` | - | `MediaTrackSettings.facingMode` |
32
34
  | <a id="framerate"></a> `frameRate?` | `number` | - | `MediaTrackSettings.frameRate` |
33
35
  | <a id="groupid"></a> `groupId?` | `string` | - | `MediaTrackSettings.groupId` |
@@ -35,4 +37,6 @@
35
37
  | <a id="noisesuppression"></a> `noiseSuppression?` | `boolean` | - | `MediaTrackSettings.noiseSuppression` |
36
38
  | <a id="samplerate"></a> `sampleRate?` | `number` | - | `MediaTrackSettings.sampleRate` |
37
39
  | <a id="samplesize"></a> `sampleSize?` | `number` | - | `MediaTrackSettings.sampleSize` |
40
+ | <a id="torch"></a> `torch?` | `boolean` | - | `MediaTrackSettings.torch` |
41
+ | <a id="whitebalancemode"></a> `whiteBalanceMode?` | `string` | - | `MediaTrackSettings.whiteBalanceMode` |
38
42
  | <a id="width"></a> `width?` | `number` | - | `MediaTrackSettings.width` |
@@ -12,3 +12,4 @@
12
12
  | <a id="discardmedia"></a> `discardMedia` | `boolean` |
13
13
  | <a id="initialized"></a> `initialized` | `boolean` |
14
14
  | <a id="signals"></a> `signals` | [`MediaSignals`](../type-aliases/MediaSignals.mdx) |
15
+ | <a id="keepvideomuted"></a> `keepVideoMuted` | `boolean` |
@@ -13,3 +13,4 @@
13
13
  | <a id="audioprocessors"></a> `audioProcessors` | [`TrackProcessor`](../type-aliases/TrackProcessor.mdx)[] | - |
14
14
  | <a id="videoprocessors"></a> `videoProcessors` | [`TrackProcessor`](../type-aliases/TrackProcessor.mdx)[] | - |
15
15
  | <a id="getdefaultconstraints"></a> `getDefaultConstraints?` | () => `object` | Pass default constraints to use with get media wrappers |
16
+ | <a id="stopvideotrackasmute"></a> `stopVideoTrackAsMute?` | () => `boolean` | - |
@@ -1,5 +1,5 @@
1
1
  ```ts
2
- type VideoRenderParams = Omit<RendererOptions, "effects"> & object;
2
+ type VideoRenderParams = Omit<RendererOptions, "effects" | "personCenter"> & object;
3
3
  ```
4
4
 
5
5
  ## Type Declaration
@@ -13,3 +13,5 @@ type VideoRenderParams = Omit<RendererOptions, "effects"> & object;
13
13
  | `pan?` | `boolean` | - |
14
14
  | `tilt?` | `boolean` | - |
15
15
  | `zoom?` | `boolean` | - |
16
+ | `personCenterX?` | `number` | - |
17
+ | `personCenterY?` | `number` | - |
@@ -7,8 +7,10 @@ interface AudioStreamProcessorProps {
7
7
  displaySource?: AudioNodeInit<MediaStreamAudioSourceNode, MediaStreamAudioSourceNode>;
8
8
  audioGraph?: AudioGraph;
9
9
  }
10
- declare const FEATURE_KEYS: ['mixWithAdditionalMedia'];
11
- type FeaturePropKeys = (typeof FEATURE_KEYS)[number];
10
+ declare const FEATURE_KEYS: {
11
+ readonly mixWithAdditionalMedia: "boolean";
12
+ };
13
+ type FeaturePropKeys = keyof typeof FEATURE_KEYS;
12
14
  type FeatureProps = Pick<AudioStreamProcessorProps, FeaturePropKeys>;
13
15
  export declare const updateFeatureProps: (constraints: MediaDeviceRequest["audio"], props: FeatureProps) => FeatureProps;
14
16
  /**
@@ -1,22 +1,32 @@
1
- import { extractConstraintsWithKeys } from '@pexip/media-control';
1
+ import { extractConstraints } from '@pexip/media-control';
2
2
  import { isEmpty, assert } from '@pexip/utils';
3
3
  import { createAudioGraph, createAudioGraphProxy, createChannelMergerGraphNode, createStreamDestinationGraphNode, createStreamSourceGraphNode, resumeAudioOnUnmute, } from '@pexip/media-processor';
4
4
  import { logger } from './logger';
5
5
  import { createMediaTrack } from './utils';
6
6
  import { PROCESSOR_LABELS } from './constants';
7
- const FEATURE_KEYS = ['mixWithAdditionalMedia'];
8
- const getAudioConstraints = extractConstraintsWithKeys(FEATURE_KEYS);
7
+ const FEATURE_KEYS = { mixWithAdditionalMedia: 'boolean' };
9
8
  export const updateFeatureProps = (constraints, props) => {
10
- const extracted = getAudioConstraints(constraints);
11
- return FEATURE_KEYS.reduce((accm, key) => {
12
- const [feature] = extracted[key];
13
- if (feature !== undefined && props[key] !== feature) {
14
- props[key] = feature;
15
- accm[key] = feature;
16
- return accm;
9
+ const features = {};
10
+ if (constraints === undefined || typeof constraints === 'boolean') {
11
+ return features;
12
+ }
13
+ for (const k of Object.keys(constraints)) {
14
+ const key = k;
15
+ if (!FEATURE_KEYS[key]) {
16
+ continue;
17
17
  }
18
- return accm;
19
- }, {});
18
+ switch (key) {
19
+ case 'mixWithAdditionalMedia': {
20
+ const [feature] = extractConstraints(key)(constraints);
21
+ if (feature !== undefined && props[key] !== feature) {
22
+ props[key] = feature;
23
+ features[key] = feature;
24
+ }
25
+ break;
26
+ }
27
+ }
28
+ }
29
+ return features;
20
30
  };
21
31
  /**
22
32
  * Create an Audio Mixing Processor and will own the stream passed-in
@@ -76,8 +76,13 @@ interface AudioStreamProcessorProps {
76
76
  contentHint?: AudioContentHint;
77
77
  audioGraph?: AudioGraph;
78
78
  }
79
- declare const FEATURE_KEYS: ['denoise', 'vad', 'asd', 'contentHint'];
80
- type FeaturePropKeys = (typeof FEATURE_KEYS)[number];
79
+ declare const FEATURE_KEYS: {
80
+ readonly denoise: "boolean";
81
+ readonly vad: "boolean";
82
+ readonly asd: "boolean";
83
+ readonly contentHint: "string";
84
+ };
85
+ type FeaturePropKeys = keyof typeof FEATURE_KEYS;
81
86
  type FeatureProps = Pick<AudioStreamProcessorProps, FeaturePropKeys>;
82
87
  export declare const updateFeatureProps: (constraints: MediaDeviceRequest["audio"], props: FeatureProps) => FeatureProps;
83
88
  /**
@@ -1,4 +1,4 @@
1
- import { extractConstraintsWithKeys } from '@pexip/media-control';
1
+ import { extractConstraints } from '@pexip/media-control';
2
2
  import { createQueue, isEmpty, assert } from '@pexip/utils';
3
3
  import { avg, createAnalyzerSubscribableGraphNode, createAudioGraph, createAudioGraphProxy, createAudioSignalDetector, createDenoiseWorkletGraphNode, createStreamDestinationGraphNode, createStreamSourceGraphNode, createVADetector, createVoiceDetectorFromProbability, createVoiceDetectorFromTimeData, } from '@pexip/media-processor';
4
4
  import { PROCESSOR_LABELS } from './constants';
@@ -17,41 +17,46 @@ const fetchDenoiseWasm = async (denoiseWasm, wasmURL) => {
17
17
  }
18
18
  return await (await fetch(wasmURL)).arrayBuffer();
19
19
  };
20
- const FEATURE_KEYS = [
21
- 'denoise',
22
- 'vad',
23
- 'asd',
24
- 'contentHint',
25
- ];
26
- const getAudioConstraints = extractConstraintsWithKeys(FEATURE_KEYS);
20
+ const FEATURE_KEYS = {
21
+ denoise: 'boolean',
22
+ vad: 'boolean',
23
+ asd: 'boolean',
24
+ contentHint: 'string',
25
+ };
27
26
  export const updateFeatureProps = (constraints, props) => {
28
- const extracted = getAudioConstraints(constraints);
29
- return FEATURE_KEYS.reduce((accm, key) => {
27
+ const features = {};
28
+ if (constraints === undefined || typeof constraints === 'boolean') {
29
+ return features;
30
+ }
31
+ for (const k of Object.keys(constraints)) {
32
+ const key = k;
33
+ if (!FEATURE_KEYS[key]) {
34
+ continue;
35
+ }
30
36
  switch (key) {
31
37
  case 'contentHint': {
32
- const [[feature] = []] = extracted[key];
38
+ const [[feature] = []] = extractConstraints(key)(constraints);
33
39
  if (isAudioContentHint(feature) && props[key] !== feature) {
34
40
  props[key] = feature;
35
- accm[key] = feature;
36
- return accm;
41
+ features[key] = feature;
37
42
  }
38
- return accm;
43
+ break;
39
44
  }
40
45
  case 'denoise':
41
46
  case 'asd':
42
47
  case 'vad': {
43
- const [feature] = extracted[key];
48
+ const [feature] = extractConstraints(key)(constraints);
44
49
  if (feature !== undefined && props[key] !== feature) {
45
50
  props[key] = feature;
46
- accm[key] = feature;
47
- return accm;
51
+ features[key] = feature;
48
52
  }
49
- return accm;
53
+ break;
50
54
  }
51
55
  default:
52
- return accm;
56
+ break;
53
57
  }
54
- }, {});
58
+ }
59
+ return features;
55
60
  };
56
61
  /**
57
62
  * Create an Audio Stream Processor and will own the stream passed-in
@@ -6,3 +6,4 @@ export declare const PROCESSOR_LABELS: Readonly<{
6
6
  }>;
7
7
  export declare const GET_USER_MEDIA_TIMEOUT_MS = 10000;
8
8
  export declare const DEVICE_CHANGE_DEBOUNCE_TIMEOUT_MS = 500;
9
+ export declare const MAX_TENT_BLUR_SIZE = 9;
package/dist/constants.js CHANGED
@@ -6,3 +6,4 @@ export const PROCESSOR_LABELS = Object.freeze({
6
6
  });
7
7
  export const GET_USER_MEDIA_TIMEOUT_MS = 10000;
8
8
  export const DEVICE_CHANGE_DEBOUNCE_TIMEOUT_MS = 500;
9
+ export const MAX_TENT_BLUR_SIZE = 9;
package/dist/index.d.ts CHANGED
@@ -4,9 +4,9 @@ export * from './signals';
4
4
  export * from './status';
5
5
  export * from './typeGuard';
6
6
  export * from './types';
7
- export { applyContentHint } from './utils';
7
+ export { applyContentHint, getBlurKernelSize, getTentBlurSize } from './utils';
8
8
  export { createAudioMixingProcess } from './audioMixingProcessor';
9
9
  export { createAudioStreamProcess } from './audioProcessor';
10
10
  export { createMedia } from './media';
11
11
  export { createVideoStreamProcess } from './videoProcessor';
12
- export { setLogger } from './logger';
12
+ export { setLogger, proxyWithLog } from './logger';
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ export * from './signals';
4
4
  export * from './status';
5
5
  export * from './typeGuard';
6
6
  export * from './types';
7
- export { applyContentHint } from './utils';
7
+ export { applyContentHint, getBlurKernelSize, getTentBlurSize } from './utils';
8
8
  export { createAudioMixingProcess } from './audioMixingProcessor';
9
9
  export { createAudioStreamProcess } from './audioProcessor';
10
10
  export { createMedia } from './media';
11
11
  export { createVideoStreamProcess } from './videoProcessor';
12
- export { setLogger } from './logger';
12
+ export { setLogger, proxyWithLog } from './logger';
package/dist/logger.js CHANGED
@@ -28,6 +28,14 @@ export const createLogProxyHandler = (logger, name, scope) => {
28
28
  get: (target, p, receiver) => {
29
29
  const value = Reflect.get(target, p, receiver);
30
30
  logger.debug({ scope, name, prop: p, value }, `called get ${name}[${String(p)}]`);
31
+ if (typeof value === 'function') {
32
+ return new Proxy(value, {
33
+ apply: (fn, thisArg, args) => {
34
+ logger.debug({ scope, name, method: String(p), args }, `called ${name}.${String(p)}(...)`);
35
+ return Reflect.apply(fn, thisArg, args);
36
+ },
37
+ });
38
+ }
31
39
  return value;
32
40
  },
33
41
  set: (target, p, value, receiver) => {