@stream-io/video-client 0.3.28 → 0.3.30
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 +14 -0
- package/README.md +6 -4
- package/dist/index.browser.es.js +382 -118
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +382 -116
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +382 -118
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +14 -10
- package/dist/src/devices/CameraManager.d.ts +0 -1
- package/dist/src/devices/InputMediaDeviceManager.d.ts +18 -15
- package/dist/src/devices/InputMediaDeviceManagerState.d.ts +22 -6
- package/dist/src/devices/MicrophoneManager.d.ts +0 -1
- package/dist/src/devices/ScreenShareManager.d.ts +39 -0
- package/dist/src/devices/ScreenShareState.d.ts +36 -0
- package/dist/src/devices/__tests__/ScreenShareManager.test.d.ts +1 -0
- package/dist/src/devices/__tests__/mocks.d.ts +3 -7
- package/dist/src/devices/index.d.ts +2 -0
- package/dist/src/helpers/DynascaleManager.d.ts +3 -2
- package/dist/src/helpers/__tests__/hq-audio-sdp.d.ts +1 -0
- package/dist/src/helpers/sdp-munging.d.ts +8 -0
- package/dist/src/rtc/Publisher.d.ts +7 -4
- package/dist/src/rtc/helpers/tracks.d.ts +2 -1
- package/dist/src/rtc/videoLayers.d.ts +2 -1
- package/dist/src/types.d.ts +20 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +56 -12
- package/src/devices/CameraManager.ts +3 -4
- package/src/devices/InputMediaDeviceManager.ts +60 -45
- package/src/devices/InputMediaDeviceManagerState.ts +34 -14
- package/src/devices/MicrophoneManager.ts +3 -4
- package/src/devices/ScreenShareManager.ts +85 -0
- package/src/devices/ScreenShareState.ts +63 -0
- package/src/devices/__tests__/InputMediaDeviceManager.test.ts +16 -1
- package/src/devices/__tests__/ScreenShareManager.test.ts +119 -0
- package/src/devices/__tests__/mocks.ts +38 -1
- package/src/devices/devices.ts +10 -1
- package/src/devices/index.ts +2 -0
- package/src/helpers/DynascaleManager.ts +18 -3
- package/src/helpers/__tests__/DynascaleManager.test.ts +36 -1
- package/src/helpers/__tests__/hq-audio-sdp.ts +332 -0
- package/src/helpers/__tests__/sdp-munging.test.ts +13 -1
- package/src/helpers/sdp-munging.ts +49 -0
- package/src/rtc/Publisher.ts +87 -48
- package/src/rtc/Subscriber.ts +4 -1
- package/src/rtc/helpers/tracks.ts +16 -6
- package/src/rtc/videoLayers.ts +4 -2
- package/src/store/CallState.ts +3 -2
- package/src/store/__tests__/CallState.test.ts +1 -1
- package/src/types.ts +27 -0
package/dist/src/Call.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { Publisher, SfuEventKinds, SfuEventListener, Subscriber } from './rtc';
|
|
|
2
2
|
import { TrackType } from './gen/video/sfu/models/models';
|
|
3
3
|
import { CallState } from './store';
|
|
4
4
|
import { AcceptCallResponse, BlockUserResponse, EndCallResponse, GetCallResponse, GetOrCreateCallRequest, GetOrCreateCallResponse, GoLiveRequest, GoLiveResponse, ListRecordingsResponse, MuteUsersResponse, PinRequest, PinResponse, QueryMembersRequest, QueryMembersResponse, RejectCallResponse, RequestPermissionRequest, RequestPermissionResponse, SendEventResponse, SendReactionRequest, SendReactionResponse, StartHLSBroadcastingResponse, StartRecordingResponse, StopHLSBroadcastingResponse, StopLiveResponse, StopRecordingResponse, UnblockUserResponse, UnpinRequest, UnpinResponse, UpdateCallMembersRequest, UpdateCallMembersResponse, UpdateCallRequest, UpdateCallResponse, UpdateUserPermissionsRequest, UpdateUserPermissionsResponse } from './gen/coordinator';
|
|
5
|
-
import { CallConstructor, CallLeaveOptions, DebounceType, JoinCallData, PublishOptions, SubscriptionChanges, VideoTrackType } from './types';
|
|
5
|
+
import { AudioTrackType, CallConstructor, CallLeaveOptions, DebounceType, JoinCallData, PublishOptions, SubscriptionChanges, TrackMuteType, VideoTrackType } from './types';
|
|
6
6
|
import { DynascaleManager } from './helpers/DynascaleManager';
|
|
7
7
|
import { PermissionsContext } from './permissions';
|
|
8
8
|
import { StreamClient } from './coordinator/connection/client';
|
|
9
9
|
import { CallEventHandler, CallEventTypes, EventTypes, Logger } from './coordinator/connection/types';
|
|
10
|
-
import { CameraManager, MicrophoneManager, SpeakerManager } from './devices';
|
|
10
|
+
import { CameraManager, MicrophoneManager, ScreenShareManager, SpeakerManager } from './devices';
|
|
11
11
|
/**
|
|
12
12
|
* An object representation of a `Call`.
|
|
13
13
|
*/
|
|
@@ -45,6 +45,10 @@ export declare class Call {
|
|
|
45
45
|
* Device manager for the speaker.
|
|
46
46
|
*/
|
|
47
47
|
readonly speaker: SpeakerManager;
|
|
48
|
+
/**
|
|
49
|
+
* Device manager for the screen.
|
|
50
|
+
*/
|
|
51
|
+
readonly screenShare: ScreenShareManager;
|
|
48
52
|
/**
|
|
49
53
|
* The DynascaleManager instance.
|
|
50
54
|
*/
|
|
@@ -198,7 +202,6 @@ export declare class Call {
|
|
|
198
202
|
* Consecutive calls to this method will replace the audio stream that is currently being published.
|
|
199
203
|
* The previous audio stream will be stopped.
|
|
200
204
|
*
|
|
201
|
-
*
|
|
202
205
|
* @param audioStream the audio stream to publish.
|
|
203
206
|
*/
|
|
204
207
|
publishAudioStream: (audioStream: MediaStream) => Promise<void>;
|
|
@@ -208,10 +211,10 @@ export declare class Call {
|
|
|
208
211
|
* Consecutive calls to this method will replace the previous screen-share stream.
|
|
209
212
|
* The previous screen-share stream will be stopped.
|
|
210
213
|
*
|
|
211
|
-
*
|
|
212
214
|
* @param screenShareStream the screen-share stream to publish.
|
|
215
|
+
* @param opts the options to use when publishing the stream.
|
|
213
216
|
*/
|
|
214
|
-
publishScreenShareStream: (screenShareStream: MediaStream) => Promise<void>;
|
|
217
|
+
publishScreenShareStream: (screenShareStream: MediaStream, opts?: PublishOptions) => Promise<void>;
|
|
215
218
|
/**
|
|
216
219
|
* Stops publishing the given track type to the call, if it is currently being published.
|
|
217
220
|
* Underlying track will be stopped and removed from the publisher.
|
|
@@ -322,26 +325,26 @@ export declare class Call {
|
|
|
322
325
|
*
|
|
323
326
|
* @param type the type of the mute operation.
|
|
324
327
|
*/
|
|
325
|
-
muteSelf: (type:
|
|
328
|
+
muteSelf: (type: TrackMuteType) => Promise<MuteUsersResponse> | undefined;
|
|
326
329
|
/**
|
|
327
330
|
* Mutes all the other participants.
|
|
328
331
|
*
|
|
329
332
|
* @param type the type of the mute operation.
|
|
330
333
|
*/
|
|
331
|
-
muteOthers: (type:
|
|
334
|
+
muteOthers: (type: TrackMuteType) => Promise<MuteUsersResponse> | undefined;
|
|
332
335
|
/**
|
|
333
336
|
* Mutes the user with the given `userId`.
|
|
334
337
|
*
|
|
335
338
|
* @param userId the id of the user to mute.
|
|
336
339
|
* @param type the type of the mute operation.
|
|
337
340
|
*/
|
|
338
|
-
muteUser: (userId: string | string[], type:
|
|
341
|
+
muteUser: (userId: string | string[], type: TrackMuteType) => Promise<MuteUsersResponse>;
|
|
339
342
|
/**
|
|
340
343
|
* Will mute all users in the call.
|
|
341
344
|
*
|
|
342
345
|
* @param type the type of the mute operation.
|
|
343
346
|
*/
|
|
344
|
-
muteAllUsers: (type:
|
|
347
|
+
muteAllUsers: (type: TrackMuteType) => Promise<MuteUsersResponse>;
|
|
345
348
|
/**
|
|
346
349
|
* Starts recording the call
|
|
347
350
|
*/
|
|
@@ -521,8 +524,9 @@ export declare class Call {
|
|
|
521
524
|
*
|
|
522
525
|
* @param audioElement the audio element to bind to.
|
|
523
526
|
* @param sessionId the session id.
|
|
527
|
+
* @param trackType the kind of audio.
|
|
524
528
|
*/
|
|
525
|
-
bindAudioElement: (audioElement: HTMLAudioElement, sessionId: string) => (() => void) | undefined;
|
|
529
|
+
bindAudioElement: (audioElement: HTMLAudioElement, sessionId: string, trackType?: AudioTrackType) => (() => void) | undefined;
|
|
526
530
|
/**
|
|
527
531
|
* Binds a DOM <img> element to this call's thumbnail (if enabled in settings).
|
|
528
532
|
*
|
|
@@ -28,5 +28,4 @@ export declare class CameraManager extends InputMediaDeviceManager<CameraManager
|
|
|
28
28
|
protected getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
|
|
29
29
|
protected publishStream(stream: MediaStream): Promise<void>;
|
|
30
30
|
protected stopPublishStream(stopTracks: boolean): Promise<void>;
|
|
31
|
-
protected getTrack(): MediaStreamTrack | undefined;
|
|
32
31
|
}
|
|
@@ -3,7 +3,7 @@ import { Call } from '../Call';
|
|
|
3
3
|
import { InputMediaDeviceManagerState } from './InputMediaDeviceManagerState';
|
|
4
4
|
import { Logger } from '../coordinator/connection/types';
|
|
5
5
|
import { TrackType } from '../gen/video/sfu/models/models';
|
|
6
|
-
export declare abstract class InputMediaDeviceManager<T extends InputMediaDeviceManagerState> {
|
|
6
|
+
export declare abstract class InputMediaDeviceManager<T extends InputMediaDeviceManagerState<C>, C = MediaTrackConstraints> {
|
|
7
7
|
protected readonly call: Call;
|
|
8
8
|
readonly state: T;
|
|
9
9
|
protected readonly trackType: TrackType;
|
|
@@ -16,7 +16,7 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
|
|
|
16
16
|
*/
|
|
17
17
|
disablePromise?: Promise<void>;
|
|
18
18
|
logger: Logger;
|
|
19
|
-
constructor(call: Call, state: T, trackType: TrackType);
|
|
19
|
+
protected constructor(call: Call, state: T, trackType: TrackType);
|
|
20
20
|
/**
|
|
21
21
|
* Lists the available audio/video devices
|
|
22
22
|
*
|
|
@@ -26,25 +26,28 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
|
|
|
26
26
|
*/
|
|
27
27
|
listDevices(): Observable<MediaDeviceInfo[]>;
|
|
28
28
|
/**
|
|
29
|
-
* Starts
|
|
29
|
+
* Starts stream.
|
|
30
30
|
*/
|
|
31
31
|
enable(): Promise<void>;
|
|
32
32
|
/**
|
|
33
|
-
* Stops
|
|
34
|
-
*
|
|
35
|
-
* @returns
|
|
33
|
+
* Stops the stream.
|
|
36
34
|
*/
|
|
37
35
|
disable(): Promise<void>;
|
|
38
36
|
/**
|
|
39
|
-
* If status was previously enabled, it will
|
|
37
|
+
* If status was previously enabled, it will re-enable the device.
|
|
40
38
|
*/
|
|
41
39
|
resume(): Promise<void>;
|
|
42
40
|
/**
|
|
43
|
-
* If current device
|
|
44
|
-
*
|
|
45
|
-
* @returns
|
|
41
|
+
* If the current device status is disabled, it will enable the device,
|
|
42
|
+
* else it will disable it.
|
|
46
43
|
*/
|
|
47
44
|
toggle(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Will set the default constraints for the device.
|
|
47
|
+
*
|
|
48
|
+
* @param constraints the constraints to set.
|
|
49
|
+
*/
|
|
50
|
+
setDefaultConstraints(constraints: C): Promise<void>;
|
|
48
51
|
/**
|
|
49
52
|
* Select device
|
|
50
53
|
*
|
|
@@ -55,14 +58,14 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
|
|
|
55
58
|
select(deviceId: string | undefined): Promise<void>;
|
|
56
59
|
protected applySettingsToStream(): Promise<void>;
|
|
57
60
|
protected abstract getDevices(): Observable<MediaDeviceInfo[]>;
|
|
58
|
-
protected abstract getStream(constraints:
|
|
61
|
+
protected abstract getStream(constraints: C): Promise<MediaStream>;
|
|
59
62
|
protected abstract publishStream(stream: MediaStream): Promise<void>;
|
|
60
63
|
protected abstract stopPublishStream(stopTracks: boolean): Promise<void>;
|
|
61
|
-
protected
|
|
64
|
+
protected getTracks(): MediaStreamTrack[];
|
|
62
65
|
protected muteStream(stopTracks?: boolean): Promise<void>;
|
|
63
|
-
private
|
|
64
|
-
private
|
|
65
|
-
private
|
|
66
|
+
private muteTracks;
|
|
67
|
+
private unmuteTracks;
|
|
68
|
+
private stopTracks;
|
|
66
69
|
private muteLocalStream;
|
|
67
70
|
protected unmuteStream(): Promise<void>;
|
|
68
71
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { BehaviorSubject
|
|
1
|
+
import { BehaviorSubject } from 'rxjs';
|
|
2
2
|
import { RxUtils } from '../store';
|
|
3
3
|
export type InputDeviceStatus = 'enabled' | 'disabled' | undefined;
|
|
4
|
-
export declare abstract class InputMediaDeviceManagerState {
|
|
4
|
+
export declare abstract class InputMediaDeviceManagerState<C = MediaTrackConstraints> {
|
|
5
5
|
readonly disableMode: 'stop-tracks' | 'disable-tracks';
|
|
6
6
|
protected statusSubject: BehaviorSubject<InputDeviceStatus>;
|
|
7
7
|
protected mediaStreamSubject: BehaviorSubject<MediaStream | undefined>;
|
|
8
8
|
protected selectedDeviceSubject: BehaviorSubject<string | undefined>;
|
|
9
|
+
protected defaultConstraintsSubject: BehaviorSubject<C | undefined>;
|
|
9
10
|
/**
|
|
10
11
|
* @internal
|
|
11
12
|
*/
|
|
@@ -14,15 +15,19 @@ export declare abstract class InputMediaDeviceManagerState {
|
|
|
14
15
|
* An Observable that emits the current media stream, or `undefined` if the device is currently disabled.
|
|
15
16
|
*
|
|
16
17
|
*/
|
|
17
|
-
mediaStream$: Observable<MediaStream | undefined>;
|
|
18
|
+
mediaStream$: import("rxjs").Observable<MediaStream | undefined>;
|
|
18
19
|
/**
|
|
19
20
|
* An Observable that emits the currently selected device
|
|
20
21
|
*/
|
|
21
|
-
selectedDevice$: Observable<string | undefined>;
|
|
22
|
+
selectedDevice$: import("rxjs").Observable<string | undefined>;
|
|
22
23
|
/**
|
|
23
24
|
* An Observable that emits the device status
|
|
24
25
|
*/
|
|
25
|
-
status$: Observable<InputDeviceStatus>;
|
|
26
|
+
status$: import("rxjs").Observable<InputDeviceStatus>;
|
|
27
|
+
/**
|
|
28
|
+
* The default constraints for the device.
|
|
29
|
+
*/
|
|
30
|
+
defaultConstraints$: import("rxjs").Observable<C | undefined>;
|
|
26
31
|
constructor(disableMode?: 'stop-tracks' | 'disable-tracks');
|
|
27
32
|
/**
|
|
28
33
|
* The device status
|
|
@@ -42,7 +47,7 @@ export declare abstract class InputMediaDeviceManagerState {
|
|
|
42
47
|
*
|
|
43
48
|
* @param observable$ the observable to get the value from.
|
|
44
49
|
*/
|
|
45
|
-
getCurrentValue: <T>(observable$: Observable<T>) => T;
|
|
50
|
+
getCurrentValue: <T>(observable$: import("rxjs").Observable<T>) => T;
|
|
46
51
|
/**
|
|
47
52
|
* @internal
|
|
48
53
|
* @param status
|
|
@@ -58,6 +63,17 @@ export declare abstract class InputMediaDeviceManagerState {
|
|
|
58
63
|
* @param deviceId the device id to set.
|
|
59
64
|
*/
|
|
60
65
|
setDevice(deviceId: string | undefined): void;
|
|
66
|
+
/**
|
|
67
|
+
* Gets the default constraints for the device.
|
|
68
|
+
*/
|
|
69
|
+
get defaultConstraints(): C | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Sets the default constraints for the device.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
* @param constraints the constraints to set.
|
|
75
|
+
*/
|
|
76
|
+
setDefaultConstraints(constraints: C | undefined): void;
|
|
61
77
|
/**
|
|
62
78
|
* Updates the value of the provided Subject.
|
|
63
79
|
* An `update` can either be a new value or a function which takes
|
|
@@ -9,7 +9,6 @@ export declare class MicrophoneManager extends InputMediaDeviceManager<Microphon
|
|
|
9
9
|
protected getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
|
|
10
10
|
protected publishStream(stream: MediaStream): Promise<void>;
|
|
11
11
|
protected stopPublishStream(stopTracks: boolean): Promise<void>;
|
|
12
|
-
protected getTrack(): MediaStreamTrack | undefined;
|
|
13
12
|
private startSpeakingWhileMutedDetection;
|
|
14
13
|
private stopSpeakingWhileMutedDetection;
|
|
15
14
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { InputMediaDeviceManager } from './InputMediaDeviceManager';
|
|
3
|
+
import { ScreenShareState } from './ScreenShareState';
|
|
4
|
+
import { Call } from '../Call';
|
|
5
|
+
import { ScreenShareSettings } from '../types';
|
|
6
|
+
export declare class ScreenShareManager extends InputMediaDeviceManager<ScreenShareState, DisplayMediaStreamOptions> {
|
|
7
|
+
constructor(call: Call);
|
|
8
|
+
/**
|
|
9
|
+
* Will enable screen share audio options on supported platforms.
|
|
10
|
+
*
|
|
11
|
+
* Note: for ongoing screen share, audio won't be enabled until you
|
|
12
|
+
* re-publish the screen share stream.
|
|
13
|
+
*/
|
|
14
|
+
enableScreenShareAudio(): void;
|
|
15
|
+
/**
|
|
16
|
+
* Will disable screen share audio options on supported platforms.
|
|
17
|
+
*/
|
|
18
|
+
disableScreenShareAudio(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Returns the current screen share settings.
|
|
21
|
+
*/
|
|
22
|
+
getSettings(): ScreenShareSettings | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Sets the current screen share settings.
|
|
25
|
+
*
|
|
26
|
+
* @param settings the settings to set.
|
|
27
|
+
*/
|
|
28
|
+
setSettings(settings: ScreenShareSettings | undefined): void;
|
|
29
|
+
protected getDevices(): Observable<MediaDeviceInfo[]>;
|
|
30
|
+
protected getStream(constraints: DisplayMediaStreamOptions): Promise<MediaStream>;
|
|
31
|
+
protected publishStream(stream: MediaStream): Promise<void>;
|
|
32
|
+
protected stopPublishStream(stopTracks: boolean): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Overrides the default `select` method to throw an error.
|
|
35
|
+
*
|
|
36
|
+
* @param deviceId ignored.
|
|
37
|
+
*/
|
|
38
|
+
select(deviceId: string | undefined): Promise<void>;
|
|
39
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { InputMediaDeviceManagerState } from './InputMediaDeviceManagerState';
|
|
2
|
+
import { ScreenShareSettings } from '../types';
|
|
3
|
+
export declare class ScreenShareState extends InputMediaDeviceManagerState<DisplayMediaStreamOptions> {
|
|
4
|
+
private audioEnabledSubject;
|
|
5
|
+
private settingsSubject;
|
|
6
|
+
/**
|
|
7
|
+
* An Observable that emits the current screen share audio status.
|
|
8
|
+
*/
|
|
9
|
+
audioEnabled$: import("rxjs").Observable<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* An Observable that emits the current screen share settings.
|
|
12
|
+
*/
|
|
13
|
+
settings$: import("rxjs").Observable<ScreenShareSettings | undefined>;
|
|
14
|
+
/**
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
protected getDeviceIdFromStream: (stream: MediaStream) => string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* The current screen share audio status.
|
|
20
|
+
*/
|
|
21
|
+
get audioEnabled(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Set the current screen share audio status.
|
|
24
|
+
*/
|
|
25
|
+
setAudioEnabled(isEnabled: boolean): void;
|
|
26
|
+
/**
|
|
27
|
+
* The current screen share settings.
|
|
28
|
+
*/
|
|
29
|
+
get settings(): ScreenShareSettings | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Set the current screen share settings.
|
|
32
|
+
*
|
|
33
|
+
* @param settings the screen share settings to set.
|
|
34
|
+
*/
|
|
35
|
+
setSettings(settings: ScreenShareSettings | undefined): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Call } from '../../Call';
|
|
2
2
|
export declare const mockVideoDevices: MediaDeviceInfo[];
|
|
3
3
|
export declare const mockAudioDevices: MediaDeviceInfo[];
|
|
4
|
-
export declare const mockCall: () =>
|
|
5
|
-
state: CallState;
|
|
6
|
-
publishVideoStream: import("@vitest/spy").Mock<any, any>;
|
|
7
|
-
publishAudioStream: import("@vitest/spy").Mock<any, any>;
|
|
8
|
-
stopPublish: import("@vitest/spy").Mock<any, any>;
|
|
9
|
-
};
|
|
4
|
+
export declare const mockCall: () => Partial<Call>;
|
|
10
5
|
export declare const mockAudioStream: () => MediaStream;
|
|
11
6
|
export declare const mockVideoStream: () => MediaStream;
|
|
7
|
+
export declare const mockScreenShareStream: (includeAudio?: boolean) => MediaStream;
|
|
@@ -5,5 +5,7 @@ export * from './CameraManager';
|
|
|
5
5
|
export * from './CameraManagerState';
|
|
6
6
|
export * from './MicrophoneManager';
|
|
7
7
|
export * from './MicrophoneManagerState';
|
|
8
|
+
export * from './ScreenShareManager';
|
|
9
|
+
export * from './ScreenShareState';
|
|
8
10
|
export * from './SpeakerManager';
|
|
9
11
|
export * from './SpeakerState';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Call } from '../Call';
|
|
2
|
-
import { VideoTrackType } from '../types';
|
|
2
|
+
import { AudioTrackType, VideoTrackType } from '../types';
|
|
3
3
|
import { ViewportTracker } from './ViewportTracker';
|
|
4
4
|
/**
|
|
5
5
|
* A manager class that handles dynascale related tasks like:
|
|
@@ -64,7 +64,8 @@ export declare class DynascaleManager {
|
|
|
64
64
|
*
|
|
65
65
|
* @param audioElement the audio element to bind to.
|
|
66
66
|
* @param sessionId the session id.
|
|
67
|
+
* @param trackType the kind of audio.
|
|
67
68
|
* @returns a cleanup function that will unbind the audio element.
|
|
68
69
|
*/
|
|
69
|
-
bindAudioElement: (audioElement: HTMLAudioElement, sessionId: string) => (() => void) | undefined;
|
|
70
|
+
bindAudioElement: (audioElement: HTMLAudioElement, sessionId: string, trackType: AudioTrackType) => (() => void) | undefined;
|
|
70
71
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const initialSdp: string;
|
|
@@ -23,3 +23,11 @@ export declare const removeCodec: (sdp: string, mediaType: 'video' | 'audio', co
|
|
|
23
23
|
* Returns an SDP with DTX enabled or disabled.
|
|
24
24
|
*/
|
|
25
25
|
export declare const toggleDtx: (sdp: string, enable: boolean) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Enables high-quality audio through SDP munging for the given trackMid.
|
|
28
|
+
*
|
|
29
|
+
* @param sdp the SDP to munge.
|
|
30
|
+
* @param trackMid the trackMid.
|
|
31
|
+
* @param maxBitrate the max bitrate to set.
|
|
32
|
+
*/
|
|
33
|
+
export declare const enableHighQualityAudio: (sdp: string, trackMid: string, maxBitrate?: number) => string;
|
|
@@ -20,6 +20,7 @@ export declare class Publisher {
|
|
|
20
20
|
private pc;
|
|
21
21
|
private readonly state;
|
|
22
22
|
private readonly transceiverRegistry;
|
|
23
|
+
private readonly publishOptionsPerTrackType;
|
|
23
24
|
/**
|
|
24
25
|
* An array maintaining the order how transceivers were added to the peer connection.
|
|
25
26
|
* This is needed because some browsers (Firefox) don't reliably report
|
|
@@ -63,10 +64,11 @@ export declare class Publisher {
|
|
|
63
64
|
*
|
|
64
65
|
* Consecutive calls to this method will replace the stream.
|
|
65
66
|
* The previous stream will be stopped.
|
|
66
|
-
*
|
|
67
|
-
* @param
|
|
68
|
-
* @param
|
|
69
|
-
* @param
|
|
67
|
+
*
|
|
68
|
+
* @param mediaStream the media stream to publish.
|
|
69
|
+
* @param track the track to publish.
|
|
70
|
+
* @param trackType the track type to publish.
|
|
71
|
+
* @param opts the optional publish options to use.
|
|
70
72
|
*/
|
|
71
73
|
publishStream: (mediaStream: MediaStream, track: MediaStreamTrack, trackType: TrackType, opts?: PublishOptions) => Promise<void>;
|
|
72
74
|
/**
|
|
@@ -123,6 +125,7 @@ export declare class Publisher {
|
|
|
123
125
|
*/
|
|
124
126
|
private negotiate;
|
|
125
127
|
private mungeCodecs;
|
|
128
|
+
private extractMid;
|
|
126
129
|
getCurrentTrackInfos: (sdp?: string) => TrackInfo[];
|
|
127
130
|
private onIceCandidateError;
|
|
128
131
|
private onIceConnectionStateChange;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { TrackType } from '../../gen/video/sfu/models/models';
|
|
2
2
|
import type { StreamVideoLocalParticipant, StreamVideoParticipant } from '../../types';
|
|
3
|
+
import { TrackMuteType } from '../../types';
|
|
3
4
|
export declare const trackTypeToParticipantStreamKey: (trackType: TrackType) => keyof StreamVideoParticipant;
|
|
4
5
|
export declare const trackTypeToDeviceIdKey: (trackType: TrackType) => keyof StreamVideoLocalParticipant | undefined;
|
|
5
|
-
export declare const muteTypeToTrackType: (muteType:
|
|
6
|
+
export declare const muteTypeToTrackType: (muteType: TrackMuteType) => TrackType;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ScreenShareSettings } from '../types';
|
|
1
2
|
import { TargetResolution } from '../gen/coordinator';
|
|
2
3
|
export type OptimalVideoLayer = RTCRtpEncodingParameters & {
|
|
3
4
|
width: number;
|
|
@@ -23,4 +24,4 @@ export declare const findOptimalVideoLayers: (videoTrack: MediaStreamTrack, targ
|
|
|
23
24
|
* @param currentHeight the current height of the track.
|
|
24
25
|
*/
|
|
25
26
|
export declare const getComputedMaxBitrate: (targetResolution: TargetResolution, currentWidth: number, currentHeight: number) => number;
|
|
26
|
-
export declare const findOptimalScreenSharingLayers: (videoTrack: MediaStreamTrack) => OptimalVideoLayer[];
|
|
27
|
+
export declare const findOptimalScreenSharingLayers: (videoTrack: MediaStreamTrack, preferences?: ScreenShareSettings) => OptimalVideoLayer[];
|
package/dist/src/types.d.ts
CHANGED
|
@@ -32,6 +32,11 @@ export interface StreamVideoParticipant extends Participant {
|
|
|
32
32
|
* and we are subscribed to it.
|
|
33
33
|
*/
|
|
34
34
|
screenShareStream?: MediaStream;
|
|
35
|
+
/**
|
|
36
|
+
* The participant's screen audio stream, if they are sharing their audio,
|
|
37
|
+
* and we are subscribed to it.
|
|
38
|
+
*/
|
|
39
|
+
screenShareAudioStream?: MediaStream;
|
|
35
40
|
/**
|
|
36
41
|
* The preferred video dimensions for this participant.
|
|
37
42
|
* Set it to `undefined` to unsubscribe from this participant's video.
|
|
@@ -83,6 +88,8 @@ export interface StreamVideoLocalParticipant extends StreamVideoParticipant {
|
|
|
83
88
|
audioOutputDeviceId?: string;
|
|
84
89
|
}
|
|
85
90
|
export type VideoTrackType = 'videoTrack' | 'screenShareTrack';
|
|
91
|
+
export type AudioTrackType = 'audioTrack' | 'screenShareAudioTrack';
|
|
92
|
+
export type TrackMuteType = 'audio' | 'video' | 'screenshare' | 'screenshare_audio';
|
|
86
93
|
/**
|
|
87
94
|
* Represents a participant's pin state.
|
|
88
95
|
*/
|
|
@@ -120,6 +127,19 @@ export type SubscriptionChanges = {
|
|
|
120
127
|
};
|
|
121
128
|
export type PublishOptions = {
|
|
122
129
|
preferredCodec?: string | null;
|
|
130
|
+
screenShareSettings?: ScreenShareSettings;
|
|
131
|
+
};
|
|
132
|
+
export type ScreenShareSettings = {
|
|
133
|
+
/**
|
|
134
|
+
* Limits the maximum framerate (in frames per second) of the screen share.
|
|
135
|
+
* Defaults to 30.
|
|
136
|
+
*/
|
|
137
|
+
maxFramerate?: number;
|
|
138
|
+
/**
|
|
139
|
+
* Limits the maximum bitrate (in bits per second) of the screen share.
|
|
140
|
+
* Defaults to 3000000 (3Mbps).
|
|
141
|
+
*/
|
|
142
|
+
maxBitrate?: number;
|
|
123
143
|
};
|
|
124
144
|
export type CallLeaveOptions = {
|
|
125
145
|
/**
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.3.
|
|
1
|
+
export declare const version = "0.3.30";
|
package/package.json
CHANGED
package/src/Call.ts
CHANGED
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
} from './gen/coordinator';
|
|
69
69
|
import { join, reconcileParticipantLocalState } from './rtc/flows/join';
|
|
70
70
|
import {
|
|
71
|
+
AudioTrackType,
|
|
71
72
|
CallConstructor,
|
|
72
73
|
CallLeaveOptions,
|
|
73
74
|
DebounceType,
|
|
@@ -76,6 +77,7 @@ import {
|
|
|
76
77
|
StreamVideoParticipant,
|
|
77
78
|
StreamVideoParticipantPatches,
|
|
78
79
|
SubscriptionChanges,
|
|
80
|
+
TrackMuteType,
|
|
79
81
|
VideoTrackType,
|
|
80
82
|
VisibilityState,
|
|
81
83
|
} from './types';
|
|
@@ -120,6 +122,7 @@ import {
|
|
|
120
122
|
CameraDirection,
|
|
121
123
|
CameraManager,
|
|
122
124
|
MicrophoneManager,
|
|
125
|
+
ScreenShareManager,
|
|
123
126
|
SpeakerManager,
|
|
124
127
|
} from './devices';
|
|
125
128
|
|
|
@@ -168,6 +171,11 @@ export class Call {
|
|
|
168
171
|
*/
|
|
169
172
|
readonly speaker: SpeakerManager;
|
|
170
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Device manager for the screen.
|
|
176
|
+
*/
|
|
177
|
+
readonly screenShare: ScreenShareManager;
|
|
178
|
+
|
|
171
179
|
/**
|
|
172
180
|
* The DynascaleManager instance.
|
|
173
181
|
*/
|
|
@@ -281,6 +289,7 @@ export class Call {
|
|
|
281
289
|
this.camera = new CameraManager(this);
|
|
282
290
|
this.microphone = new MicrophoneManager(this);
|
|
283
291
|
this.speaker = new SpeakerManager();
|
|
292
|
+
this.screenShare = new ScreenShareManager(this);
|
|
284
293
|
}
|
|
285
294
|
|
|
286
295
|
private registerEffects() {
|
|
@@ -768,9 +777,21 @@ export class Call {
|
|
|
768
777
|
const {
|
|
769
778
|
audioStream,
|
|
770
779
|
videoStream,
|
|
771
|
-
screenShareStream
|
|
780
|
+
screenShareStream,
|
|
781
|
+
screenShareAudioStream,
|
|
772
782
|
} = localParticipant;
|
|
773
783
|
|
|
784
|
+
let screenShare: MediaStream | undefined;
|
|
785
|
+
if (screenShareStream || screenShareAudioStream) {
|
|
786
|
+
screenShare = new MediaStream();
|
|
787
|
+
screenShareStream?.getVideoTracks().forEach((track) => {
|
|
788
|
+
screenShare?.addTrack(track);
|
|
789
|
+
});
|
|
790
|
+
screenShareAudioStream?.getAudioTracks().forEach((track) => {
|
|
791
|
+
screenShare?.addTrack(track);
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
|
|
774
795
|
// restore previous publishing state
|
|
775
796
|
if (audioStream) await this.publishAudioStream(audioStream);
|
|
776
797
|
if (videoStream) await this.publishVideoStream(videoStream);
|
|
@@ -1081,7 +1102,6 @@ export class Call {
|
|
|
1081
1102
|
* Consecutive calls to this method will replace the audio stream that is currently being published.
|
|
1082
1103
|
* The previous audio stream will be stopped.
|
|
1083
1104
|
*
|
|
1084
|
-
*
|
|
1085
1105
|
* @param audioStream the audio stream to publish.
|
|
1086
1106
|
*/
|
|
1087
1107
|
publishAudioStream = async (audioStream: MediaStream) => {
|
|
@@ -1112,10 +1132,13 @@ export class Call {
|
|
|
1112
1132
|
* Consecutive calls to this method will replace the previous screen-share stream.
|
|
1113
1133
|
* The previous screen-share stream will be stopped.
|
|
1114
1134
|
*
|
|
1115
|
-
*
|
|
1116
1135
|
* @param screenShareStream the screen-share stream to publish.
|
|
1136
|
+
* @param opts the options to use when publishing the stream.
|
|
1117
1137
|
*/
|
|
1118
|
-
publishScreenShareStream = async (
|
|
1138
|
+
publishScreenShareStream = async (
|
|
1139
|
+
screenShareStream: MediaStream,
|
|
1140
|
+
opts: PublishOptions = {},
|
|
1141
|
+
) => {
|
|
1119
1142
|
// we should wait until we get a JoinResponse from the SFU,
|
|
1120
1143
|
// otherwise we risk breaking the ICETrickle flow.
|
|
1121
1144
|
await this.assertCallJoined();
|
|
@@ -1140,7 +1163,18 @@ export class Call {
|
|
|
1140
1163
|
screenShareStream,
|
|
1141
1164
|
screenShareTrack,
|
|
1142
1165
|
TrackType.SCREEN_SHARE,
|
|
1166
|
+
opts,
|
|
1143
1167
|
);
|
|
1168
|
+
|
|
1169
|
+
const [screenShareAudioTrack] = screenShareStream.getAudioTracks();
|
|
1170
|
+
if (screenShareAudioTrack) {
|
|
1171
|
+
await this.publisher.publishStream(
|
|
1172
|
+
screenShareStream,
|
|
1173
|
+
screenShareAudioTrack,
|
|
1174
|
+
TrackType.SCREEN_SHARE_AUDIO,
|
|
1175
|
+
opts,
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1144
1178
|
};
|
|
1145
1179
|
|
|
1146
1180
|
/**
|
|
@@ -1252,6 +1286,13 @@ export class Call {
|
|
|
1252
1286
|
dimension: p.screenShareDimension,
|
|
1253
1287
|
});
|
|
1254
1288
|
}
|
|
1289
|
+
if (p.publishedTracks.includes(TrackType.SCREEN_SHARE_AUDIO)) {
|
|
1290
|
+
subscriptions.push({
|
|
1291
|
+
userId: p.userId,
|
|
1292
|
+
sessionId: p.sessionId,
|
|
1293
|
+
trackType: TrackType.SCREEN_SHARE_AUDIO,
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1255
1296
|
}
|
|
1256
1297
|
// schedule update
|
|
1257
1298
|
this.trackSubscriptionsSubject.next({ type, data: subscriptions });
|
|
@@ -1414,7 +1455,7 @@ export class Call {
|
|
|
1414
1455
|
*
|
|
1415
1456
|
* @param type the type of the mute operation.
|
|
1416
1457
|
*/
|
|
1417
|
-
muteSelf = (type:
|
|
1458
|
+
muteSelf = (type: TrackMuteType) => {
|
|
1418
1459
|
const myUserId = this.currentUserId;
|
|
1419
1460
|
if (myUserId) {
|
|
1420
1461
|
return this.muteUser(myUserId, type);
|
|
@@ -1426,7 +1467,7 @@ export class Call {
|
|
|
1426
1467
|
*
|
|
1427
1468
|
* @param type the type of the mute operation.
|
|
1428
1469
|
*/
|
|
1429
|
-
muteOthers = (type:
|
|
1470
|
+
muteOthers = (type: TrackMuteType) => {
|
|
1430
1471
|
const trackType = muteTypeToTrackType(type);
|
|
1431
1472
|
if (!trackType) return;
|
|
1432
1473
|
const userIdsToMute: string[] = [];
|
|
@@ -1445,10 +1486,7 @@ export class Call {
|
|
|
1445
1486
|
* @param userId the id of the user to mute.
|
|
1446
1487
|
* @param type the type of the mute operation.
|
|
1447
1488
|
*/
|
|
1448
|
-
muteUser = (
|
|
1449
|
-
userId: string | string[],
|
|
1450
|
-
type: 'audio' | 'video' | 'screenshare',
|
|
1451
|
-
) => {
|
|
1489
|
+
muteUser = (userId: string | string[], type: TrackMuteType) => {
|
|
1452
1490
|
return this.streamClient.post<MuteUsersResponse, MuteUsersRequest>(
|
|
1453
1491
|
`${this.streamClientBasePath}/mute_users`,
|
|
1454
1492
|
{
|
|
@@ -1463,7 +1501,7 @@ export class Call {
|
|
|
1463
1501
|
*
|
|
1464
1502
|
* @param type the type of the mute operation.
|
|
1465
1503
|
*/
|
|
1466
|
-
muteAllUsers = (type:
|
|
1504
|
+
muteAllUsers = (type: TrackMuteType) => {
|
|
1467
1505
|
return this.streamClient.post<MuteUsersResponse, MuteUsersRequest>(
|
|
1468
1506
|
`${this.streamClientBasePath}/mute_users`,
|
|
1469
1507
|
{
|
|
@@ -1952,11 +1990,17 @@ export class Call {
|
|
|
1952
1990
|
*
|
|
1953
1991
|
* @param audioElement the audio element to bind to.
|
|
1954
1992
|
* @param sessionId the session id.
|
|
1993
|
+
* @param trackType the kind of audio.
|
|
1955
1994
|
*/
|
|
1956
|
-
bindAudioElement = (
|
|
1995
|
+
bindAudioElement = (
|
|
1996
|
+
audioElement: HTMLAudioElement,
|
|
1997
|
+
sessionId: string,
|
|
1998
|
+
trackType: AudioTrackType = 'audioTrack',
|
|
1999
|
+
) => {
|
|
1957
2000
|
const unbind = this.dynascaleManager.bindAudioElement(
|
|
1958
2001
|
audioElement,
|
|
1959
2002
|
sessionId,
|
|
2003
|
+
trackType,
|
|
1960
2004
|
);
|
|
1961
2005
|
|
|
1962
2006
|
if (!unbind) return;
|