@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
|
@@ -51,7 +51,7 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
51
51
|
throttleInMS: DEFAULT_QUEUE_THROTTLE_MS,
|
|
52
52
|
delayInMS: DEFAULT_QUEUE_DELAY_MS,
|
|
53
53
|
dropLast: DEFAULT_QUEUE_DROP_LAST,
|
|
54
|
-
}, audioProcessors, videoProcessors, getDefaultConstraints = () => ({}), signals, }) => {
|
|
54
|
+
}, audioProcessors, videoProcessors, getDefaultConstraints = () => ({}), signals, stopVideoTrackAsMute = () => false, }) => {
|
|
55
55
|
const queue = createAsyncQueue(queueOptions);
|
|
56
56
|
const eventHandlers = {};
|
|
57
57
|
const internalProps = {
|
|
@@ -62,6 +62,7 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
62
62
|
discardMedia: false,
|
|
63
63
|
initialized: false,
|
|
64
64
|
signals,
|
|
65
|
+
keepVideoMuted: false,
|
|
65
66
|
};
|
|
66
67
|
const logger = createModuleLogger({
|
|
67
68
|
module: 'PreviewStreamController',
|
|
@@ -125,7 +126,7 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
125
126
|
eventHandlers.audioMuted?.(track.muted);
|
|
126
127
|
}
|
|
127
128
|
else {
|
|
128
|
-
eventHandlers.videoMuted?.(track.muted);
|
|
129
|
+
eventHandlers.videoMuted?.(props.keepVideoMuted || track.muted);
|
|
129
130
|
}
|
|
130
131
|
}),
|
|
131
132
|
props.signals.onMediaTrackSuspended?.add(track => {
|
|
@@ -151,7 +152,9 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
151
152
|
break;
|
|
152
153
|
}
|
|
153
154
|
case 'video': {
|
|
154
|
-
eventHandlers.videoMuted?.(
|
|
155
|
+
eventHandlers.videoMuted?.(props.keepVideoMuted ||
|
|
156
|
+
isTrackMuted(track) ||
|
|
157
|
+
isTrackEnded(track));
|
|
155
158
|
break;
|
|
156
159
|
}
|
|
157
160
|
}
|
|
@@ -163,7 +166,9 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
163
166
|
break;
|
|
164
167
|
}
|
|
165
168
|
case 'video': {
|
|
166
|
-
eventHandlers.videoMuted?.(
|
|
169
|
+
eventHandlers.videoMuted?.(props.keepVideoMuted ||
|
|
170
|
+
isTrackMuted(track) ||
|
|
171
|
+
isTrackEnded(track));
|
|
167
172
|
break;
|
|
168
173
|
}
|
|
169
174
|
}
|
|
@@ -173,7 +178,7 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
173
178
|
getUserMedia: requestUserMediaWithRetry(() => Promise.resolve(getCurrentDevices())),
|
|
174
179
|
signals: props.signals,
|
|
175
180
|
getCurrentDevices: () => Promise.resolve(getCurrentDevices()),
|
|
176
|
-
stopVideoTrackAsMute
|
|
181
|
+
stopVideoTrackAsMute,
|
|
177
182
|
updateMedia: constraints => updateMedia(constraints),
|
|
178
183
|
});
|
|
179
184
|
const mergeMediaConstraints = (constraints) => {
|
|
@@ -223,6 +228,14 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
223
228
|
getCurrentDevices: () => Promise.resolve(getCurrentDevices()),
|
|
224
229
|
shouldDiscardMedia: () => props.discardMedia,
|
|
225
230
|
onMediaTracksChanged: (media, tracks) => {
|
|
231
|
+
if (props.keepVideoMuted) {
|
|
232
|
+
for (const track of tracks) {
|
|
233
|
+
if (track.kind === 'videoinput') {
|
|
234
|
+
track.mute(true);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
props.keepVideoMuted = false;
|
|
238
|
+
}
|
|
226
239
|
props.media = media;
|
|
227
240
|
queue.enqueue(async () => {
|
|
228
241
|
await processAndUpdateMedia(media, tracks, false);
|
|
@@ -328,14 +341,16 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
328
341
|
props.updatingPreviewAudio = false;
|
|
329
342
|
}
|
|
330
343
|
};
|
|
331
|
-
const updateVideoInput = async (input) => {
|
|
344
|
+
const updateVideoInput = async (input, syncMuteState = true) => {
|
|
332
345
|
try {
|
|
333
346
|
props.videoInput = input;
|
|
334
347
|
props.updatingPreviewVideo = true;
|
|
335
348
|
if (input === undefined) {
|
|
336
349
|
return await releaseVideo();
|
|
337
350
|
}
|
|
338
|
-
|
|
351
|
+
props.keepVideoMuted = syncMuteState && !!props.media?.videoMuted;
|
|
352
|
+
await updatePreviewMedia({ video: { device: { exact: input } } });
|
|
353
|
+
return;
|
|
339
354
|
}
|
|
340
355
|
catch (error) {
|
|
341
356
|
if (error instanceof Error) {
|
|
@@ -475,7 +490,7 @@ export const createPreviewStreamController = ({ getCurrentDevices, getCurrentMed
|
|
|
475
490
|
return updateAudioInput(input);
|
|
476
491
|
}
|
|
477
492
|
case 'videoinput': {
|
|
478
|
-
return updateVideoInput(input);
|
|
493
|
+
return updateVideoInput(input, false);
|
|
479
494
|
}
|
|
480
495
|
}
|
|
481
496
|
},
|
package/dist/typeGuard.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnalyzerNodeInit } from '@pexip/media-processor';
|
|
2
|
-
import type { AudioContentHint, Media, VideoContentHint
|
|
2
|
+
import type { AudioContentHint, Media, VideoContentHint } from './types';
|
|
3
3
|
import { UserMediaStatus } from './types';
|
|
4
4
|
export declare const isNonNullObject: (value: unknown) => value is Record<string, unknown>;
|
|
5
5
|
export declare const isUserMediaStatus: (value: unknown) => value is UserMediaStatus;
|
|
@@ -7,4 +7,3 @@ export declare const isMedia: (value: unknown) => value is Media;
|
|
|
7
7
|
export declare const isAnalyzerNodeInitProp: (value: unknown) => value is AnalyzerNodeInit | undefined;
|
|
8
8
|
export declare const isAudioContentHint: (value: unknown) => value is AudioContentHint;
|
|
9
9
|
export declare const isVideoContentHint: (value: unknown) => value is VideoContentHint;
|
|
10
|
-
export declare const isVideoStreamTrackProcessorAPIs: (value: unknown) => value is VideoStreamTrackProcessorAPIs;
|
package/dist/typeGuard.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IndexedDevices, InputConstraintSet, InputDeviceConstraint, MediaDeviceInfoLike, MediaDeviceRequest } from '@pexip/media-control';
|
|
2
|
-
import type { RendererOptions, RenderEffects
|
|
2
|
+
import type { RendererOptions, RenderEffects } from '@pexip/media-processor';
|
|
3
3
|
import type { Signal } from '@pexip/signal';
|
|
4
4
|
export type Unsubscribe = () => void;
|
|
5
5
|
export interface ExtendedMediaTrackSettings extends MediaTrackSettings {
|
|
@@ -14,10 +14,12 @@ export interface ExtendedMediaTrackSettings extends MediaTrackSettings {
|
|
|
14
14
|
maskCombineRatio?: number;
|
|
15
15
|
foregroundThreshold?: number;
|
|
16
16
|
videoSegmentation?: RenderEffects;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
panEnabled?: boolean;
|
|
18
|
+
tiltEnabled?: boolean;
|
|
19
|
+
zoomEnabled?: boolean;
|
|
20
|
+
pan?: number;
|
|
21
|
+
tilt?: number;
|
|
22
|
+
zoom?: number;
|
|
21
23
|
contentHint?: AudioContentHint | VideoContentHint;
|
|
22
24
|
}
|
|
23
25
|
export type ExtendedMediaTrackSettingsKey = keyof ExtendedMediaTrackSettings;
|
|
@@ -230,12 +232,6 @@ export type GetUserMediaProcess = (request: {
|
|
|
230
232
|
};
|
|
231
233
|
currentMedia: Media | undefined;
|
|
232
234
|
}) => Promise<Media>;
|
|
233
|
-
/**
|
|
234
|
-
* Use which processor API to process the stream track
|
|
235
|
-
* `stream` - Use `MediaStreamTrackProcessor`, when available
|
|
236
|
-
* `canvas` - Use Canvas
|
|
237
|
-
*/
|
|
238
|
-
export type VideoStreamTrackProcessorAPIs = 'stream' | 'canvas';
|
|
239
235
|
export declare enum UserMediaStatus {
|
|
240
236
|
/**
|
|
241
237
|
* The initial status
|
|
@@ -573,9 +569,6 @@ export declare enum DeniedDevices {
|
|
|
573
569
|
Camera = "camera",
|
|
574
570
|
Both = "microphone-and-camera"
|
|
575
571
|
}
|
|
576
|
-
export type Segmenters = {
|
|
577
|
-
[Property in SegmentationModel]: Segmenter;
|
|
578
|
-
};
|
|
579
572
|
/**
|
|
580
573
|
* Audio content hints are only applicable when the MediaStreamTrack contains an
|
|
581
574
|
* audio track
|
package/dist/utils.js
CHANGED
|
@@ -3,6 +3,7 @@ import { calculateMaxBlurPass, clamping, } from '@pexip/media-processor';
|
|
|
3
3
|
import { hasOwn, assert, isEmpty } from '@pexip/utils';
|
|
4
4
|
import { internalSignals } from './signals';
|
|
5
5
|
import { MAX_TENT_BLUR_SIZE } from './constants';
|
|
6
|
+
import { mapFeatureToSettings } from './videoProcessor';
|
|
6
7
|
export const makeDeriveDeviceStatus = (constraints) => (audio, video, both) => {
|
|
7
8
|
if (constraints.audio) {
|
|
8
9
|
if (constraints.video) {
|
|
@@ -571,7 +572,6 @@ export const AUDIO_SETTINGS_KEYS = [
|
|
|
571
572
|
export const VIDEO_SETTINGS_KEYS = [
|
|
572
573
|
'frameRate',
|
|
573
574
|
'videoSegmentation',
|
|
574
|
-
'videoSegmentationModel',
|
|
575
575
|
'foregroundThreshold',
|
|
576
576
|
'backgroundBlurAmount',
|
|
577
577
|
'edgeBlurAmount',
|
|
@@ -629,10 +629,11 @@ export const getSettingsFromKeys = (keys, settings) => {
|
|
|
629
629
|
return settings;
|
|
630
630
|
}
|
|
631
631
|
const result = {};
|
|
632
|
+
const mapped = mapFeatureToSettings(settings);
|
|
632
633
|
for (const key of keys) {
|
|
633
|
-
if (
|
|
634
|
+
if (mapped[key] !== undefined) {
|
|
634
635
|
// @ts-expect-error --- Type issue and need to be fixed when we have time
|
|
635
|
-
result[key] =
|
|
636
|
+
result[key] = mapped[key];
|
|
636
637
|
}
|
|
637
638
|
}
|
|
638
639
|
return result;
|
package/dist/videoProcessor.d.ts
CHANGED
|
@@ -1,27 +1,15 @@
|
|
|
1
|
-
import type { RenderBackend,
|
|
2
|
-
import type { MediaDeviceRequest } from '@pexip/media-control';
|
|
3
|
-
import type {
|
|
4
|
-
interface
|
|
5
|
-
segmenters: Partial<Segmenters>;
|
|
6
|
-
transformer?: SegmentationTransform;
|
|
7
|
-
videoProcessor?: () => VideoProcessor;
|
|
8
|
-
videoSegmentationModel?: SegmentationModel;
|
|
9
|
-
}
|
|
10
|
-
interface VideoStreamProcessOptions extends Partial<VideoRenderParams>, Omit<ProcessorDeps, 'videoProcessor'> {
|
|
11
|
-
/**
|
|
12
|
-
* What API to use for processing the MediaStreamTrack
|
|
13
|
-
* `stream` - Use MediaStreamTrackProcessor, when available
|
|
14
|
-
* `canvas` - Use Canvas
|
|
15
|
-
*/
|
|
16
|
-
trackProcessorAPI?: () => VideoStreamTrackProcessorAPIs;
|
|
1
|
+
import type { RenderBackend, VideoProcessor } from '@pexip/media-processor';
|
|
2
|
+
import type { InputConstraintSet, MediaDeviceRequest } from '@pexip/media-control';
|
|
3
|
+
import type { ExtendedMediaTrackSettings, MediaSignals, TrackProcessor, VideoContentHint, VideoRenderParams } from './types';
|
|
4
|
+
interface VideoStreamProcessOptions extends Partial<VideoRenderParams> {
|
|
17
5
|
/**
|
|
18
6
|
* Whether or to enable this processor
|
|
19
7
|
*/
|
|
20
8
|
shouldEnable: () => boolean;
|
|
9
|
+
getVideoProcessor: () => VideoProcessor;
|
|
21
10
|
referenceProcessingHeight?: number;
|
|
22
11
|
processingWidth: number;
|
|
23
12
|
processingHeight: number;
|
|
24
|
-
hasInitializedDeps?: boolean;
|
|
25
13
|
width?: number;
|
|
26
14
|
height?: number;
|
|
27
15
|
label?: string;
|
|
@@ -30,13 +18,43 @@ interface VideoStreamProcessOptions extends Partial<VideoRenderParams>, Omit<Pro
|
|
|
30
18
|
gpuAPI?: () => RenderBackend;
|
|
31
19
|
signals?: MediaSignals;
|
|
32
20
|
}
|
|
33
|
-
interface VideoStreamProcessProps extends Partial<VideoRenderParams
|
|
34
|
-
hasInitialized: boolean;
|
|
21
|
+
interface VideoStreamProcessProps extends Partial<VideoRenderParams> {
|
|
35
22
|
contentHint?: VideoContentHint;
|
|
36
23
|
}
|
|
37
|
-
declare const FEATURE_KEYS:
|
|
38
|
-
|
|
24
|
+
declare const FEATURE_KEYS: {
|
|
25
|
+
readonly backgroundBlurAmount: "number";
|
|
26
|
+
readonly backgroundImageUrl: "string";
|
|
27
|
+
readonly backgroundThreshold: "number";
|
|
28
|
+
readonly maskCombineRatio: "number";
|
|
29
|
+
readonly edgeBlurAmount: "number";
|
|
30
|
+
readonly foregroundThreshold: "number";
|
|
31
|
+
readonly frameRate: "number";
|
|
32
|
+
readonly videoSegmentation: "string";
|
|
33
|
+
readonly width: "number";
|
|
34
|
+
readonly height: "number";
|
|
35
|
+
readonly pan: "boolean";
|
|
36
|
+
readonly tilt: "boolean";
|
|
37
|
+
readonly zoom: "boolean";
|
|
38
|
+
readonly contentHint: "string";
|
|
39
|
+
readonly sigmaSpace: "number";
|
|
40
|
+
readonly sigmaRangeLo: "number";
|
|
41
|
+
readonly sigmaRangeHi: "number";
|
|
42
|
+
readonly excludeBystanders: "boolean";
|
|
43
|
+
readonly personCenterX: "number";
|
|
44
|
+
readonly personCenterY: "number";
|
|
45
|
+
readonly morphErodeRadiusPx: "number";
|
|
46
|
+
readonly morphPass: "number";
|
|
47
|
+
readonly morphDilateRadiusPx: "number";
|
|
48
|
+
readonly lightWrapIntensity: "number";
|
|
49
|
+
readonly lightWrapTightness: "number";
|
|
50
|
+
readonly lightWrapEdgeBand: "number";
|
|
51
|
+
readonly lightWrapBlurAmount: "number";
|
|
52
|
+
readonly downSampleFactor: "number";
|
|
53
|
+
};
|
|
54
|
+
type FeaturePropKeys = keyof typeof FEATURE_KEYS;
|
|
39
55
|
type FeatureProps = Pick<Partial<VideoStreamProcessProps>, FeaturePropKeys>;
|
|
40
56
|
export declare const updateFeatureProps: (constraints: MediaDeviceRequest["video"], props: FeatureProps) => FeatureProps;
|
|
41
|
-
export declare const
|
|
57
|
+
export declare const mapFeatureToSettings: (props: InputConstraintSet) => ExtendedMediaTrackSettings;
|
|
58
|
+
export declare const mapSettingsToFeatures: (settings: ExtendedMediaTrackSettings) => InputConstraintSet;
|
|
59
|
+
export declare const createVideoStreamProcess: ({ backgroundImageUrl, dynamicProcessingDimensions, backgroundThreshold, downSampleFactor, foregroundThreshold, lightWrapEdgeBand, lightWrapIntensity, lightWrapTightness, morphDilateRadiusPx, morphErodeRadiusPx, morphPass, personCenterX, personCenterY, sigmaSpace, sigmaRangeHi, sigmaRangeLo, frameRate, gpuAPI, label, referenceProcessingHeight, maskCombineRatio, processingHeight, processingWidth, shouldEnable, stopAsMute, videoSegmentation, signals, getVideoProcessor, ...options }: VideoStreamProcessOptions) => TrackProcessor;
|
|
42
60
|
export {};
|