@pexip/media 21.0.0 → 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 +46 -0
- package/README.md +20 -32
- package/api-docs/README.mdx +21 -35
- package/api-docs/functions/proxyWithLog.mdx +33 -0
- package/api-docs/interfaces/ExtendedMediaTrackSettings.mdx +9 -5
- package/api-docs/interfaces/PreviewControllerProps.mdx +1 -0
- package/api-docs/interfaces/PreviewStreamParams.mdx +1 -0
- package/dist/audioMixingProcessor.d.ts +4 -2
- package/dist/audioMixingProcessor.js +22 -12
- package/dist/audioProcessor.d.ts +7 -2
- package/dist/audioProcessor.js +25 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/logger.js +8 -0
- package/dist/media.js +5 -5
- package/dist/previewController.d.ts +3 -1
- package/dist/previewController.js +23 -8
- package/dist/typeGuard.d.ts +1 -2
- package/dist/typeGuard.js +0 -3
- package/dist/types.d.ts +7 -14
- package/dist/utils.js +4 -3
- package/dist/videoProcessor.d.ts +40 -22
- package/dist/videoProcessor.js +225 -245
- package/package.json +10 -10
- package/api-docs/functions/isVideoStreamTrackProcessorAPIs.mdx +0 -13
- package/api-docs/type-aliases/Segmenters.mdx +0 -3
- package/api-docs/type-aliases/VideoStreamTrackProcessorAPIs.mdx +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
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
|
+
|
|
3
49
|
## 21.0.0
|
|
4
50
|
|
|
5
51
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ create a streamlined media process
|
|
|
11
11
|
|
|
12
12
|
### `createMedia`
|
|
13
13
|
|
|
14
|
-
It
|
|
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,
|
|
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
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
package/api-docs/README.mdx
CHANGED
|
@@ -11,7 +11,7 @@ create a streamlined media process
|
|
|
11
11
|
|
|
12
12
|
### `createMedia`
|
|
13
13
|
|
|
14
|
-
It
|
|
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,
|
|
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
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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,7 +386,6 @@ 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) | - |
|
|
403
389
|
| [getBlurKernelSize](functions/getBlurKernelSize.mdx) | A function to get the blur kernel size of image height based on Kawase blur algorithm |
|
|
404
390
|
| [getTentBlurSize](functions/getTentBlurSize.mdx) | A function to get the Tent blur size of image height |
|
|
405
391
|
| [applyContentHint](functions/applyContentHint.mdx) | Apply the content hint to the track |
|
|
@@ -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="
|
|
21
|
-
| <a id="
|
|
22
|
-
| <a id="
|
|
23
|
-
| <a id="
|
|
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` | - |
|
|
@@ -7,8 +7,10 @@ interface AudioStreamProcessorProps {
|
|
|
7
7
|
displaySource?: AudioNodeInit<MediaStreamAudioSourceNode, MediaStreamAudioSourceNode>;
|
|
8
8
|
audioGraph?: AudioGraph;
|
|
9
9
|
}
|
|
10
|
-
declare const FEATURE_KEYS:
|
|
11
|
-
|
|
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 {
|
|
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 =
|
|
8
|
-
const getAudioConstraints = extractConstraintsWithKeys(FEATURE_KEYS);
|
|
7
|
+
const FEATURE_KEYS = { mixWithAdditionalMedia: 'boolean' };
|
|
9
8
|
export const updateFeatureProps = (constraints, props) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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
|
package/dist/audioProcessor.d.ts
CHANGED
|
@@ -76,8 +76,13 @@ interface AudioStreamProcessorProps {
|
|
|
76
76
|
contentHint?: AudioContentHint;
|
|
77
77
|
audioGraph?: AudioGraph;
|
|
78
78
|
}
|
|
79
|
-
declare const FEATURE_KEYS:
|
|
80
|
-
|
|
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
|
/**
|
package/dist/audioProcessor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
29
|
-
|
|
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] = []] =
|
|
38
|
+
const [[feature] = []] = extractConstraints(key)(constraints);
|
|
33
39
|
if (isAudioContentHint(feature) && props[key] !== feature) {
|
|
34
40
|
props[key] = feature;
|
|
35
|
-
|
|
36
|
-
return accm;
|
|
41
|
+
features[key] = feature;
|
|
37
42
|
}
|
|
38
|
-
|
|
43
|
+
break;
|
|
39
44
|
}
|
|
40
45
|
case 'denoise':
|
|
41
46
|
case 'asd':
|
|
42
47
|
case 'vad': {
|
|
43
|
-
const [feature] =
|
|
48
|
+
const [feature] = extractConstraints(key)(constraints);
|
|
44
49
|
if (feature !== undefined && props[key] !== feature) {
|
|
45
50
|
props[key] = feature;
|
|
46
|
-
|
|
47
|
-
return accm;
|
|
51
|
+
features[key] = feature;
|
|
48
52
|
}
|
|
49
|
-
|
|
53
|
+
break;
|
|
50
54
|
}
|
|
51
55
|
default:
|
|
52
|
-
|
|
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
|
package/dist/index.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ 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
|
@@ -9,4 +9,4 @@ 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) => {
|
package/dist/media.js
CHANGED
|
@@ -7,7 +7,7 @@ import { createGetUserMediaProcess, requestUserMediaWithRetry, } from './userMed
|
|
|
7
7
|
import { AUDIO_SETTINGS_KEYS, MIXING_SETTINGS_KEYS, PAN_TILT_ZOOM_SETTINGS_KEYS, VIDEO_SETTINGS_KEYS, buildMedia, createMediaProcessor, diffSettings, getDevicesChanges, getSettingsFromKeys, hasPtzFeature, isApplyingRenderEffect, mergeSettings, refineMediaConstraints, } from './utils';
|
|
8
8
|
import { getPermissionStatus, isRequestPermissionNeeded } from './status';
|
|
9
9
|
import { isMedia } from './typeGuard';
|
|
10
|
-
import { updateFeatureProps as getVideoFeatures } from './videoProcessor';
|
|
10
|
+
import { updateFeatureProps as getVideoFeatures, mapFeatureToSettings, mapSettingsToFeatures, } from './videoProcessor';
|
|
11
11
|
import { updateFeatureProps as getAudioFeatures } from './audioProcessor';
|
|
12
12
|
import { updateFeatureProps as getMixingFeatures } from './audioMixingProcessor';
|
|
13
13
|
import { GET_USER_MEDIA_TIMEOUT_MS, DEVICE_CHANGE_DEBOUNCE_TIMEOUT_MS, } from './constants';
|
|
@@ -59,7 +59,7 @@ export const createMediaUpdater = ({ getUserMedia, getCurrentDevices, shouldDisc
|
|
|
59
59
|
const defaultVideoSettings = getSettingsFromKeys(VIDEO_SETTINGS_KEYS, getDefaultConstraints?.().video);
|
|
60
60
|
const videoFeaturesChanged = defaultVideoSettings === false
|
|
61
61
|
? undefined
|
|
62
|
-
: diffSettings(VIDEO_SETTINGS_KEYS)(prevVideoSettings ?? defaultVideoSettings, videoFeatures);
|
|
62
|
+
: diffSettings(VIDEO_SETTINGS_KEYS)(prevVideoSettings ?? defaultVideoSettings, mapFeatureToSettings(videoFeatures));
|
|
63
63
|
const defaultMixingSettings = getSettingsFromKeys(MIXING_SETTINGS_KEYS, getDefaultConstraints?.().audio);
|
|
64
64
|
const mixingFeaturesChanged = defaultMixingSettings === false
|
|
65
65
|
? undefined
|
|
@@ -68,7 +68,7 @@ export const createMediaUpdater = ({ getUserMedia, getCurrentDevices, shouldDisc
|
|
|
68
68
|
const ptzFeaturesChanges = defaultPTZSettings === false
|
|
69
69
|
? undefined
|
|
70
70
|
: hasPtzFeature() &&
|
|
71
|
-
diffSettings(PAN_TILT_ZOOM_SETTINGS_KEYS)(prevVideoSettings ?? defaultPTZSettings, videoFeatures);
|
|
71
|
+
diffSettings(PAN_TILT_ZOOM_SETTINGS_KEYS)(prevVideoSettings ?? defaultPTZSettings, mapFeatureToSettings(videoFeatures));
|
|
72
72
|
const audioRequest = refineMediaConstraints({
|
|
73
73
|
kind: 'audioinput',
|
|
74
74
|
request: constraints.audio,
|
|
@@ -154,8 +154,8 @@ export const createMediaUpdater = ({ getUserMedia, getCurrentDevices, shouldDisc
|
|
|
154
154
|
: undefined;
|
|
155
155
|
if (audioDiff || videoDiff) {
|
|
156
156
|
await currentMedia?.applyConstraints({
|
|
157
|
-
audio: audioDiff,
|
|
158
|
-
video: videoDiff,
|
|
157
|
+
audio: audioDiff && mapSettingsToFeatures(audioDiff),
|
|
158
|
+
video: videoDiff && mapSettingsToFeatures(videoDiff),
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
};
|
|
@@ -39,6 +39,7 @@ export interface PreviewStreamParams {
|
|
|
39
39
|
audio?: InputConstraintSet | false;
|
|
40
40
|
video?: InputConstraintSet | false;
|
|
41
41
|
};
|
|
42
|
+
stopVideoTrackAsMute?: () => boolean;
|
|
42
43
|
}
|
|
43
44
|
export interface PreviewControllerProps {
|
|
44
45
|
media: Media | undefined;
|
|
@@ -51,6 +52,7 @@ export interface PreviewControllerProps {
|
|
|
51
52
|
discardMedia: boolean;
|
|
52
53
|
initialized: boolean;
|
|
53
54
|
signals: MediaSignals;
|
|
55
|
+
keepVideoMuted: boolean;
|
|
54
56
|
}
|
|
55
57
|
export interface PreviewStreamController {
|
|
56
58
|
media: Media | undefined;
|
|
@@ -83,6 +85,6 @@ export interface PreviewStreamController {
|
|
|
83
85
|
onVideoMuted(callback: EventCallback<boolean | undefined>): Unsubscribe;
|
|
84
86
|
onVideoSuspended(callback: EventCallback<boolean | undefined>): Unsubscribe;
|
|
85
87
|
}
|
|
86
|
-
export declare const createPreviewStreamController: ({ getCurrentDevices, getCurrentMedia, updateMainStream, onEnded, mainMediaSignal, queueOptions, audioProcessors, videoProcessors, getDefaultConstraints, signals, }: PreviewStreamParams) => PreviewStreamController;
|
|
88
|
+
export declare const createPreviewStreamController: ({ getCurrentDevices, getCurrentMedia, updateMainStream, onEnded, mainMediaSignal, queueOptions, audioProcessors, videoProcessors, getDefaultConstraints, signals, stopVideoTrackAsMute, }: PreviewStreamParams) => PreviewStreamController;
|
|
87
89
|
export type CreatePreviewStreamController = typeof createPreviewStreamController;
|
|
88
90
|
export {};
|