@pexip/media-control 19.1.0 → 20.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 +28 -0
- package/dist/baseLogger.d.ts +15 -6
- package/dist/baseLogger.js +13 -7
- package/dist/constraints.d.ts +7 -7
- package/dist/constraints.js +36 -55
- package/dist/devices.d.ts +8 -17
- package/dist/devices.js +36 -42
- package/dist/errors.d.ts +2 -2
- package/dist/eventEmitter.d.ts +2 -12
- package/dist/eventEmitter.js +0 -4
- package/dist/index.js +4 -13
- package/dist/streamTrackMap.js +2 -2
- package/dist/streams.js +3 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/typeGuards.d.ts +11 -11
- package/dist/types.d.ts +15 -1
- package/dist/utils.d.ts +3 -4
- package/dist/utils.js +44 -14
- package/package.json +23 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 20.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 2bfd9e1: Adds esm entry points.
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- 3555d9d: Adds `build:sourcemap` script.
|
|
12
|
+
- 7d94f5c: Take unauthorized device into account
|
|
13
|
+
- ed53b05: Upgrade Typescript
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- b0d8af9: Enable recommended lint rules
|
|
18
|
+
- e76a15e: Migrate to biome linter
|
|
19
|
+
- Updated dependencies [2bfd9e1]
|
|
20
|
+
- Updated dependencies [4fe77de]
|
|
21
|
+
- Updated dependencies [2bbff64]
|
|
22
|
+
- Updated dependencies [4ea0492]
|
|
23
|
+
- Updated dependencies [3555d9d]
|
|
24
|
+
- Updated dependencies [1601985]
|
|
25
|
+
- Updated dependencies [84956b8]
|
|
26
|
+
- Updated dependencies [ed53b05]
|
|
27
|
+
- Updated dependencies [d681fd3]
|
|
28
|
+
- Updated dependencies [e76a15e]
|
|
29
|
+
- @pexip/utils@17.0.0
|
|
30
|
+
|
|
3
31
|
## 19.1.0
|
|
4
32
|
|
|
5
33
|
## 19.0.0
|
package/dist/baseLogger.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare enum LogLevels {
|
|
|
9
9
|
warn = 40,
|
|
10
10
|
error = 50,
|
|
11
11
|
fatal = 60,
|
|
12
|
-
silent
|
|
12
|
+
silent = 9007199254740991
|
|
13
13
|
}
|
|
14
14
|
export type LogLevelsString = keyof typeof LogLevels;
|
|
15
15
|
export type LogMethods = {
|
|
@@ -21,14 +21,23 @@ export type LogMethods = {
|
|
|
21
21
|
*/
|
|
22
22
|
export interface Logger extends LogMethods {
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Add a pattern to the redactor and an optional mask for the redaction.
|
|
25
25
|
*
|
|
26
|
-
* @
|
|
27
|
-
* The redaction set is applied globally, and only applies to the log file, not console logs.
|
|
26
|
+
* @see {@link Redactor}
|
|
28
27
|
*
|
|
29
|
-
* @param value -
|
|
28
|
+
* @param value - The pattern to add.
|
|
29
|
+
* @param replaceTo - The mask to use for redaction.
|
|
30
30
|
*/
|
|
31
|
-
|
|
31
|
+
addRedactPattern(value: string, redactTo?: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Redact the provided string by replacing all occurrences of the patterns
|
|
34
|
+
* and return a new string with redacted values.
|
|
35
|
+
*
|
|
36
|
+
* @see {@link Redactor}
|
|
37
|
+
*
|
|
38
|
+
* @param text - The string to redact.
|
|
39
|
+
*/
|
|
40
|
+
redact(text: string): string;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
43
|
* Create a logger with console API, and map fatal to error, skipping trace
|
package/dist/baseLogger.js
CHANGED
|
@@ -6,8 +6,7 @@ export var LogLevels;
|
|
|
6
6
|
LogLevels[LogLevels["warn"] = 40] = "warn";
|
|
7
7
|
LogLevels[LogLevels["error"] = 50] = "error";
|
|
8
8
|
LogLevels[LogLevels["fatal"] = 60] = "fatal";
|
|
9
|
-
|
|
10
|
-
LogLevels[LogLevels["silent"] = Number.MAX_SAFE_INTEGER] = "silent";
|
|
9
|
+
LogLevels[LogLevels["silent"] = 9007199254740991] = "silent";
|
|
11
10
|
})(LogLevels || (LogLevels = {}));
|
|
12
11
|
/**
|
|
13
12
|
* Create a logger with console API, and map fatal to error, skipping trace
|
|
@@ -15,15 +14,22 @@ export var LogLevels;
|
|
|
15
14
|
*/
|
|
16
15
|
export function createConsoleLogger() {
|
|
17
16
|
return Object.freeze({
|
|
18
|
-
/* eslint-disable no-console -- set logger to console */
|
|
19
17
|
fatal: (meta, message) => console.error(message, meta),
|
|
20
18
|
error: (meta, message) => console.error(message, meta),
|
|
21
19
|
warn: (meta, message) => console.warn(message, meta),
|
|
22
20
|
info: (meta, message) => console.info(message, meta),
|
|
23
21
|
debug: (meta, message) => console.debug(message, meta),
|
|
24
|
-
trace() {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
trace() {
|
|
23
|
+
// Noop
|
|
24
|
+
},
|
|
25
|
+
silent() {
|
|
26
|
+
// Noop
|
|
27
|
+
},
|
|
28
|
+
redact(text) {
|
|
29
|
+
return text;
|
|
30
|
+
},
|
|
31
|
+
addRedactPattern() {
|
|
32
|
+
// Noop
|
|
33
|
+
},
|
|
28
34
|
});
|
|
29
35
|
}
|
package/dist/constraints.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare const mergeConstraints: (baseConstraints: InputConstraintSet | bo
|
|
|
19
19
|
*
|
|
20
20
|
* Check test cases for the details
|
|
21
21
|
*/
|
|
22
|
-
export declare const normalizeDevice: (device: InputConstraintSet[
|
|
22
|
+
export declare const normalizeDevice: (device: InputConstraintSet["device"]) => MediaDeviceInfo[] | undefined;
|
|
23
23
|
/**
|
|
24
24
|
* Normalize Device Constraint
|
|
25
25
|
* Convert Device Constraints into a form of `ConstraintDeviceParameters`
|
|
@@ -32,12 +32,12 @@ export declare const normalizeDevice: (device: InputConstraintSet['device']) =>
|
|
|
32
32
|
* `undefined` if nothing is meaningful for the constraint, otherwise,
|
|
33
33
|
* a normalized form of `ConstraintDeviceParameters`
|
|
34
34
|
*/
|
|
35
|
-
export declare const normalizeDeviceConstraint: (constraints: InputConstraintSet[
|
|
35
|
+
export declare const normalizeDeviceConstraint: (constraints: InputConstraintSet["device"]) => NormalizedConstraintDeviceParameters | undefined;
|
|
36
36
|
/**
|
|
37
37
|
* Convert `InputConstraintSet['device']` into
|
|
38
38
|
* `MediaTrackConstraintSet['deviceId']` in a normalized form
|
|
39
39
|
*/
|
|
40
|
-
export declare const toDeviceIdConstraintSet: (constraint: InputConstraintSet[
|
|
40
|
+
export declare const toDeviceIdConstraintSet: (constraint: InputConstraintSet["device"]) => MediaTrackConstraints["deviceId"];
|
|
41
41
|
export declare const toArray: <T>(t: T | T[]) => T[];
|
|
42
42
|
export type ConstrainNoneTuple = [undefined, 'ideal'];
|
|
43
43
|
export declare const NONE: ConstrainNoneTuple;
|
|
@@ -104,8 +104,8 @@ export declare const getMediaConstraints: ({ audio, video, defaultConstraints, }
|
|
|
104
104
|
*/
|
|
105
105
|
export declare const applyConstraints: (tracks: MediaStreamTrack[] | undefined, constraints: MediaDeviceRequest) => Promise<void>;
|
|
106
106
|
export declare const findDeviceFrom: (devicesToFind: MediaDeviceInfoLike[], devices: IndexedDevices) => MediaDeviceInfoLike[];
|
|
107
|
-
export declare const findDeviceFromDeviceConstraints: (device: InputConstraintSet[
|
|
108
|
-
export declare const relaxDevice: (device: InputConstraintSet[
|
|
107
|
+
export declare const findDeviceFromDeviceConstraints: (device: InputConstraintSet["device"], devices: IndexedDevices) => MediaDeviceInfoLike[] | undefined;
|
|
108
|
+
export declare const relaxDevice: (device: InputConstraintSet["device"], devices: IndexedDevices) => MediaDeviceInfoLike[] | undefined;
|
|
109
109
|
export declare const resolveOnlyDevice: (devices: IndexedDevices) => true | MediaDeviceInfoLike | undefined;
|
|
110
110
|
type ConstrainNumberKeys = ConstrainULongKeys | ConstrainDoubleKeys | ExtendedConstrainDoubleKeys | ExtendedConstrainULongKeys;
|
|
111
111
|
type ConstrainTuples = ConstrainDeviceTuple | ConstrainNumberTuple | ConstrainStringTuple | ConstrainBooleanTuple | ConstrainNoneTuple;
|
|
@@ -143,7 +143,7 @@ export type Constraints = ConstrainStrings & ConstrainNumbers & ConstrainBoolean
|
|
|
143
143
|
* expect(noiseSuppressionParam).toEqual('ideal');
|
|
144
144
|
* ```
|
|
145
145
|
*/
|
|
146
|
-
export declare const extractConstraintsWithKeys: <T extends
|
|
146
|
+
export declare const extractConstraintsWithKeys: <T extends keyof Constraints>(keys: readonly T[]) => (constraints: InputDeviceConstraint | undefined) => Pick<Constraints, T>;
|
|
147
147
|
/**
|
|
148
148
|
* Extract deviceId from constraints
|
|
149
149
|
*/
|
|
@@ -167,7 +167,7 @@ export declare const findDeviceFromConstraints: (constraints: InputDeviceConstra
|
|
|
167
167
|
* @param input - The input constraints to be relaxed
|
|
168
168
|
* @param devices - The current device list
|
|
169
169
|
*/
|
|
170
|
-
export declare const relaxInputConstraint: (kind:
|
|
170
|
+
export declare const relaxInputConstraint: (kind: "audioinput" | "videoinput", input: InputDeviceConstraint | undefined, devices: IndexedDevices) => InputDeviceConstraint | undefined;
|
|
171
171
|
export declare const getConstraintsHandlers: () => {
|
|
172
172
|
getDefaultConstraints: () => MediaStreamConstraints;
|
|
173
173
|
setDefaultConstraints: (newConstraints: MediaStreamConstraints) => void;
|
package/dist/constraints.js
CHANGED
|
@@ -18,10 +18,13 @@ const getConstraintsSetFilter = (supportedConstraints) => (trackConstraints) =>
|
|
|
18
18
|
if (!isMediaTrackConstraints(trackConstraints)) {
|
|
19
19
|
return trackConstraints;
|
|
20
20
|
}
|
|
21
|
-
const constraints =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const constraints = {};
|
|
22
|
+
for (const [key, value] of Object.entries(trackConstraints)) {
|
|
23
|
+
if (key === 'advanced' ||
|
|
24
|
+
supportedConstraints.has(key)) {
|
|
25
|
+
constraints[key] = value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
25
28
|
// If we don't have any valid constraints it seems sensible to fallback to a boolean constraint -ea
|
|
26
29
|
if (Object.keys(constraints).length === 0) {
|
|
27
30
|
return true;
|
|
@@ -29,7 +32,13 @@ const getConstraintsSetFilter = (supportedConstraints) => (trackConstraints) =>
|
|
|
29
32
|
return constraints;
|
|
30
33
|
};
|
|
31
34
|
const getDefinedOnly = (obj) => {
|
|
32
|
-
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
37
|
+
if (typeof value !== 'undefined') {
|
|
38
|
+
result[key] = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
33
42
|
};
|
|
34
43
|
/**
|
|
35
44
|
* Use navigator.mediaDevices.getSupportedConstraints to remove constraints not supported by agent.
|
|
@@ -41,11 +50,7 @@ export const removeUnsupportedConstraints = (constraints) => {
|
|
|
41
50
|
}
|
|
42
51
|
const supportedConstraints = Object.entries(navigator.mediaDevices.getSupportedConstraints());
|
|
43
52
|
logger.debug({ supportedConstraints }, 'Supported constraints');
|
|
44
|
-
const constraintsSetFilter = getConstraintsSetFilter(supportedConstraints.reduce((set, [key, value]) =>
|
|
45
|
-
// FIXME: Cast inserted to unblock typescript upgrade, will have to be verified and properly fixed.
|
|
46
|
-
value && isMediaTrackConstraintSetKey(key)
|
|
47
|
-
? set.add(key)
|
|
48
|
-
: set, new Set()));
|
|
53
|
+
const constraintsSetFilter = getConstraintsSetFilter(supportedConstraints.reduce((set, [key, value]) => value && isMediaTrackConstraintSetKey(key) ? set.add(key) : set, new Set()));
|
|
49
54
|
return getDefinedOnly({
|
|
50
55
|
audio: constraintsSetFilter(constraints.audio),
|
|
51
56
|
peerIdentity: constraints.peerIdentity,
|
|
@@ -73,9 +78,9 @@ export const mergeConstraints = (baseConstraints) => (constraints) => {
|
|
|
73
78
|
...baseConstraints,
|
|
74
79
|
device: constraints,
|
|
75
80
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return result;
|
|
81
|
+
result.facingMode = undefined;
|
|
82
|
+
result.deviceId = undefined;
|
|
83
|
+
return getDefinedOnly(result);
|
|
79
84
|
}
|
|
80
85
|
if (isInputConstraintSet(constraints)) {
|
|
81
86
|
const combined = { ...baseConstraints, ...constraints };
|
|
@@ -87,13 +92,13 @@ export const mergeConstraints = (baseConstraints) => (constraints) => {
|
|
|
87
92
|
const result = {
|
|
88
93
|
...combined,
|
|
89
94
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return result;
|
|
95
|
+
result.facingMode = undefined;
|
|
96
|
+
result.deviceId = undefined;
|
|
97
|
+
return getDefinedOnly(result);
|
|
93
98
|
}
|
|
94
99
|
if (hasDevice || hasDeviceId) {
|
|
95
|
-
|
|
96
|
-
return combined;
|
|
100
|
+
combined.facingMode = undefined;
|
|
101
|
+
return getDefinedOnly(combined);
|
|
97
102
|
}
|
|
98
103
|
return combined;
|
|
99
104
|
}
|
|
@@ -271,7 +276,7 @@ export const extractConstrainDevice = (constraints, initialParam = 'ideal') => {
|
|
|
271
276
|
* @param numDigits - The number of digits to check after the decimal point @defaultValue 5 digits
|
|
272
277
|
*/
|
|
273
278
|
export const closedTo = (a, b, numDigits = 5) => {
|
|
274
|
-
const multiplier =
|
|
279
|
+
const multiplier = 10 ** numDigits;
|
|
275
280
|
return Math.round(a * multiplier) === Math.round(b * multiplier);
|
|
276
281
|
};
|
|
277
282
|
/**
|
|
@@ -374,12 +379,12 @@ export const resolveMediaDeviceConstraints = (constraints, base) => {
|
|
|
374
379
|
return merge(Object.keys(constraints).reduce((cs, k) => {
|
|
375
380
|
const key = k;
|
|
376
381
|
if (key === 'device') {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
deviceId: toDeviceIdConstraintSet(constraints.device),
|
|
380
|
-
};
|
|
382
|
+
cs.deviceId = toDeviceIdConstraintSet(constraints.device);
|
|
383
|
+
return cs;
|
|
381
384
|
}
|
|
382
|
-
|
|
385
|
+
// @ts-expect-error --- for performance
|
|
386
|
+
cs[key] = constraints[key];
|
|
387
|
+
return cs;
|
|
383
388
|
}, {}));
|
|
384
389
|
}
|
|
385
390
|
return merge(constraints);
|
|
@@ -532,38 +537,14 @@ export function extractConstraints(key) {
|
|
|
532
537
|
* expect(noiseSuppressionParam).toEqual('ideal');
|
|
533
538
|
* ```
|
|
534
539
|
*/
|
|
535
|
-
export const extractConstraintsWithKeys = (keys) => (constraints) =>
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
};
|
|
541
|
-
}
|
|
542
|
-
if (isConstrainULongKeys(key) ||
|
|
543
|
-
isConstrainDoubleKeys(key) ||
|
|
544
|
-
isExtendedConstrainULongKeys(key) ||
|
|
545
|
-
isExtendedConstrainDoubleKeys(key)) {
|
|
546
|
-
return {
|
|
547
|
-
...result,
|
|
548
|
-
[key]: extractConstraints(key)(constraints),
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
if (isConstrainStringKeys(key) ||
|
|
552
|
-
isExtendedConstrainStringKeys(key)) {
|
|
553
|
-
return {
|
|
554
|
-
...result,
|
|
555
|
-
[key]: extractConstraints(key)(constraints),
|
|
556
|
-
};
|
|
540
|
+
export const extractConstraintsWithKeys = (keys) => (constraints) => {
|
|
541
|
+
const extracted = {};
|
|
542
|
+
for (const key of keys) {
|
|
543
|
+
// @ts-expect-error --- subpress ts error for performance
|
|
544
|
+
extracted[key] = extractConstraints(key)(constraints);
|
|
557
545
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
return {
|
|
561
|
-
...result,
|
|
562
|
-
[key]: extractConstraints(key)(constraints),
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
return result;
|
|
566
|
-
}, {});
|
|
546
|
+
return extracted;
|
|
547
|
+
};
|
|
567
548
|
/**
|
|
568
549
|
* Extract deviceId from constraints
|
|
569
550
|
*/
|
package/dist/devices.d.ts
CHANGED
|
@@ -4,17 +4,11 @@ import type { FacingMode, IndexedDevices, InputConstraintSet, InputDeviceConstra
|
|
|
4
4
|
*
|
|
5
5
|
* ```
|
|
6
6
|
* devices (raw)
|
|
7
|
-
* |--- authorized
|
|
8
|
-
* | |--- found
|
|
9
|
-
* | |--- lost
|
|
10
|
-
* |--- unauthorized
|
|
11
7
|
* ```
|
|
12
8
|
*
|
|
13
9
|
* @beta
|
|
14
10
|
*/
|
|
15
11
|
export type DeviceChangedChanges = {
|
|
16
|
-
authorized: MediaDeviceInfoLike[];
|
|
17
|
-
unauthorized: MediaDeviceInfoLike[];
|
|
18
12
|
found: MediaDeviceInfoLike[];
|
|
19
13
|
lost: MediaDeviceInfoLike[];
|
|
20
14
|
devices: MediaDeviceInfoLike[];
|
|
@@ -30,7 +24,7 @@ interface ToKeyOptions {
|
|
|
30
24
|
* @beta
|
|
31
25
|
*/
|
|
32
26
|
export declare const toKey: ({ id, kind, label }: ToKeyOptions) => string;
|
|
33
|
-
export declare const toMediaDeviceInputKind: (track: Pick<MediaStreamTrack,
|
|
27
|
+
export declare const toMediaDeviceInputKind: (track: Pick<MediaStreamTrack, "kind">) => "audioinput" | "videoinput";
|
|
34
28
|
/**
|
|
35
29
|
* Future proofing: in case we want to alter the values or type returned
|
|
36
30
|
* by {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices | enumerateDevices}
|
|
@@ -52,10 +46,7 @@ export declare const getDevices: () => Promise<MediaDeviceInfo[]>;
|
|
|
52
46
|
export declare const toDeviceKey: (device: MediaDeviceInfoLike) => string;
|
|
53
47
|
export declare const toDeviceTuple: (device: MediaDeviceInfoLike) => readonly [string, MediaDeviceInfoLike];
|
|
54
48
|
export declare const toDevicesMap: (devices: MediaDeviceInfoLike[]) => Map<string, MediaDeviceInfoLike>;
|
|
55
|
-
export declare const toUniqueDevices: (devices: MediaDeviceInfoLike[]) => MediaDeviceInfoLike[];
|
|
56
49
|
export declare const createTrackDevicesChanges: (prevDevices?: MediaDeviceInfoLike[]) => (devices: MediaDeviceInfoLike[]) => {
|
|
57
|
-
unauthorized: MediaDeviceInfoLike[];
|
|
58
|
-
authorized: MediaDeviceInfoLike[];
|
|
59
50
|
found: MediaDeviceInfoLike[];
|
|
60
51
|
lost: MediaDeviceInfoLike[];
|
|
61
52
|
devices: MediaDeviceInfoLike[];
|
|
@@ -90,7 +81,7 @@ export declare const toMediaDeviceInfoLike: (track: MediaStreamTrack) => MediaDe
|
|
|
90
81
|
*
|
|
91
82
|
* @beta
|
|
92
83
|
*/
|
|
93
|
-
export declare const compareMediaDeviceToMediaTrack: (track: Pick<MediaStreamTrack,
|
|
84
|
+
export declare const compareMediaDeviceToMediaTrack: (track: Pick<MediaStreamTrack, "kind" | "getSettings" | "label">) => (device: MediaDeviceInfoLike) => boolean;
|
|
94
85
|
export declare const toMediaDeviceInfo: (info: MediaDeviceInfoLike) => {
|
|
95
86
|
deviceId: string;
|
|
96
87
|
groupId: string;
|
|
@@ -121,7 +112,7 @@ export declare const findMediaInputFromMediaStreamTrack: (devices: IndexedDevice
|
|
|
121
112
|
* @beta
|
|
122
113
|
*/
|
|
123
114
|
export declare const findMediaInputFromStream: (devices: IndexedDevices) => (stream: MediaStream | undefined) => MediaInput;
|
|
124
|
-
export declare const compareDeviceConstraintAndTrackDevice: (device: MediaDeviceInfoLike | undefined) => (constraint: InputConstraintSet[
|
|
115
|
+
export declare const compareDeviceConstraintAndTrackDevice: (device: MediaDeviceInfoLike | undefined) => (constraint: InputConstraintSet["device"]) => boolean;
|
|
125
116
|
export declare const isRequestedResolution: (request: InputDeviceConstraint | undefined, response: MediaTrackSettings | undefined) => boolean;
|
|
126
117
|
export declare const isRequestedInputDevice: (request: InputDeviceConstraint | undefined, response: MediaDeviceInfoLike | MediaDeviceTrackInfo | undefined) => boolean;
|
|
127
118
|
/**
|
|
@@ -204,8 +195,8 @@ export declare const findPermissionGrantedDevices: (devices: MediaDeviceInfoLike
|
|
|
204
195
|
* guess the state more accurately
|
|
205
196
|
*/
|
|
206
197
|
export declare const toPermissionState: (anyGrantedDevice: boolean, anyLiveTrack?: boolean) => PermissionState;
|
|
207
|
-
export declare const queryPermissionFallback: (name:
|
|
208
|
-
export declare const queryPermission: (name:
|
|
198
|
+
export declare const queryPermissionFallback: (name: "camera" | "microphone", everActiveTrack?: boolean, getDevices?: () => Promise<MediaDeviceInfo[]>) => Promise<PermissionState>;
|
|
199
|
+
export declare const queryPermission: (name: "camera" | "microphone", everActiveTrack?: boolean, getDevices?: () => Promise<MediaDeviceInfo[]>) => Promise<PermissionState>;
|
|
209
200
|
/**
|
|
210
201
|
* A wrapper for `navigator.permissions.query` with fallback to use
|
|
211
202
|
* `navigator.mediaDevices.enumerateDevices` to guess the `PermissionState`
|
|
@@ -313,7 +304,7 @@ export declare const findAudioOutputDevices: (devices: MediaDeviceInfoLike[]) =>
|
|
|
313
304
|
*
|
|
314
305
|
* @beta
|
|
315
306
|
*/
|
|
316
|
-
export declare const muteStreamTrack: (stream?: MediaStream) => (mute: boolean, mediaType?:
|
|
307
|
+
export declare const muteStreamTrack: (stream?: MediaStream) => (mute: boolean, mediaType?: "audio" | "video" | "all") => void;
|
|
317
308
|
/**
|
|
318
309
|
* Stops all tracks in the given stream
|
|
319
310
|
*
|
|
@@ -324,7 +315,7 @@ export declare const muteStreamTrack: (stream?: MediaStream) => (mute: boolean,
|
|
|
324
315
|
* @param stream - `MediaStream` which we mutate
|
|
325
316
|
* @param onStopped - callback to be called when the track is stopped
|
|
326
317
|
*/
|
|
327
|
-
export declare const stopMediaStream: (stream: MediaStream | undefined, onStopped?: (
|
|
318
|
+
export declare const stopMediaStream: (stream: MediaStream | undefined, onStopped?: (track: MediaStreamTrack) => void) => void;
|
|
328
319
|
/**
|
|
329
320
|
* Checks that tracks with a given type are enabled in the stream
|
|
330
321
|
*
|
|
@@ -335,7 +326,7 @@ export declare const stopMediaStream: (stream: MediaStream | undefined, onStoppe
|
|
|
335
326
|
*
|
|
336
327
|
* @beta
|
|
337
328
|
*/
|
|
338
|
-
export declare const areTracksEnabled: (stream: MediaStream | undefined, type:
|
|
329
|
+
export declare const areTracksEnabled: (stream: MediaStream | undefined, type: "audio" | "video") => boolean;
|
|
339
330
|
/**
|
|
340
331
|
* Check if list contains media inputs
|
|
341
332
|
*
|
package/dist/devices.js
CHANGED
|
@@ -49,39 +49,29 @@ export const getDevices = async () => {
|
|
|
49
49
|
export const toDeviceKey = (device) => toKey({ id: device.deviceId, kind: device.kind, label: device.label });
|
|
50
50
|
export const toDeviceTuple = (device) => [toDeviceKey(device), device];
|
|
51
51
|
export const toDevicesMap = (devices) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
const map = new Map();
|
|
53
|
+
for (const device of devices) {
|
|
54
|
+
const key = toDeviceKey(device);
|
|
55
|
+
if (!map.has(key)) {
|
|
56
|
+
map.set(key, device);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return map;
|
|
57
60
|
};
|
|
58
61
|
export const createTrackDevicesChanges = (prevDevices = []) => {
|
|
59
62
|
let seen = toDevicesMap(prevDevices);
|
|
60
63
|
return (devices) => {
|
|
61
64
|
const found = [];
|
|
62
|
-
const lost = [];
|
|
63
65
|
// Remove duplicated
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
if (d.label) {
|
|
68
|
-
ds.authorized.push(d);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
ds.unauthorized.push(d);
|
|
72
|
-
}
|
|
73
|
-
return ds;
|
|
74
|
-
}, { authorized: [], unauthorized: [] });
|
|
75
|
-
for (const device of authorized) {
|
|
76
|
-
if (!seen.delete(toDeviceKey(device))) {
|
|
66
|
+
const nextDeviceMap = toDevicesMap(devices);
|
|
67
|
+
for (const [key, device] of nextDeviceMap) {
|
|
68
|
+
if (!seen.delete(key)) {
|
|
77
69
|
found.push(device);
|
|
78
70
|
}
|
|
79
71
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
seen = new Map(authorized.map(toDeviceTuple));
|
|
84
|
-
return { unauthorized, authorized, found, lost, devices: uniqueDevices };
|
|
72
|
+
const lost = Array.from(seen.values());
|
|
73
|
+
seen = nextDeviceMap;
|
|
74
|
+
return { found, lost, devices: Array.from(nextDeviceMap.values()) };
|
|
85
75
|
};
|
|
86
76
|
};
|
|
87
77
|
/**
|
|
@@ -103,9 +93,9 @@ export const deviceChanged = (fn) => {
|
|
|
103
93
|
//
|
|
104
94
|
// Ref. https://caniuse.com/#search=ondevicechange
|
|
105
95
|
if (navigator.mediaDevices && 'ondevicechange' in navigator.mediaDevices) {
|
|
106
|
-
navigator.mediaDevices.
|
|
96
|
+
navigator.mediaDevices.addEventListener('devicechange', odc);
|
|
107
97
|
return () => {
|
|
108
|
-
navigator.mediaDevices.
|
|
98
|
+
navigator.mediaDevices.removeEventListener('devicechange', odc);
|
|
109
99
|
};
|
|
110
100
|
}
|
|
111
101
|
const it = window.setInterval(() => void odc(), 5000);
|
|
@@ -348,7 +338,6 @@ export const shouldRequestDevice = ({ kind, permission, request, tracks, current
|
|
|
348
338
|
}
|
|
349
339
|
switch (permission) {
|
|
350
340
|
case 'prompt':
|
|
351
|
-
return true;
|
|
352
341
|
case 'granted': {
|
|
353
342
|
if (currentDevices.size(kind) === 0) {
|
|
354
343
|
return false;
|
|
@@ -473,10 +462,13 @@ export const queryPermission = async (name, everActiveTrack = false, getDevices
|
|
|
473
462
|
* guess the state more accurately
|
|
474
463
|
* @param getDevices - A function to get the list of devices, e.g. navigator.mediaDevices.enumerateDevices
|
|
475
464
|
*/
|
|
476
|
-
export const getInputDevicePermissionState = async (anyActiveAudioTrack = false, anyActiveVideoTrack = false, getDevices = () => navigator.mediaDevices.enumerateDevices()) =>
|
|
477
|
-
audio
|
|
478
|
-
|
|
479
|
-
|
|
465
|
+
export const getInputDevicePermissionState = async (anyActiveAudioTrack = false, anyActiveVideoTrack = false, getDevices = () => navigator.mediaDevices.enumerateDevices()) => {
|
|
466
|
+
const [audio, video] = await Promise.all([
|
|
467
|
+
queryPermission('microphone', anyActiveAudioTrack, getDevices),
|
|
468
|
+
queryPermission('camera', anyActiveVideoTrack, getDevices),
|
|
469
|
+
]);
|
|
470
|
+
return { audio, video };
|
|
471
|
+
};
|
|
480
472
|
/**
|
|
481
473
|
* Find current audio output id to be used to set as sinkId
|
|
482
474
|
*
|
|
@@ -572,6 +564,11 @@ export const findVideoInputDevices = findDevicesByKind(MediaDeviceKinds.VIDEOINP
|
|
|
572
564
|
* @beta
|
|
573
565
|
*/
|
|
574
566
|
export const findAudioOutputDevices = findDevicesByKind(MediaDeviceKinds.AUDIOOUTPUT);
|
|
567
|
+
const muteTrack = (tracks, muted) => {
|
|
568
|
+
for (const track of tracks) {
|
|
569
|
+
track.enabled = !muted;
|
|
570
|
+
}
|
|
571
|
+
};
|
|
575
572
|
/**
|
|
576
573
|
* Set `MediaStreamTrack['enabled']` according to `mute` param for the provided `stream`
|
|
577
574
|
*
|
|
@@ -586,21 +583,18 @@ export const findAudioOutputDevices = findDevicesByKind(MediaDeviceKinds.AUDIOOU
|
|
|
586
583
|
* @beta
|
|
587
584
|
*/
|
|
588
585
|
export const muteStreamTrack = (stream) => (mute, mediaType = 'all') => {
|
|
586
|
+
if (!stream) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
589
|
switch (mediaType) {
|
|
590
590
|
case 'audio':
|
|
591
|
-
stream?.getAudioTracks()
|
|
592
|
-
track.enabled = !mute;
|
|
593
|
-
});
|
|
591
|
+
muteTrack(stream?.getAudioTracks(), mute);
|
|
594
592
|
break;
|
|
595
593
|
case 'video':
|
|
596
|
-
stream
|
|
597
|
-
track.enabled = !mute;
|
|
598
|
-
});
|
|
594
|
+
muteTrack(stream.getVideoTracks(), mute);
|
|
599
595
|
break;
|
|
600
596
|
default:
|
|
601
|
-
stream
|
|
602
|
-
track.enabled = !mute;
|
|
603
|
-
});
|
|
597
|
+
muteTrack(stream.getTracks(), mute);
|
|
604
598
|
break;
|
|
605
599
|
}
|
|
606
600
|
};
|
|
@@ -618,10 +612,10 @@ export const stopMediaStream = (stream, onStopped) => {
|
|
|
618
612
|
if (!stream) {
|
|
619
613
|
return;
|
|
620
614
|
}
|
|
621
|
-
stream.getTracks()
|
|
615
|
+
for (const track of stream.getTracks()) {
|
|
622
616
|
track.stop();
|
|
623
617
|
onStopped?.(track);
|
|
624
|
-
}
|
|
618
|
+
}
|
|
625
619
|
};
|
|
626
620
|
/**
|
|
627
621
|
* Checks that tracks with a given type are enabled in the stream
|
package/dist/errors.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export interface InputNotFoundErrorParams {
|
|
|
8
8
|
export declare const isInputNotFoundError: ({ input, kind, devices }: InputNotFoundErrorParams) => (error: string) => boolean;
|
|
9
9
|
export declare const normalizeGetUserMediaError: (browserError: Error, constraints: MediaStreamConstraints, devices: MediaDeviceInfoLike[]) => MediaDeviceFailure | string;
|
|
10
10
|
export declare const normalizeDeviceError: ({ audio, video, streamingAudioInput, streamingVideoInput, }: {
|
|
11
|
-
streamingAudioInput?: boolean
|
|
12
|
-
streamingVideoInput?: boolean
|
|
11
|
+
streamingAudioInput?: boolean;
|
|
12
|
+
streamingVideoInput?: boolean;
|
|
13
13
|
} & MediaDeviceRequest) => false | MediaDeviceFailure;
|
package/dist/eventEmitter.d.ts
CHANGED
|
@@ -44,10 +44,6 @@ export declare enum MediaEventType {
|
|
|
44
44
|
* Lost device from authorized device list
|
|
45
45
|
*/
|
|
46
46
|
DeviceLost = "device:lost",
|
|
47
|
-
/**
|
|
48
|
-
* Unauthorized devices
|
|
49
|
-
*/
|
|
50
|
-
DevicesUnauthorized = "devices:unauthorized",
|
|
51
47
|
/**
|
|
52
48
|
* No Input Devices, and no further device events will be emitted
|
|
53
49
|
*/
|
|
@@ -80,18 +76,12 @@ export type Events = {
|
|
|
80
76
|
type: MediaEventType.DevicesChanged;
|
|
81
77
|
} | {
|
|
82
78
|
devices: MediaDeviceInfoLike[];
|
|
83
|
-
|
|
84
|
-
unauthorizedDevices: MediaDeviceInfoLike[];
|
|
79
|
+
devicesFound: MediaDeviceInfoLike[];
|
|
85
80
|
type: MediaEventType.DevicesFound;
|
|
86
81
|
} | {
|
|
87
82
|
devices: MediaDeviceInfoLike[];
|
|
88
|
-
|
|
89
|
-
unauthorizedDevices: MediaDeviceInfoLike[];
|
|
83
|
+
devicesLost: MediaDeviceInfoLike[];
|
|
90
84
|
type: MediaEventType.DevicesLost;
|
|
91
|
-
} | {
|
|
92
|
-
devices: MediaDeviceInfoLike[];
|
|
93
|
-
authorizedDevices: MediaDeviceInfoLike[];
|
|
94
|
-
type: MediaEventType.DevicesUnauthorized;
|
|
95
85
|
} | {
|
|
96
86
|
devices: MediaDeviceInfoLike[];
|
|
97
87
|
type: MediaEventType.NoInputDevices;
|
package/dist/eventEmitter.js
CHANGED
|
@@ -44,10 +44,6 @@ export var MediaEventType;
|
|
|
44
44
|
* Lost device from authorized device list
|
|
45
45
|
*/
|
|
46
46
|
MediaEventType["DeviceLost"] = "device:lost";
|
|
47
|
-
/**
|
|
48
|
-
* Unauthorized devices
|
|
49
|
-
*/
|
|
50
|
-
MediaEventType["DevicesUnauthorized"] = "devices:unauthorized";
|
|
51
47
|
/**
|
|
52
48
|
* No Input Devices, and no further device events will be emitted
|
|
53
49
|
*/
|
package/dist/index.js
CHANGED
|
@@ -43,29 +43,20 @@ const state = () => {
|
|
|
43
43
|
devices: event.devices,
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
-
if (event.unauthorized.length) {
|
|
47
|
-
dispatch({
|
|
48
|
-
type: MediaEventType.DevicesUnauthorized,
|
|
49
|
-
devices: event.unauthorized,
|
|
50
|
-
authorizedDevices: event.authorized,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
46
|
if (event.found.length) {
|
|
54
47
|
// Can be used to trigger user notification of a potentially better device being available
|
|
55
48
|
dispatch({
|
|
56
49
|
type: MediaEventType.DevicesFound,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
devices: event.found,
|
|
50
|
+
devicesFound: event.found,
|
|
51
|
+
devices: event.devices,
|
|
60
52
|
});
|
|
61
53
|
}
|
|
62
54
|
if (event.lost.length) {
|
|
63
55
|
// Can be used to trigger user notification of no longer seen devices
|
|
64
56
|
dispatch({
|
|
65
57
|
type: MediaEventType.DevicesLost,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
devices: event.lost,
|
|
58
|
+
devicesLost: event.lost,
|
|
59
|
+
devices: event.devices,
|
|
69
60
|
});
|
|
70
61
|
for (const device of event.lost) {
|
|
71
62
|
if (streamTrackMap.has(device)) {
|
package/dist/streamTrackMap.js
CHANGED
|
@@ -52,9 +52,9 @@ export const createStreamTrackMap = (tracks) => {
|
|
|
52
52
|
* Stop all tracks and empty `streamTrackMap`
|
|
53
53
|
*/
|
|
54
54
|
const clear = () => {
|
|
55
|
-
streamTrackMap.
|
|
55
|
+
for (const track of streamTrackMap.values()) {
|
|
56
56
|
track.stop();
|
|
57
|
-
}
|
|
57
|
+
}
|
|
58
58
|
streamTrackMap.clear();
|
|
59
59
|
};
|
|
60
60
|
/**
|
package/dist/streams.js
CHANGED
|
@@ -94,6 +94,8 @@ export const createStreamTrackEventSubscriptions = (track, handlers) => {
|
|
|
94
94
|
return [];
|
|
95
95
|
});
|
|
96
96
|
return () => {
|
|
97
|
-
|
|
97
|
+
for (const unsubscribe of trackSubscriptions) {
|
|
98
|
+
unsubscribe();
|
|
99
|
+
}
|
|
98
100
|
};
|
|
99
101
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/baseLogger.ts","../src/constants.ts","../src/constraints.ts","../src/devices.ts","../src/displayMedia.ts","../src/errors.ts","../src/eventEmitter.ts","../src/getMediaStream.ts","../src/index.ts","../src/logger.ts","../src/streamTrackMap.ts","../src/streams.ts","../src/typeGuards.ts","../src/types.ts","../src/utils.ts","../../../@types/globals.d.ts"],"version":"5.7.3"}
|
package/dist/typeGuards.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConstraintDeviceParameters, DeviceConstraint, IndexedDevices, InputConstraintSet, MediaDeviceTrackInfo } from './types';
|
|
1
|
+
import type { ConstraintDeviceParameters, DeviceConstraint, FacingMode, IndexedDevices, InputConstraintSet, MediaDeviceTrackInfo } from './types';
|
|
2
2
|
export declare const isBoolean: (t: unknown) => t is boolean;
|
|
3
3
|
export declare const isUndefined: (t: unknown) => t is undefined;
|
|
4
4
|
/**
|
|
@@ -40,14 +40,14 @@ export type ConstrainBooleanKeys = (typeof CONSTRAIN_BOOLEAN_KEYS)[number];
|
|
|
40
40
|
* The keys from the `MediaTrackConstraintSet`
|
|
41
41
|
*/
|
|
42
42
|
export declare const CONSTRAINT_SET_KEYS: readonly ["aspectRatio", "frameRate", "latency", "width", "height", "sampleRate", "sampleSize", "channelCount", "facingMode", "resizeMode", "deviceId", "groupId", "echoCancellation", "autoGainControl", "noiseSuppression", "pan", "tilt", "zoom"];
|
|
43
|
-
export declare const isConstrainStringKeys: (t: unknown) => t is
|
|
44
|
-
export declare const isExtendedConstrainStringKeys: (t: unknown) => t is
|
|
45
|
-
export declare const isConstrainULongKeys: (t: unknown) => t is
|
|
46
|
-
export declare const isExtendedConstrainULongKeys: (t: unknown) => t is
|
|
47
|
-
export declare const isConstrainDoubleKeys: (t: unknown) => t is
|
|
48
|
-
export declare const isExtendedConstrainDoubleKeys: (t: unknown) => t is
|
|
49
|
-
export declare const isConstrainBooleanKeys: (t: unknown) => t is
|
|
50
|
-
export declare const isExtendedConstrainBooleanKeys: (t: unknown) => t is
|
|
43
|
+
export declare const isConstrainStringKeys: (t: unknown) => t is ConstrainStringKeys;
|
|
44
|
+
export declare const isExtendedConstrainStringKeys: (t: unknown) => t is ExtendedConstrainStringKeys;
|
|
45
|
+
export declare const isConstrainULongKeys: (t: unknown) => t is ConstrainULongKeys;
|
|
46
|
+
export declare const isExtendedConstrainULongKeys: (t: unknown) => t is ExtendedConstrainULongKeys;
|
|
47
|
+
export declare const isConstrainDoubleKeys: (t: unknown) => t is ConstrainDoubleKeys;
|
|
48
|
+
export declare const isExtendedConstrainDoubleKeys: (t: unknown) => t is ExtendedConstrainDoubleKeys;
|
|
49
|
+
export declare const isConstrainBooleanKeys: (t: unknown) => t is ConstrainBooleanKeys;
|
|
50
|
+
export declare const isExtendedConstrainBooleanKeys: (t: unknown) => t is ExtendedConstrainBooleanKeys;
|
|
51
51
|
export declare const isMediaTrackConstraintSetKey: (t: string) => t is keyof MediaTrackConstraintSet;
|
|
52
52
|
export declare const isMediaTrackConstraintsKey: (t: string) => t is keyof MediaTrackConstraints;
|
|
53
53
|
export declare const isMediaTrackConstraints: (t: unknown) => t is MediaTrackConstraints;
|
|
@@ -75,7 +75,7 @@ export declare const isConstrainRange: (t: unknown) => t is ConstrainDoubleRange
|
|
|
75
75
|
export declare const isConstrainDoubleRange: (t: unknown) => t is ConstrainDoubleRange;
|
|
76
76
|
export declare const isConstrainULongRange: (t: unknown) => t is ConstrainULongRange;
|
|
77
77
|
export declare const isConstraintDeviceParameters: (t: unknown) => t is ConstraintDeviceParameters;
|
|
78
|
-
export declare const isConstraintSetDevice: (t: unknown) => t is
|
|
78
|
+
export declare const isConstraintSetDevice: (t: unknown) => t is InputConstraintSet["device"];
|
|
79
79
|
type ExtendedConstraintSet = Pick<InputConstraintSet, ExtendedConstrainULongKeys | ExtendedConstrainDoubleKeys | ExtendedConstrainStringKeys | ExtendedConstrainBooleanKeys | 'device'>;
|
|
80
80
|
export declare const isExtendedConstraint: (t: unknown) => t is ExtendedConstraintSet;
|
|
81
81
|
export declare const isInputConstraintSet: (t: unknown) => t is InputConstraintSet;
|
|
@@ -85,7 +85,7 @@ export declare const isInputConstraintSet: (t: unknown) => t is InputConstraintS
|
|
|
85
85
|
* @beta
|
|
86
86
|
*/
|
|
87
87
|
export declare const isMediaStreamTrack: (m: unknown) => m is MediaStreamTrack;
|
|
88
|
-
export declare const isFacingMode: (s: unknown) => s is
|
|
88
|
+
export declare const isFacingMode: (s: unknown) => s is FacingMode;
|
|
89
89
|
export declare const isIndexedDevices: (t: unknown) => t is IndexedDevices;
|
|
90
90
|
export declare const isMediaDeviceTrackInfo: (t: unknown) => t is MediaDeviceTrackInfo;
|
|
91
91
|
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -21,15 +21,29 @@ export interface IndexedDevices {
|
|
|
21
21
|
/**
|
|
22
22
|
* Get devices by kind and device id or label
|
|
23
23
|
* When both `deviceId` and `label` are provided, it will use `deviceId` to
|
|
24
|
-
*
|
|
24
|
+
* find the device, and when it's not found, it will use `label` to find
|
|
25
|
+
*
|
|
26
|
+
* When device is not provided, it returns all devices.
|
|
25
27
|
*
|
|
26
28
|
* @param device - the device to find
|
|
27
29
|
* @returns found devices otherwise empty array
|
|
28
30
|
*/
|
|
29
31
|
get(device?: Pick<Partial<MediaDeviceInfoLike>, 'deviceId' | 'groupId' | 'label' | 'kind'>): MediaDeviceInfoLike[];
|
|
32
|
+
/**
|
|
33
|
+
* Size of particular kind of devices. When kind is not specified, it
|
|
34
|
+
* returns the total size.
|
|
35
|
+
*/
|
|
30
36
|
size(kind?: MediaDeviceKind): number;
|
|
37
|
+
/**
|
|
38
|
+
* First device of the kind
|
|
39
|
+
*/
|
|
31
40
|
first(kind: MediaDeviceInfo['kind']): MediaDeviceInfoLike | undefined;
|
|
32
41
|
toJSON(): Record<MediaDeviceKind, MediaDeviceInfoLike[]>;
|
|
42
|
+
/**
|
|
43
|
+
* `true` when there is any authorized device of the kind. When kind is not
|
|
44
|
+
* provided, it checks for any audio or video input device.
|
|
45
|
+
*/
|
|
46
|
+
anyAuthorizedDevice(kind?: MediaDeviceKind): boolean;
|
|
33
47
|
}
|
|
34
48
|
export type DeviceConstraint = MediaDeviceInfoLike | MediaDeviceInfoLike[];
|
|
35
49
|
export interface NormalizedConstraintDeviceParameters {
|
package/dist/utils.d.ts
CHANGED
|
@@ -16,12 +16,12 @@ export declare const isDeviceGranted: (device: MediaDeviceInfoLike) => boolean;
|
|
|
16
16
|
export declare const not: <T = void>(fn: (arg: T) => boolean) => (arg: T) => boolean;
|
|
17
17
|
/**
|
|
18
18
|
* Create a device ID from provided `device`.
|
|
19
|
-
* The device ID here is in the format of `
|
|
19
|
+
* The device ID here is in the format of `deviceId:kind`, be default.
|
|
20
20
|
*
|
|
21
21
|
* @param device - The device to create the ID from
|
|
22
22
|
* @param separator - The separator to use to join the device ID
|
|
23
23
|
*/
|
|
24
|
-
export declare const getDeviceId: (device: Pick<MediaDeviceInfoLike,
|
|
24
|
+
export declare const getDeviceId: (device: Pick<MediaDeviceInfoLike, "deviceId" | "kind">, separator?: string) => string;
|
|
25
25
|
/**
|
|
26
26
|
* Reverse the device ID to its original form i.e. `MediaDeviceInfo`
|
|
27
27
|
* The device ID here is in the format of `groupId:deviceId:kind`, be default.
|
|
@@ -31,7 +31,6 @@ export declare const getDeviceId: (device: Pick<MediaDeviceInfoLike, 'groupId' |
|
|
|
31
31
|
*/
|
|
32
32
|
export declare const reverseDeviceId: (id: string, separator?: string) => {
|
|
33
33
|
deviceId: string;
|
|
34
|
-
groupId: string;
|
|
35
34
|
kind: MediaDeviceKind;
|
|
36
35
|
};
|
|
37
36
|
/**
|
|
@@ -45,7 +44,7 @@ export declare const createIndexedDevices: (devices: MediaDeviceInfoLike[]) => I
|
|
|
45
44
|
*
|
|
46
45
|
* @beta
|
|
47
46
|
*/
|
|
48
|
-
export declare const compareDevices: (deviceInfo: MediaDeviceInfoLike, key?: Exclude<keyof MediaDeviceInfoLike,
|
|
47
|
+
export declare const compareDevices: (deviceInfo: MediaDeviceInfoLike, key?: Exclude<keyof MediaDeviceInfoLike, "kind" | "settings">) => (anotherDeviceInfo: MediaDeviceInfoLike) => boolean;
|
|
49
48
|
/**
|
|
50
49
|
* Lookup the `device` from `devices` list
|
|
51
50
|
*
|
package/dist/utils.js
CHANGED
|
@@ -17,12 +17,12 @@ export const isDeviceGranted = (device) => Boolean(device.label);
|
|
|
17
17
|
export const not = (fn) => (arg) => !fn(arg);
|
|
18
18
|
/**
|
|
19
19
|
* Create a device ID from provided `device`.
|
|
20
|
-
* The device ID here is in the format of `
|
|
20
|
+
* The device ID here is in the format of `deviceId:kind`, be default.
|
|
21
21
|
*
|
|
22
22
|
* @param device - The device to create the ID from
|
|
23
23
|
* @param separator - The separator to use to join the device ID
|
|
24
24
|
*/
|
|
25
|
-
export const getDeviceId = (device, separator = DEVICE_ID_SEPARATOR) => [device.
|
|
25
|
+
export const getDeviceId = (device, separator = DEVICE_ID_SEPARATOR) => [device.deviceId, device.kind].join(separator);
|
|
26
26
|
/**
|
|
27
27
|
* Reverse the device ID to its original form i.e. `MediaDeviceInfo`
|
|
28
28
|
* The device ID here is in the format of `groupId:deviceId:kind`, be default.
|
|
@@ -31,20 +31,35 @@ export const getDeviceId = (device, separator = DEVICE_ID_SEPARATOR) => [device.
|
|
|
31
31
|
* @param separator - The separator used to split the device ID
|
|
32
32
|
*/
|
|
33
33
|
export const reverseDeviceId = (id, separator = DEVICE_ID_SEPARATOR) => {
|
|
34
|
-
const [
|
|
35
|
-
assert(groupId !== undefined, `Invalid id[${id}] format: groupId`);
|
|
34
|
+
const [deviceId, kind] = id.split(separator);
|
|
36
35
|
assert(deviceId !== undefined, `Invalid id[${id}] format: deviceId`);
|
|
37
36
|
assert(kind === 'audioinput' ||
|
|
38
37
|
kind === 'videoinput' ||
|
|
39
|
-
kind === 'audiooutput', `Invalid id[${id}] format: kind`);
|
|
40
|
-
return { deviceId,
|
|
38
|
+
kind === 'audiooutput', `Invalid id[${id}] format: kind[${kind}]`);
|
|
39
|
+
return { deviceId, kind: kind };
|
|
41
40
|
};
|
|
41
|
+
const EMPTY = [];
|
|
42
42
|
/**
|
|
43
43
|
* Create an `IndexedDevices` construct from provided `devices` which index the
|
|
44
44
|
* device by device ID or kind.
|
|
45
45
|
*/
|
|
46
46
|
export const createIndexedDevices = (devices) => {
|
|
47
|
+
const anyAuthorizedDevice = {
|
|
48
|
+
audioinput: false,
|
|
49
|
+
videoinput: false,
|
|
50
|
+
audiooutput: false,
|
|
51
|
+
};
|
|
52
|
+
const deviceIdCache = new Map();
|
|
53
|
+
const kindCache = new Map();
|
|
47
54
|
const emptyIndex = {
|
|
55
|
+
anyAuthorizedDevice(kind) {
|
|
56
|
+
if (kind) {
|
|
57
|
+
return anyAuthorizedDevice[kind];
|
|
58
|
+
}
|
|
59
|
+
// This is a handy check to input device
|
|
60
|
+
return (anyAuthorizedDevice['audioinput'] ||
|
|
61
|
+
anyAuthorizedDevice['videoinput']);
|
|
62
|
+
},
|
|
48
63
|
audioinput: {
|
|
49
64
|
deviceId: new Map(),
|
|
50
65
|
label: new Map(),
|
|
@@ -92,19 +107,32 @@ export const createIndexedDevices = (devices) => {
|
|
|
92
107
|
const deviceIdMap = this[kind].deviceId;
|
|
93
108
|
const findSimilarDevices = (label) => {
|
|
94
109
|
const foundSimilar = this[kind].label.get(label);
|
|
95
|
-
return foundSimilar
|
|
110
|
+
return foundSimilar ?? EMPTY;
|
|
96
111
|
};
|
|
97
112
|
if (deviceId !== undefined) {
|
|
113
|
+
const cacheId = getDeviceId({ deviceId, kind });
|
|
114
|
+
const cachedDevice = deviceIdCache.get(cacheId);
|
|
115
|
+
if (cachedDevice) {
|
|
116
|
+
return cachedDevice;
|
|
117
|
+
}
|
|
98
118
|
const foundExact = deviceIdMap.get(deviceId);
|
|
99
119
|
if (!foundExact && label) {
|
|
100
120
|
return findSimilarDevices(label);
|
|
101
121
|
}
|
|
102
|
-
|
|
122
|
+
const devicesFound = foundExact ? [foundExact] : EMPTY;
|
|
123
|
+
deviceIdCache.set(cacheId, devicesFound);
|
|
124
|
+
return devicesFound;
|
|
103
125
|
}
|
|
104
126
|
if (label) {
|
|
105
127
|
return findSimilarDevices(label);
|
|
106
128
|
}
|
|
107
|
-
|
|
129
|
+
const cachedDevices = kindCache.get(kind);
|
|
130
|
+
if (cachedDevices) {
|
|
131
|
+
return cachedDevices;
|
|
132
|
+
}
|
|
133
|
+
const devices = Array.from(deviceIdMap.values());
|
|
134
|
+
kindCache.set(kind, devices);
|
|
135
|
+
return devices;
|
|
108
136
|
},
|
|
109
137
|
first(kind) {
|
|
110
138
|
if (!kind) {
|
|
@@ -124,14 +152,16 @@ export const createIndexedDevices = (devices) => {
|
|
|
124
152
|
};
|
|
125
153
|
return devices.reduce((acc, device) => {
|
|
126
154
|
// We don't want to index devices that are not granted
|
|
127
|
-
if (device.
|
|
155
|
+
if (device.deviceId !== undefined) {
|
|
128
156
|
acc[device.kind].deviceId.set(device.deviceId, device);
|
|
129
157
|
}
|
|
130
|
-
if (device.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
acc[device.kind].label.set(device.label, labelDevices);
|
|
158
|
+
if (anyAuthorizedDevice[device.kind] === false &&
|
|
159
|
+
isDeviceGranted(device)) {
|
|
160
|
+
anyAuthorizedDevice[device.kind] = true;
|
|
134
161
|
}
|
|
162
|
+
const labelDevices = acc[device.kind].label.get(device.label) ?? [];
|
|
163
|
+
labelDevices.push(device);
|
|
164
|
+
acc[device.kind].label.set(device.label, labelDevices);
|
|
135
165
|
return acc;
|
|
136
166
|
}, emptyIndex);
|
|
137
167
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pexip/media-control",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "20.0.0",
|
|
4
4
|
"homepage": "https://gitlab.com/pexip/zoo",
|
|
5
5
|
"bugs": "https://gitlab.com/pexip/zoo/issues",
|
|
6
6
|
"repository": {
|
|
@@ -13,34 +13,49 @@
|
|
|
13
13
|
"author": "Pexip <pexip@pexip.com>",
|
|
14
14
|
"module": "dist/index.js",
|
|
15
15
|
"types": "dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./*": {
|
|
22
|
+
"types": "./dist/*.d.ts",
|
|
23
|
+
"import": "./dist/*.js"
|
|
24
|
+
},
|
|
25
|
+
"./*.js": {
|
|
26
|
+
"types": "./dist/*.d.ts",
|
|
27
|
+
"import": "./dist/*.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
16
30
|
"files": [
|
|
17
31
|
"dist"
|
|
18
32
|
],
|
|
19
33
|
"scripts": {
|
|
20
34
|
"build": "pexip-bundler build",
|
|
35
|
+
"build:sourcemap": "pexip-bundler build --sourcemap",
|
|
21
36
|
"clean": "rm -rf dist",
|
|
22
37
|
"dev": "pexip-bundler dev",
|
|
23
|
-
"prepack": "yarn clean && yarn build
|
|
38
|
+
"prepack": "yarn clean && yarn build",
|
|
24
39
|
"test": "jest",
|
|
25
40
|
"check-format": "prettier --ignore-path=../../.prettierignore --check .",
|
|
26
41
|
"format": "prettier --ignore-path=../../.prettierignore --write .",
|
|
27
|
-
"lint": "yarn run -T
|
|
42
|
+
"lint": "yarn run -T biome lint",
|
|
28
43
|
"typecheck": "yarn tsc --noEmit -p tsconfig.build.json"
|
|
29
44
|
},
|
|
30
45
|
"dependencies": {
|
|
31
|
-
"@pexip/utils": "
|
|
46
|
+
"@pexip/utils": "17.0.0"
|
|
32
47
|
},
|
|
33
48
|
"devDependencies": {
|
|
34
49
|
"@jest/globals": "^29.7.0",
|
|
35
|
-
"@pexip/bundler": "
|
|
36
|
-
"@swc/core": "^1.
|
|
37
|
-
"@swc/jest": "^0.2.
|
|
50
|
+
"@pexip/bundler": "18.0.0",
|
|
51
|
+
"@swc/core": "^1.10.12",
|
|
52
|
+
"@swc/jest": "^0.2.37",
|
|
38
53
|
"@types/uuid": "^8.3.0",
|
|
39
54
|
"@types/webrtc": "^0.0.31",
|
|
40
55
|
"jest": "^29.5.12",
|
|
41
56
|
"jest-junit": "^16.0.0",
|
|
42
57
|
"prettier": "^3.2.5",
|
|
43
|
-
"typescript": "~5.3
|
|
58
|
+
"typescript": "~5.7.3",
|
|
44
59
|
"uuid": "^11.0.0"
|
|
45
60
|
},
|
|
46
61
|
"publishConfig": {
|