@kaltura-sdk/rtc-core 1.25.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.
Files changed (41) hide show
  1. package/README.md +237 -0
  2. package/index.d.ts +1 -0
  3. package/index.esm.js +15293 -0
  4. package/package.json +22 -0
  5. package/src/index.d.ts +6 -0
  6. package/src/lib/core-utils/BrowserDetector.d.ts +101 -0
  7. package/src/lib/core-utils/DevicesUtils.d.ts +1 -0
  8. package/src/lib/core-utils/GlobalEventEmitter.d.ts +1 -0
  9. package/src/lib/core-utils/MediaUtils.d.ts +45 -0
  10. package/src/lib/core-utils/Mutex.d.ts +8 -0
  11. package/src/lib/core-utils/SdpUtils.d.ts +25 -0
  12. package/src/lib/core-utils/UserBrowserUtils.d.ts +37 -0
  13. package/src/lib/core-utils/UtilityFunctions.d.ts +21 -0
  14. package/src/lib/core-utils/index.d.ts +4 -0
  15. package/src/lib/core-utils/webrtcAudioStats.d.ts +56 -0
  16. package/src/lib/core-utils/webrtcStatsTypes.d.ts +76 -0
  17. package/src/lib/core-utils/webrtcVideoStats.d.ts +6 -0
  18. package/src/lib/devices/DevicesManager.d.ts +137 -0
  19. package/src/lib/devices/UserMediaManager.d.ts +52 -0
  20. package/src/lib/devices/index.d.ts +2 -0
  21. package/src/lib/media/AudioAnalyzer.d.ts +60 -0
  22. package/src/lib/media/GetUserMediaManager.d.ts +178 -0
  23. package/src/lib/media/MediaSources.d.ts +105 -0
  24. package/src/lib/media/index.d.ts +4 -0
  25. package/src/lib/media/media-processing/AudioProcessing.d.ts +42 -0
  26. package/src/lib/media/media-processing/AudioProcessingModes.d.ts +76 -0
  27. package/src/lib/media/media-processing/index.d.ts +4 -0
  28. package/src/lib/media/media-processing/types.d.ts +83 -0
  29. package/src/lib/media/types.d.ts +73 -0
  30. package/src/lib/peer-connection/IceHandler.d.ts +60 -0
  31. package/src/lib/peer-connection/PeerConnection.d.ts +153 -0
  32. package/src/lib/peer-connection/PeerConnectionBeacon.d.ts +208 -0
  33. package/src/lib/peer-connection/PeerConnectionManager.d.ts +57 -0
  34. package/src/lib/peer-connection/PeerConnectionWebrtcStats.d.ts +32 -0
  35. package/src/lib/peer-connection/constants.d.ts +89 -0
  36. package/src/lib/peer-connection/index.d.ts +10 -0
  37. package/src/lib/peer-connection/types.d.ts +167 -0
  38. package/src/lib/session/CoreRTCSession.d.ts +215 -0
  39. package/src/lib/session/index.d.ts +2 -0
  40. package/src/lib/simulcast/simulcastCommonPublisher.d.ts +4 -0
  41. package/src/lib/unisphere-sample.d.ts +50 -0
@@ -0,0 +1,167 @@
1
+ export declare enum StreamStatus {
2
+ Na = "Na",
3
+ new = "new",
4
+ connecting = "connecting",
5
+ getRemoteSDPOffer = "getRemoteSDPOffer",
6
+ setRemoteSDPOffer = "setRemoteSDPOffer",
7
+ getLocalSDPAnswer = "getLocalSDPAnswer",
8
+ setLocalSDPAnswer = "setLocalSDPAnswer",
9
+ createdPeerConnection = "createdPeerConnection",
10
+ gotTrackEvent = "gotTrackEvent",
11
+ connected = "connected",
12
+ createdLocalSDPOffer = "createdLocalSDPOffer",
13
+ setLocalSDPOffer = "setLocalSDPOffer",
14
+ iceGatheringDone = "iceGatheringDone",
15
+ disconnected = "disconnected",
16
+ gotRemoteSDPAnswer = "gotRemoteSDPAnswer",
17
+ setRemoteSDPAnswer = "setRemoteSDPAnswer"
18
+ }
19
+ export type LocalIceCandidateInfoObj = {
20
+ localCandidateType: string;
21
+ localRelayProtocol: string;
22
+ localProtocol: string;
23
+ localNetworkType: string;
24
+ remoteNetworkPort: string;
25
+ };
26
+ /**
27
+ * Simplified ICE candidate data for trickle ICE
28
+ * Matches the format from test_webrtc.html
29
+ */
30
+ export type IceCandidateDataObj = {
31
+ candidate: string | null | undefined;
32
+ sdpMLineIndex: number;
33
+ };
34
+ export interface PeerConnectionConfig {
35
+ isPublisher: boolean;
36
+ isDesktop?: boolean;
37
+ isAudioMix?: boolean;
38
+ retryStrategy?: RetryStrategy;
39
+ statsInterval?: number;
40
+ timeouts?: {
41
+ connectionStart?: number;
42
+ disconnectCheck?: number;
43
+ sdpAnswer?: number;
44
+ iceGathering?: number;
45
+ };
46
+ codecType?: string;
47
+ turnServerUrl?: string;
48
+ enableTrickleIce?: boolean;
49
+ }
50
+ export interface IceConfiguration {
51
+ iceServers: RTCIceServer[];
52
+ iceTransportPolicy?: RTCIceTransportPolicy;
53
+ }
54
+ export interface ConnectionFailureInfo {
55
+ iceFailure: boolean;
56
+ reason: ConnectionFailureReason | number;
57
+ subReason: number;
58
+ reasonStr: string;
59
+ wasConnected: boolean;
60
+ disconnections: Array<{
61
+ disconnectionTime: number;
62
+ disconnectReason: number;
63
+ duration: number;
64
+ totalBytes: number;
65
+ wasConnected: boolean;
66
+ }>;
67
+ lastConnFailureTime: number;
68
+ pcCreationTime: number;
69
+ localCandidateType?: string;
70
+ }
71
+ export interface RetryStrategy {
72
+ shouldRetry(attempt: number, reason: ConnectionFailureReason): boolean;
73
+ getRetryDelay(attempt: number): number;
74
+ onRetryAttempt?(attempt: number): void;
75
+ onRetrySuccess?(): void;
76
+ onRetryExhausted?(): void;
77
+ }
78
+ export interface VideoSenderConfig {
79
+ /** @see https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/contentHint */
80
+ contentHint?: string;
81
+ degradationPreference?: RTCDegradationPreference;
82
+ maxFps?: number;
83
+ maxBitrateKbps?: number;
84
+ scaleResolutionDownBy?: number;
85
+ }
86
+ export declare enum ConnectionFailureReason {
87
+ ICE_FAILED = "ice_failed",
88
+ CONNECTION_TIMEOUT = "connection_timeout",
89
+ DISCONNECTED = "disconnected",
90
+ SIGNALING_ERROR = "signaling_error",
91
+ MEDIA_ERROR = "media_error",
92
+ UNKNOWN = "unknown"
93
+ }
94
+ export interface PeerConnectionEventPayloads {
95
+ pcCreated: {
96
+ connectionId: string;
97
+ timestamp: number;
98
+ };
99
+ pcConnected: {
100
+ connectionId: string;
101
+ };
102
+ pcConnectedFinal: {
103
+ connectionId: string;
104
+ };
105
+ pcConnectionFailed: {
106
+ connectionId: string;
107
+ reason: ConnectionFailureReason;
108
+ willRetry: boolean;
109
+ iceFailure: boolean;
110
+ subReason: number;
111
+ reasonStr: string;
112
+ };
113
+ pcTrackReceived: {
114
+ connectionId: string;
115
+ track: MediaStreamTrack;
116
+ streams: ReadonlyArray<MediaStream>;
117
+ };
118
+ pcStartPublishing: {
119
+ connectionId: string;
120
+ localDescription: RTCSessionDescription;
121
+ };
122
+ pcClosed: {
123
+ connectionId: string;
124
+ };
125
+ pcStatsUpdate: {
126
+ connectionId: string;
127
+ stats: any;
128
+ };
129
+ pcConnectionGroupNeeded: {
130
+ connectionId: string;
131
+ currentGroup: any;
132
+ reason: number;
133
+ };
134
+ pcNegotiationNeeded: {
135
+ connectionId: string;
136
+ isPublisher: boolean;
137
+ };
138
+ pcLocalDescriptionCreated: {
139
+ connectionId: string;
140
+ description: RTCSessionDescriptionInit;
141
+ };
142
+ pcIceCandidate: {
143
+ connectionId: string;
144
+ candidate: RTCIceCandidate | null;
145
+ };
146
+ pcConnectionStateChange: {
147
+ connectionId: string;
148
+ state: RTCPeerConnectionState;
149
+ previousState: RTCPeerConnectionState;
150
+ };
151
+ pcIceConnectionStateChange: {
152
+ connectionId: string;
153
+ state: RTCIceConnectionState;
154
+ };
155
+ pcConnectionStartTimeout: {
156
+ connectionId: string;
157
+ };
158
+ pcDisconnectCheckTimeout: {
159
+ connectionId: string;
160
+ };
161
+ pcSdpAnswerTimeout: {
162
+ connectionId: string;
163
+ };
164
+ pcIceGatheringTimeout: {
165
+ connectionId: string;
166
+ };
167
+ }
@@ -0,0 +1,215 @@
1
+ import { GetUserMediaManager } from '../media/GetUserMediaManager';
2
+ import { MediaSources, TrackKind } from '../media/MediaSources';
3
+ import { GetUserMediaEveObj } from '../media/types';
4
+ import DevicesManager, { UserDevicesType, DeviceType } from '../devices/DevicesManager';
5
+ import { PeerConnectionManager } from '../peer-connection/PeerConnectionManager';
6
+ import PeerConnection from '../peer-connection/PeerConnection';
7
+ import { PeerConnectionConfig, ConnectionFailureInfo, IceCandidateDataObj } from '../peer-connection/types';
8
+ import { AudioNrMode } from '../media/media-processing/types';
9
+ /**
10
+ * Media track/device type: audio or video
11
+ */
12
+ export type MediaDeviceKind = 'audio' | 'video';
13
+ export declare class CoreRTCSession {
14
+ peerConnectionManager: PeerConnectionManager;
15
+ userStreams: Map<string, MediaStream>;
16
+ mediaSources: MediaSources;
17
+ devicesManager: DevicesManager;
18
+ getUserMediaManager: GetUserMediaManager;
19
+ private logger;
20
+ private audioAnalyzer;
21
+ private speakingThreshold;
22
+ private dbgAudioLoopbackActive;
23
+ constructor(devicesManager: DevicesManager);
24
+ /**
25
+ * Handle AudioContext errors - attempt recovery by re-acquiring audio
26
+ * Called by AudioProcessing when audioContext.onerror is triggered
27
+ * MATCHES ORIGINAL: mediaSetup.getUserMedia recovery logic from audioProcessing.ts
28
+ */
29
+ private onAudioContextError;
30
+ /**
31
+ * Update peer connection senders with new track
32
+ * MATCHES ORIGINAL: mdReplaceStopSenderTrack with simulcast support
33
+ *
34
+ * This callback is passed to GetUserMediaManager and called when tracks need
35
+ * to be replaced in all active peer connections (e.g., device change, unmute)
36
+ *
37
+ * @param trackKind - 'audio' or 'video'
38
+ * @param newTrack - New track to replace with
39
+ *
40
+ * @param initial - Whether this is initial setup (for simulcast)
41
+ * @returns Promise<boolean> - True if track was replaced successfully
42
+ */
43
+ private updatePeerConnectionSenders;
44
+ /**
45
+ * Release media device - complete device release with stream cleanup
46
+ * MATCHES ORIGINAL: releaseMediaDevice function from production code
47
+ *
48
+ * This callback handles the full device release flow:
49
+ * 2. Stop and remove stream tracks
50
+ * 3. Stop audio/video processing
51
+ * 4. Clear mediaSources references
52
+ *
53
+ * @param deviceType - 'audio' or 'video'
54
+ * @param replaceWithEmptyTracks - If true, replace with silent/dummy track in PC
55
+ * @returns Promise<void>
56
+ */
57
+ private releaseMediaDevice;
58
+ init(): Promise<void>;
59
+ /**
60
+ * Get a peer connection by ID
61
+ * @param connectionId - Unique identifier for the connection
62
+ * @returns PeerConnection instance or undefined if not found
63
+ */
64
+ getConnection(connectionId: string): PeerConnection | undefined;
65
+ /**
66
+ * Get all peer connections
67
+ * @returns Array of PeerConnection instances
68
+ */
69
+ getAllConnections(): PeerConnection[];
70
+ /**
71
+ * Get the number of active connections
72
+ * @returns Number of connections
73
+ */
74
+ getConnectionCount(): number;
75
+ /**
76
+ * Create a new peer connection and add it to the manager
77
+ *
78
+ * @param connectionId - Unique identifier for this connection
79
+ * @param config - Peer connection configuration
80
+ * @param callbacks - Callbacks for peer connection events
81
+ * @returns The created PeerConnection instance
82
+ */
83
+ createPeerConnection(connectionId: string, config: PeerConnectionConfig, callbacks: {
84
+ onPcCreated?: () => void;
85
+ onPcConnected?: () => void;
86
+ onPcConnectedFinal?: () => void;
87
+ onPcConnectionFail?: (failureInfo: ConnectionFailureInfo) => void;
88
+ onHandlePcTrackEvent?: (streams: ReadonlyArray<MediaStream>) => void;
89
+ onIceCandidate?: (candidate: IceCandidateDataObj | null) => void;
90
+ /**
91
+ * Primary callback - fires when local description (offer OR answer) is ready to send via signaling
92
+ * Use this for new code
93
+ */
94
+ onLocalDescriptionReady?: (localDescription: RTCSessionDescription | null) => void;
95
+ /**
96
+ * @deprecated Use onLocalDescriptionReady instead. Kept for backward compatibility.
97
+ */
98
+ onStartPublishing?: (localDescription: RTCSessionDescription | null) => void;
99
+ }): PeerConnection;
100
+ getUserMedia(desiredConstraints: MediaStreamConstraints, isDeviceChange?: boolean): Promise<{
101
+ gumResult: GetUserMediaEveObj;
102
+ stream: MediaStream | null;
103
+ }>;
104
+ /**
105
+ * Start audio analysis for speaking indicator
106
+ * Called automatically after getUserMedia succeeds with audio
107
+ * @private
108
+ */
109
+ private startAudioAnalysis;
110
+ /**
111
+ * Stop audio analysis and clean up analysis track
112
+ * Call this when stopping media capture or closing connections
113
+ */
114
+ stopAudioAnalysis(): void;
115
+ /**
116
+ * Set speaking threshold
117
+ * @param threshold - Volume threshold for speaking detection (default: 300)
118
+ */
119
+ setSpeakingThreshold(threshold: number): void;
120
+ /**
121
+ * Update AudioAnalyzer about listener status (performance optimization)
122
+ * Called when listeners are added/removed from EselfSession
123
+ * Only emits events when listeners are registered to avoid overhead
124
+ */
125
+ updateAudioAnalyzerListeners(): void;
126
+ getUserDevices(): Promise<UserDevicesType>;
127
+ /**
128
+ * Replaces tracks in ALL active peer connections
129
+ * Critical for mute/unmute to work across multiple connections
130
+ * @param trackKind - 'audio' or 'video'
131
+ * @param newTrack - New track to replace with (or null to stop sending)
132
+ */
133
+ replaceTrackInAllConnections(trackKind: MediaDeviceKind, newTrack: MediaStreamTrack | null, publisher: boolean): Promise<void>;
134
+ /**
135
+ * Generic method to mute a track
136
+ * @param trackKind - TrackKind.AUDIO or TrackKind.VIDEO
137
+ * @param useDummyTrack - Whether to replace with dummy track
138
+ */
139
+ muteTrack(trackKind: TrackKind, useDummyTrack?: boolean): Promise<boolean>;
140
+ /**
141
+ * Generic method to unmute a track
142
+ * This will be called by EselfSession which handles getUserMedia with proper constraints
143
+ * Note: getUserMedia with isDeviceChange=true already updates all media sources and streams
144
+ * @param trackKind - TrackKind.AUDIO or TrackKind.VIDEO
145
+ */
146
+ unmuteTrack(trackKind: TrackKind): Promise<boolean>;
147
+ isAudioMuted(): boolean;
148
+ isVideoMuted(): boolean;
149
+ /**
150
+ * Clean up all media streams and tracks
151
+ * Stops all tracks from getUserMedia calls and nullifies stream references
152
+ * Call this when leaving a session or destroying the RTC connection
153
+ */
154
+ cleanupAllStreamsAndTracks(): Promise<void>;
155
+ releaseDeviceByType(deviceType: DeviceType.AudioInput | DeviceType.VideoInput | DeviceType.AudioOutput): Promise<void>;
156
+ /**
157
+ * Change input or output device (microphone, camera, or speaker)
158
+ * Handles complete device switching flow:
159
+ * - Validates device exists
160
+ * - Calls getUserMedia with new device for input devices
161
+ * - Replaces tracks on all peer connections
162
+ * - Stops old tracks
163
+ * - Updates localStorage
164
+ * - Emits deviceChanged event
165
+ *
166
+ * @param deviceType - DeviceType.AudioInput, DeviceType.VideoInput, or DeviceType.AudioOutput
167
+ * @param deviceId - Device ID from enumerateDevices
168
+ * @returns Promise with success status, stream, and previous device info
169
+ */
170
+ changeDevice(deviceType: DeviceType.AudioInput | DeviceType.VideoInput | DeviceType.AudioOutput, deviceId: string): Promise<{
171
+ success: boolean;
172
+ replaced: boolean;
173
+ stream: MediaStream | null;
174
+ error?: string;
175
+ previousDevice?: {
176
+ id: string;
177
+ label: string;
178
+ };
179
+ }>;
180
+ /**
181
+ * Set noise reduction state
182
+ * Enables or disables audio noise reduction with specified mode
183
+ * @param enable - True to enable NR, false to disable
184
+ * @param mode - Noise reduction mode (required when enabling, default: Mode13)
185
+ * @returns Promise<boolean> - True if successful, false otherwise
186
+ */
187
+ setNoiseReduction(enable: boolean, mode?: AudioNrMode): Promise<boolean>;
188
+ /**
189
+ * Get current noise reduction state
190
+ * @returns Object with enabled status and current mode
191
+ */
192
+ getNoiseReductionState(): {
193
+ enabled: boolean;
194
+ mode: AudioNrMode;
195
+ };
196
+ /**
197
+ */
198
+ getNoiseReductionEnableState(): boolean;
199
+ /**
200
+ * DEBUG: Start audio loopback to monitor the audio being sent to ASR
201
+ * Creates an audio element that plays back the published audio track
202
+ * WARNING: Use headphones to avoid feedback! For debugging only.
203
+ * @returns HTMLAudioElement or null if no audio track available
204
+ */
205
+ dbgStartAudioLoopback(): boolean;
206
+ /**
207
+ * DEBUG: Stop audio loopback monitoring
208
+ */
209
+ dbgStopAudioLoopback(): void;
210
+ /**
211
+ * DEBUG: Update audio loopback with new track if loopback is active
212
+ * Called automatically when audio track changes (device change, NR toggle, etc.)
213
+ */
214
+ dbgUpdateAudioLoopback(): void;
215
+ }
@@ -0,0 +1,2 @@
1
+ import { CoreRTCSession } from './CoreRTCSession';
2
+ export { CoreRTCSession };
@@ -0,0 +1,4 @@
1
+ export declare enum publisherQualityCheckStageType {
2
+ periodic = "periodic",
3
+ connected = "connected"
4
+ }
@@ -0,0 +1,50 @@
1
+ import { UnisphereLoggerType } from '@unisphere/core';
2
+ export interface RTCCoreOptions {
3
+ logger: UnisphereLoggerType;
4
+ onEvent: (event: any) => void;
5
+ }
6
+ export declare class RTCCore {
7
+ private _options;
8
+ private _microphoneStatus;
9
+ get onMicrophoneStatusChange(): (callback: (data: {
10
+ available: boolean;
11
+ muted: boolean;
12
+ devices: string[];
13
+ }) => void, options?: {
14
+ once?: boolean | undefined;
15
+ replayLastValue?: boolean | undefined;
16
+ } | undefined) => () => void;
17
+ get microphoneStatus(): {
18
+ available: boolean;
19
+ muted: boolean;
20
+ devices: string[];
21
+ };
22
+ private _userStream;
23
+ get onUserStreamChange(): (callback: (data: {
24
+ identifier: string;
25
+ elementId: string;
26
+ status: "attached" | "detached";
27
+ htmlElementId: string;
28
+ }) => void, options?: {
29
+ once?: boolean | undefined;
30
+ replayLastValue?: boolean | undefined;
31
+ } | undefined) => () => void;
32
+ get userStream(): {
33
+ identifier: string;
34
+ elementId: string;
35
+ status: "attached" | "detached";
36
+ htmlElementId: string;
37
+ };
38
+ private _onSomethingSpecificHappened;
39
+ get onSomethingSpecificHappened(): (callback: (data: {
40
+ interesting: boolean;
41
+ }) => void, options?: {
42
+ once?: boolean | undefined;
43
+ replayLastValue?: boolean | undefined;
44
+ } | undefined) => () => void;
45
+ constructor(_options: RTCCoreOptions);
46
+ attachUserStream(elementId: string): void;
47
+ muteMicrophone(): void;
48
+ unmuteMicrophone(): void;
49
+ detachUserStream(): void;
50
+ }