@kaltura-sdk/rtc-avatar 1.32.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/README.md +237 -0
- package/index.d.ts +1 -0
- package/index.esm.js +10077 -0
- package/package.json +21 -0
- package/src/index.d.ts +6 -0
- package/src/lib/connection/EselfRTCConnection.d.ts +186 -0
- package/src/lib/connection/index.d.ts +3 -0
- package/src/lib/connection/types.d.ts +94 -0
- package/src/lib/dom/EselfDOMManager.d.ts +80 -0
- package/src/lib/dom/index.d.ts +1 -0
- package/src/lib/eself-demo.d.ts +1 -0
- package/src/lib/session/EselfSession.d.ts +394 -0
- package/src/lib/session/index.d.ts +1 -0
- package/src/lib/signaling/EselfSignaling.d.ts +76 -0
- package/src/lib/signaling/KasSignalingAdapter.d.ts +55 -0
- package/src/lib/signaling/SrsSignalingAdapter.d.ts +50 -0
- package/src/lib/signaling/WhepSignalingAdapter.d.ts +70 -0
- package/src/lib/signaling/index.d.ts +5 -0
- package/src/lib/signaling/types.d.ts +34 -0
- package/src/lib/utils/RequestsDebouncer.d.ts +15 -0
- package/src/lib/utils/compressedLogger.d.ts +95 -0
- package/src/lib/utils/logBuffer.d.ts +47 -0
- package/src/lib/utils/logsCollector.d.ts +28 -0
- package/src/lib/utils/runWithRetry.d.ts +10 -0
- package/src/lib/utils/tests/testUtils.d.ts +2 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { GetUserMediaEveObj, UserDevicesType, DeviceType, AudioNrMode } from '@kaltura-sdk/rtc-core';
|
|
2
|
+
import { TinyPubSub } from '@unisphere/core';
|
|
3
|
+
import { SignalingOptions } from '../signaling';
|
|
4
|
+
import { MediaTrackState } from '../connection';
|
|
5
|
+
import { LogsCollectorConfig } from '../utils/logsCollector';
|
|
6
|
+
/**
|
|
7
|
+
* Simplified ICE candidate data for trickle ICE
|
|
8
|
+
* Matches the format from test_webrtc.html
|
|
9
|
+
*/
|
|
10
|
+
export type IceCandidateData = {
|
|
11
|
+
candidate: string | null;
|
|
12
|
+
sdpMLineIndex: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Options for joining ASR connection.
|
|
16
|
+
* Extensible for future feature flags.
|
|
17
|
+
*/
|
|
18
|
+
export interface AsrVideoConfig {
|
|
19
|
+
/** Video width in pixels (default: 640) */
|
|
20
|
+
width?: number;
|
|
21
|
+
/** Video height in pixels (default: 480) */
|
|
22
|
+
height?: number;
|
|
23
|
+
/** MaxFps: default 25 FPS*/
|
|
24
|
+
maxFps?: number;
|
|
25
|
+
/** Content hint for the video track (default: 'detail') */
|
|
26
|
+
contentHint?: string;
|
|
27
|
+
/** max bitrate in Kilobits, if not given use browser default */
|
|
28
|
+
maxBitrateKbps?: number;
|
|
29
|
+
/** Degradation preference for the video sender (default: 'maintain-resolution') */
|
|
30
|
+
degradationPreference?: RTCDegradationPreference;
|
|
31
|
+
/** Prevent resolution downscaling (default 1.0 = no scaling) */
|
|
32
|
+
scaleResolutionDownBy?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface JoinAsrOptions {
|
|
35
|
+
/** Send the local video track to the ASR backend (default: false) */
|
|
36
|
+
sendVideo?: boolean;
|
|
37
|
+
/** Video configuration when sendVideo is true */
|
|
38
|
+
videoConfig?: AsrVideoConfig;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Payload for connection state change events emitted by EselfSession.
|
|
42
|
+
*/
|
|
43
|
+
export type ConnectionStateEvent = {
|
|
44
|
+
connectionId: string;
|
|
45
|
+
connectionType: 'asr' | 'stv';
|
|
46
|
+
status: 'connected' | 'reconnecting' | 'failed';
|
|
47
|
+
attempt?: number;
|
|
48
|
+
maxAttempts?: number;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Configuration options for EselfSession
|
|
52
|
+
*/
|
|
53
|
+
export type EselfSessionConfig = {
|
|
54
|
+
turnServerUrl?: string;
|
|
55
|
+
turnUsername?: string;
|
|
56
|
+
turnCredential?: string;
|
|
57
|
+
forceAsrRelay?: boolean;
|
|
58
|
+
forceStvRelay?: boolean;
|
|
59
|
+
initialConstraintsConfig?: {
|
|
60
|
+
audio?: {
|
|
61
|
+
echoCancellation?: boolean;
|
|
62
|
+
autoGainControl?: boolean;
|
|
63
|
+
noiseReduction?: boolean;
|
|
64
|
+
};
|
|
65
|
+
video?: boolean;
|
|
66
|
+
};
|
|
67
|
+
asrUrl?: string;
|
|
68
|
+
stvUrl?: string;
|
|
69
|
+
srsUrl?: string;
|
|
70
|
+
srsApp?: string;
|
|
71
|
+
maxReconnectAttempts?: number;
|
|
72
|
+
reconnectDelayMs?: number;
|
|
73
|
+
speakingThreshold?: number;
|
|
74
|
+
logsConfig?: LogsCollectorConfig;
|
|
75
|
+
noiseReduction?: {
|
|
76
|
+
enabled?: boolean;
|
|
77
|
+
mode?: AudioNrMode;
|
|
78
|
+
workletBasePath?: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export declare class EselfSession {
|
|
82
|
+
onDevicesListChangePS: TinyPubSub<UserDevicesType>;
|
|
83
|
+
onDeviceChangedPS: TinyPubSub<{
|
|
84
|
+
type: 'audio' | 'video' | 'audioOutput';
|
|
85
|
+
deviceId: string;
|
|
86
|
+
deviceLabel: string;
|
|
87
|
+
automatic: boolean;
|
|
88
|
+
previousDevice?: {
|
|
89
|
+
id: string;
|
|
90
|
+
label: string;
|
|
91
|
+
} | undefined;
|
|
92
|
+
}>;
|
|
93
|
+
onConnectionStatePS: TinyPubSub<ConnectionStateEvent>;
|
|
94
|
+
private devicesManager;
|
|
95
|
+
private coreRTCSession;
|
|
96
|
+
private logger;
|
|
97
|
+
private turnServerUrl?;
|
|
98
|
+
private turnUsername?;
|
|
99
|
+
private turnCredential?;
|
|
100
|
+
private readonly forceAsrRelay;
|
|
101
|
+
private readonly forceStvRelay;
|
|
102
|
+
private readonly maxReconnectAttempts;
|
|
103
|
+
private readonly reconnectDelayMs;
|
|
104
|
+
private enableTrickleIce;
|
|
105
|
+
private whepAdapter;
|
|
106
|
+
private srsAdapter;
|
|
107
|
+
private srsApp?;
|
|
108
|
+
private kasAdapter;
|
|
109
|
+
private stvRemoteUrl?;
|
|
110
|
+
private domManager;
|
|
111
|
+
private signalingClient;
|
|
112
|
+
private asrConnection;
|
|
113
|
+
private asrSessionId;
|
|
114
|
+
private asrReconnectAttempts;
|
|
115
|
+
private asrReconnectAborted;
|
|
116
|
+
private stvConnection;
|
|
117
|
+
private stvConnectionId;
|
|
118
|
+
private stvSessionId;
|
|
119
|
+
private stvReconnectAttempts;
|
|
120
|
+
private stvReconnectAborted;
|
|
121
|
+
private remoteStreams;
|
|
122
|
+
private streamElementMappings;
|
|
123
|
+
private defaultVideoElementId;
|
|
124
|
+
private deviceListChangedUnsubscribe;
|
|
125
|
+
private deviceChangedUnsubscribe;
|
|
126
|
+
private deviceDisappearedUnsubscribe;
|
|
127
|
+
private speakingStateUnsubscribe;
|
|
128
|
+
private volumeLevelUnsubscribe;
|
|
129
|
+
private currentSpeakingState;
|
|
130
|
+
constructor(config?: EselfSessionConfig);
|
|
131
|
+
init(): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Setup listener for device list changes (when devices are added/removed)
|
|
134
|
+
*/
|
|
135
|
+
private setupDevicesListChangedListener;
|
|
136
|
+
/**
|
|
137
|
+
* Setup listener for manual device changes
|
|
138
|
+
*/
|
|
139
|
+
private setupDeviceChangedListener;
|
|
140
|
+
/**
|
|
141
|
+
* Setup listener for automatic device switching when selected device disappears
|
|
142
|
+
*/
|
|
143
|
+
private setupDeviceDisappearedListener;
|
|
144
|
+
getUserMedia(audio?: boolean, video?: boolean, elementId?: string, isDeviceChange?: boolean, videoConfig?: AsrVideoConfig): Promise<{
|
|
145
|
+
gumResult: GetUserMediaEveObj;
|
|
146
|
+
stream: MediaStream | null;
|
|
147
|
+
}>;
|
|
148
|
+
getUserDevices(): Promise<UserDevicesType>;
|
|
149
|
+
/**
|
|
150
|
+
* Cleanup tracked media elements for a specific tracking key
|
|
151
|
+
* @param trackingKey - The key used to track elements (elementId or 'default')
|
|
152
|
+
*/
|
|
153
|
+
private cleanupMediaElements;
|
|
154
|
+
/**
|
|
155
|
+
* Cleanup all tracked media elements
|
|
156
|
+
*/
|
|
157
|
+
private cleanupAllMediaElements;
|
|
158
|
+
onDevicesListChange(callback: () => void): void;
|
|
159
|
+
/**
|
|
160
|
+
* Change input or output device (microphone, camera, or speaker)
|
|
161
|
+
* Wrapper around CoreRTCSession.changeDevice with DOM element updates
|
|
162
|
+
*
|
|
163
|
+
* @param deviceType - DeviceType.AudioInput, DeviceType.VideoInput, or DeviceType.AudioOutput
|
|
164
|
+
* @param deviceId - Device ID from enumerateDevices
|
|
165
|
+
* @returns Promise<boolean> - Success status
|
|
166
|
+
*/
|
|
167
|
+
changeDevice(deviceType: DeviceType.AudioInput | DeviceType.VideoInput | DeviceType.AudioOutput, deviceId: string): Promise<boolean>;
|
|
168
|
+
/**
|
|
169
|
+
* Subscribe to device change events
|
|
170
|
+
* Fires when device is manually changed or automatically switched due to device disappearing
|
|
171
|
+
*
|
|
172
|
+
* @param callback - Called when device is changed
|
|
173
|
+
*/
|
|
174
|
+
onDeviceChanged(callback: (event: {
|
|
175
|
+
type: 'audio' | 'video' | 'audioOutput';
|
|
176
|
+
deviceId: string;
|
|
177
|
+
deviceLabel: string;
|
|
178
|
+
automatic: boolean;
|
|
179
|
+
previousDevice?: {
|
|
180
|
+
id: string;
|
|
181
|
+
label: string;
|
|
182
|
+
};
|
|
183
|
+
}) => void): void;
|
|
184
|
+
/**
|
|
185
|
+
* Subscribe to connection state changes.
|
|
186
|
+
* Fires when a peer connection is established (connected), during retry attempts
|
|
187
|
+
* (reconnecting), or when max retries are exhausted (failed).
|
|
188
|
+
*
|
|
189
|
+
* @param callback - Called on each state change
|
|
190
|
+
*/
|
|
191
|
+
onConnectionState(callback: (event: ConnectionStateEvent) => void): void;
|
|
192
|
+
/**
|
|
193
|
+
* Build ICE configuration from TURN settings
|
|
194
|
+
* @returns IceConfiguration with TURN servers or empty if not configured
|
|
195
|
+
*/
|
|
196
|
+
private buildIceConfiguration;
|
|
197
|
+
/**
|
|
198
|
+
* Join ASR (Audio Speech Recognition) - Publisher connection
|
|
199
|
+
* Sends local audio stream to ASR service
|
|
200
|
+
*
|
|
201
|
+
* @param signalingOptions - Optional signaling configuration (HTTP endpoints or WebSocket callbacks)
|
|
202
|
+
* If not provided and kasAdapter is available, will use kas backend
|
|
203
|
+
* @param sessionId - Optional session ID for the connection. If not provided, defaults to 'asr'
|
|
204
|
+
* @throws Error if connection fails or if already connected
|
|
205
|
+
*/
|
|
206
|
+
joinASR(signalingOptions?: SignalingOptions, sessionId?: string, isReconnect?: boolean, options?: JoinAsrOptions): Promise<void>;
|
|
207
|
+
/**
|
|
208
|
+
* Join STV (Streaming Video) - Viewer connection
|
|
209
|
+
* Receives remote audio/video stream from avatar
|
|
210
|
+
*
|
|
211
|
+
* @param videoContainerId - Optional container element ID for video display
|
|
212
|
+
* @param signalingOptions - Optional signaling configuration (HTTP endpoints or WebSocket callbacks)
|
|
213
|
+
* If not provided and srsAdapter is available, will use SRS backend
|
|
214
|
+
* @param sessionId - Optional session ID for the connection. If not provided, defaults to 'stv'.
|
|
215
|
+
* For SRS, this becomes the stream name in the WHEP URL.
|
|
216
|
+
* @throws Error if connection fails or if already connected
|
|
217
|
+
*/
|
|
218
|
+
joinSTV(videoContainerId?: string, signalingOptions?: SignalingOptions, sessionId?: string, isReconnect?: boolean, stvUrl?: string): Promise<void>;
|
|
219
|
+
/**
|
|
220
|
+
* Manually attach a remote stream to a video container
|
|
221
|
+
* Allows attaching one stream to multiple containers
|
|
222
|
+
*
|
|
223
|
+
* @param streamId - ID of the remote stream
|
|
224
|
+
* @param containerElementId - ID of the container element
|
|
225
|
+
*/
|
|
226
|
+
attachStreamToElement(streamId: string, containerElementId: string): void;
|
|
227
|
+
/**
|
|
228
|
+
* Detach a remote stream from a specific container
|
|
229
|
+
*
|
|
230
|
+
* @param streamId - ID of the remote stream
|
|
231
|
+
* @param containerElementId - ID of the container element
|
|
232
|
+
*/
|
|
233
|
+
detachStreamFromElement(streamId: string, containerElementId: string): void;
|
|
234
|
+
/**
|
|
235
|
+
* Add a remote ICE candidate to the ASR connection (for trickle ICE)
|
|
236
|
+
* Accepts simplified format: { candidate: string, sdpMLineIndex: number }
|
|
237
|
+
*
|
|
238
|
+
* @param candidate - ICE candidate data received from server (only candidate and sdpMLineIndex)
|
|
239
|
+
* @throws Error if ASR connection is not active
|
|
240
|
+
*/
|
|
241
|
+
addRemoteIceCandidate(candidate: IceCandidateData): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Leave ASR connection
|
|
244
|
+
* Closes the ASR peer connection and cleans up all streams and tracks
|
|
245
|
+
*/
|
|
246
|
+
leaveASR(): void;
|
|
247
|
+
/**
|
|
248
|
+
* Leave STV connection
|
|
249
|
+
* Closes the STV peer connection and cleans up remote streams
|
|
250
|
+
*/
|
|
251
|
+
leaveSTV(): void;
|
|
252
|
+
/**
|
|
253
|
+
* Private method to handle ASR reconnection logic.
|
|
254
|
+
* Uses instance fields for state (reconnectAttempts, reconnectAborted, asrSessionId).
|
|
255
|
+
*
|
|
256
|
+
* @param connectionId - Connection ID that failed
|
|
257
|
+
* @param error - Error that caused the failure
|
|
258
|
+
* @param state - Minimal reconnection state that can't be stored on the instance
|
|
259
|
+
*/
|
|
260
|
+
private handleAsrReconnection;
|
|
261
|
+
/**
|
|
262
|
+
* Private method to handle STV reconnection logic.
|
|
263
|
+
* Uses instance fields for state (stvReconnectAttempts, stvReconnectAborted, stvBaseUrl, stvAgentId).
|
|
264
|
+
* Note: does NOT call createStvSession unless the server session is gone (404).
|
|
265
|
+
*
|
|
266
|
+
* @param connectionId - Connection ID that failed
|
|
267
|
+
* @param error - Error that caused the failure
|
|
268
|
+
* @param state - Minimal reconnection state that can't be stored on the instance
|
|
269
|
+
*/
|
|
270
|
+
private handleStvReconnection;
|
|
271
|
+
/**
|
|
272
|
+
* Test method to manually trigger reconnection by emitting connection failed event
|
|
273
|
+
* Used for testing reconnection logic in development/testing
|
|
274
|
+
*
|
|
275
|
+
* @param connectionType - Which connection to trigger reconnection for ('asr' or 'stv')
|
|
276
|
+
*/
|
|
277
|
+
testCloseConnection(connectionType: 'asr' | 'stv'): void;
|
|
278
|
+
/**
|
|
279
|
+
* Register debug helpers on window for development/testing.
|
|
280
|
+
* Call this after initializing the session.
|
|
281
|
+
*
|
|
282
|
+
* window.killAllPeerConnections() — triggers PC_CONNECTION_FAILED on all active connections,
|
|
283
|
+
* causing the reconnection logic to fire (same as a real network failure).
|
|
284
|
+
*/
|
|
285
|
+
registerDebugGlobals(): void;
|
|
286
|
+
/**
|
|
287
|
+
* Subscribe to speaking state changes
|
|
288
|
+
* Core SDK will START emitting events when first listener is added
|
|
289
|
+
* @param callback - Called when user starts/stops speaking
|
|
290
|
+
* @returns Unsubscribe function
|
|
291
|
+
*/
|
|
292
|
+
onSpeakingStateChanged(callback: (speaking: boolean) => void): () => void;
|
|
293
|
+
/**
|
|
294
|
+
* Subscribe to raw volume levels (for high-precision features)
|
|
295
|
+
* Core SDK will START emitting volume events when first listener is added
|
|
296
|
+
* @param callback - Called every 50ms with current volume
|
|
297
|
+
* @returns Unsubscribe function
|
|
298
|
+
*/
|
|
299
|
+
onAudioVolumeLevel(callback: (volume: number) => void): () => void;
|
|
300
|
+
/**
|
|
301
|
+
* Update speaking threshold dynamically
|
|
302
|
+
* @param threshold - New volume threshold (default: 300)
|
|
303
|
+
*/
|
|
304
|
+
setSpeakingThreshold(threshold: number): void;
|
|
305
|
+
/**
|
|
306
|
+
* Get current speaking state (cached from last event)
|
|
307
|
+
* @returns true if currently speaking, false otherwise
|
|
308
|
+
*/
|
|
309
|
+
isSpeaking(): boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Check if user is speaking while muted
|
|
312
|
+
* Useful for showing "unmute" prompts
|
|
313
|
+
* @returns true if speaking while audio is muted
|
|
314
|
+
*/
|
|
315
|
+
isSpeakingWhileMuted(): boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Destroy the session and clean up all resources
|
|
318
|
+
* Closes all connections and removes all DOM elements
|
|
319
|
+
*/
|
|
320
|
+
destroy(): void;
|
|
321
|
+
/**
|
|
322
|
+
* Mutes audio
|
|
323
|
+
* Routes through connection to maintain state consistency
|
|
324
|
+
*/
|
|
325
|
+
muteASRAudio(): Promise<boolean>;
|
|
326
|
+
/**
|
|
327
|
+
* Unmutes audio
|
|
328
|
+
* Routes through connection to maintain state consistency
|
|
329
|
+
*/
|
|
330
|
+
unmuteASRAudio(): Promise<boolean>;
|
|
331
|
+
/**
|
|
332
|
+
* Gets audio mute state for ASR connection
|
|
333
|
+
* Returns actual connection state when connected, otherwise checks core session
|
|
334
|
+
*/
|
|
335
|
+
getASRAudioState(): MediaTrackState | null;
|
|
336
|
+
/**
|
|
337
|
+
* Mutes video
|
|
338
|
+
* Routes through connection to maintain state consistency
|
|
339
|
+
*/
|
|
340
|
+
muteASRVideo(): Promise<void>;
|
|
341
|
+
/**
|
|
342
|
+
* Unmutes video
|
|
343
|
+
* Routes through connection to maintain state consistency
|
|
344
|
+
*/
|
|
345
|
+
unmuteASRVideo(): Promise<boolean>;
|
|
346
|
+
/**
|
|
347
|
+
* Reattaches the current video track to the mapped video element after unmute.
|
|
348
|
+
* The peer connection sender is updated by the core unmute flow,
|
|
349
|
+
* but the local preview element needs its srcObject refreshed.
|
|
350
|
+
*/
|
|
351
|
+
private reattachVideoToElement;
|
|
352
|
+
/**
|
|
353
|
+
* Gets video mute state for ASR connection
|
|
354
|
+
* Returns actual connection state when connected, otherwise checks core session
|
|
355
|
+
*/
|
|
356
|
+
getASRVideoState(): MediaTrackState | null;
|
|
357
|
+
/**
|
|
358
|
+
* Enable noise reduction
|
|
359
|
+
* @param mode - NR mode to use (default: Mode11)
|
|
360
|
+
* @returns Promise<boolean> - True if successful, false otherwise
|
|
361
|
+
*/
|
|
362
|
+
enableNoiseReduction(mode?: AudioNrMode): Promise<boolean>;
|
|
363
|
+
/**
|
|
364
|
+
* Disable noise reduction
|
|
365
|
+
* Falls back to raw audio track
|
|
366
|
+
*/
|
|
367
|
+
disableNoiseReduction(): Promise<boolean>;
|
|
368
|
+
/**
|
|
369
|
+
* Switch noise reduction mode
|
|
370
|
+
* @param mode - New NR mode
|
|
371
|
+
* @returns Promise<boolean> - True if successful, false otherwise
|
|
372
|
+
*/
|
|
373
|
+
setNoiseReductionMode(mode: AudioNrMode): Promise<boolean>;
|
|
374
|
+
/**
|
|
375
|
+
* Get current noise reduction state
|
|
376
|
+
* @returns Object with enabled status and current mode
|
|
377
|
+
*/
|
|
378
|
+
getNoiseReductionState(): {
|
|
379
|
+
enabled: boolean;
|
|
380
|
+
mode: AudioNrMode;
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* DEBUG: Start audio loopback for testing
|
|
384
|
+
* Creates an audio element that plays back the published audio track
|
|
385
|
+
* Useful for testing noise reduction and audio processing
|
|
386
|
+
* @returns The created audio element or existing one
|
|
387
|
+
*/
|
|
388
|
+
dbgStartAudioLoopback(): boolean;
|
|
389
|
+
/**
|
|
390
|
+
* DEBUG: Stop audio loopback
|
|
391
|
+
* Removes the audio element and stops playback
|
|
392
|
+
*/
|
|
393
|
+
dbgStopAudioLoopback(): void;
|
|
394
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './EselfSession';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { SignalingOptions } from './types';
|
|
2
|
+
import { IceCandidateData } from '../session';
|
|
3
|
+
/**
|
|
4
|
+
* EselfSignaling: Flexible signaling client supporting HTTP and WebSocket modes
|
|
5
|
+
*
|
|
6
|
+
* Two modes of operation:
|
|
7
|
+
* 1. HTTP Mode: SDK manages fetch() calls to provided endpoints
|
|
8
|
+
* 2. WebSocket Mode: App provides callbacks that manage WebSocket communication
|
|
9
|
+
*
|
|
10
|
+
* Priority: If a callback is provided, it's used. Otherwise, falls back to HTTP.
|
|
11
|
+
*
|
|
12
|
+
* Example HTTP usage:
|
|
13
|
+
* signalingClient.updateOptions({
|
|
14
|
+
* asrEndpoint: 'https://api.example.com/asr/signaling',
|
|
15
|
+
* stvEndpoint: 'https://api.example.com/stv/signaling'
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* Example WebSocket usage:
|
|
19
|
+
* signalingClient.updateOptions({
|
|
20
|
+
* sendOfferCallback: async (connId, sdp) => {
|
|
21
|
+
* ws.send(JSON.stringify({ type: 'offer', connectionId: connId, sdp }));
|
|
22
|
+
* return await waitForAnswer();
|
|
23
|
+
* },
|
|
24
|
+
* sendAnswerCallback: async (connId, sdp) => {
|
|
25
|
+
* ws.send(JSON.stringify({ type: 'answer', connectionId: connId, sdp }));
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
export declare class EselfSignaling {
|
|
30
|
+
private logger;
|
|
31
|
+
private options;
|
|
32
|
+
constructor(initialOptions?: SignalingOptions);
|
|
33
|
+
/**
|
|
34
|
+
* Update signaling options at runtime
|
|
35
|
+
* Allows switching between HTTP and WebSocket modes dynamically
|
|
36
|
+
*
|
|
37
|
+
* @param options - New signaling options to merge with existing
|
|
38
|
+
*/
|
|
39
|
+
updateOptions(options: SignalingOptions): void;
|
|
40
|
+
/**
|
|
41
|
+
* Send an offer and wait for an answer
|
|
42
|
+
* Priority: Uses sendOfferCallback if provided, otherwise HTTP endpoint
|
|
43
|
+
*
|
|
44
|
+
* @param connectionId - Connection ID ('asr' or 'stv')
|
|
45
|
+
* @param sdp - Local SDP offer
|
|
46
|
+
* @param isReconnect - Flag indicating if this is a reconnection attempt
|
|
47
|
+
* @returns Remote SDP answer
|
|
48
|
+
* @throws SignalingError if signaling fails
|
|
49
|
+
*/
|
|
50
|
+
sendOffer(connectionId: string, sdp: RTCSessionDescriptionInit, isReconnect?: boolean): Promise<RTCSessionDescriptionInit>;
|
|
51
|
+
/**
|
|
52
|
+
* Send an answer to a received offer
|
|
53
|
+
* Priority: Uses sendAnswerCallback if provided, otherwise HTTP endpoint
|
|
54
|
+
*
|
|
55
|
+
* @param connectionId - Connection ID ('asr' or 'stv')
|
|
56
|
+
* @param sdp - Local SDP answer
|
|
57
|
+
* @throws SignalingError if signaling fails
|
|
58
|
+
*/
|
|
59
|
+
sendAnswer(connectionId: string, sdp: RTCSessionDescriptionInit): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Send an ICE candidate
|
|
62
|
+
* Priority: Uses sendICECandidateCallback if provided, otherwise HTTP endpoint
|
|
63
|
+
*
|
|
64
|
+
* @param connectionId - Connection ID ('asr' or 'stv')
|
|
65
|
+
* @param candidate - ICE candidate
|
|
66
|
+
* @throws SignalingError if signaling fails
|
|
67
|
+
*/
|
|
68
|
+
sendICECandidate(connectionId: string, candidate: IceCandidateData): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Get the HTTP endpoint for a specific connection
|
|
71
|
+
* @param connectionId - Connection ID ('asr' or 'stv')
|
|
72
|
+
* @returns Endpoint URL or undefined if not configured
|
|
73
|
+
*/
|
|
74
|
+
private getEndpointForConnection;
|
|
75
|
+
}
|
|
76
|
+
export default EselfSignaling;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KasSignalingAdapter: Adapter for kas backend signaling protocol
|
|
3
|
+
*
|
|
4
|
+
* Adapts the kas backend's specific HTTP API format:
|
|
5
|
+
* - POST /offer -> returns { sdp, type, session_id }
|
|
6
|
+
* - POST /start -> starts the session
|
|
7
|
+
*
|
|
8
|
+
* This adapter creates callbacks that can be used with EselfSignaling
|
|
9
|
+
*/
|
|
10
|
+
export declare class KasSignalingAdapter {
|
|
11
|
+
private logger;
|
|
12
|
+
private asrBaseUrl;
|
|
13
|
+
private stvBaseUrl;
|
|
14
|
+
private sessionIds;
|
|
15
|
+
/**
|
|
16
|
+
* @param asrBaseUrl - Base URL for ASR service (e.g., 'http://localhost:8081')
|
|
17
|
+
* @param stvBaseUrl - Base URL for STV service (e.g., 'http://localhost:8080')
|
|
18
|
+
*/
|
|
19
|
+
constructor(asrBaseUrl: string, stvBaseUrl: string);
|
|
20
|
+
/**
|
|
21
|
+
* Get the base URL for a specific connection
|
|
22
|
+
*/
|
|
23
|
+
private getBaseUrl;
|
|
24
|
+
/**
|
|
25
|
+
* Create sendOffer callback for use with EselfSignaling
|
|
26
|
+
* Handles the kas backend's offer/answer protocol
|
|
27
|
+
*/
|
|
28
|
+
createSendOfferCallback(): (connectionId: string, sdp: RTCSessionDescriptionInit) => Promise<RTCSessionDescriptionInit>;
|
|
29
|
+
/**
|
|
30
|
+
* Start the session by calling the /start endpoint
|
|
31
|
+
* This should be called after the peer connection is established
|
|
32
|
+
*
|
|
33
|
+
* @param connectionId - Connection ID ('asr' or 'stv')
|
|
34
|
+
*/
|
|
35
|
+
startSession(connectionId: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Create sendAnswer callback for use with EselfSignaling
|
|
38
|
+
* (Not typically used with kas backend since we're the client)
|
|
39
|
+
*/
|
|
40
|
+
createSendAnswerCallback(): (connectionId: string, sdp: RTCSessionDescriptionInit) => Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Create sendICECandidate callback for use with EselfSignaling
|
|
43
|
+
* (Not used with kas backend - ICE candidates are bundled in SDP)
|
|
44
|
+
*/
|
|
45
|
+
createSendICECandidateCallback(): (connectionId: string, candidate: RTCIceCandidate) => Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the session ID for a connection (if available)
|
|
48
|
+
*/
|
|
49
|
+
getSessionId(connectionId: string): string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Clear session data
|
|
52
|
+
*/
|
|
53
|
+
clear(): void;
|
|
54
|
+
}
|
|
55
|
+
export default KasSignalingAdapter;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SrsSignalingAdapter: Adapter for SRS (Simple Realtime Server) WHEP protocol
|
|
3
|
+
*
|
|
4
|
+
* Adapts the SRS WHEP (WebRTC-HTTP Egress Protocol) format:
|
|
5
|
+
* - POST /rtc/v1/whep/?app={app}&stream={stream} with plain SDP text
|
|
6
|
+
* - Response: Plain SDP text (not JSON)
|
|
7
|
+
* - Content-Type: application/sdp (not application/json)
|
|
8
|
+
* - No session management endpoints
|
|
9
|
+
*
|
|
10
|
+
* This adapter creates callbacks that can be used with EselfSignaling
|
|
11
|
+
*/
|
|
12
|
+
export declare class SrsSignalingAdapter {
|
|
13
|
+
private logger;
|
|
14
|
+
private baseUrl;
|
|
15
|
+
private app;
|
|
16
|
+
/**
|
|
17
|
+
* @param baseUrl - Base URL for SRS server (e.g., 'http://localhost:1985')
|
|
18
|
+
* @param app - SRS app name (default: 'live')
|
|
19
|
+
*/
|
|
20
|
+
constructor(baseUrl: string, app?: string);
|
|
21
|
+
/**
|
|
22
|
+
* Construct WHEP endpoint URL
|
|
23
|
+
* Format: {baseUrl}/rtc/v1/whep/?app={app}&stream={stream}
|
|
24
|
+
*/
|
|
25
|
+
private constructWhepUrl;
|
|
26
|
+
/**
|
|
27
|
+
* Create sendOffer callback for use with EselfSignaling
|
|
28
|
+
* Handles the SRS WHEP protocol
|
|
29
|
+
*/
|
|
30
|
+
createSendOfferCallback(): (connectionId: string, sdp: RTCSessionDescriptionInit) => Promise<RTCSessionDescriptionInit>;
|
|
31
|
+
/**
|
|
32
|
+
* Create sendAnswer callback for use with EselfSignaling
|
|
33
|
+
* (Not used with WHEP protocol - client always sends offer)
|
|
34
|
+
*/
|
|
35
|
+
createSendAnswerCallback(): (connectionId: string, sdp: RTCSessionDescriptionInit) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Create sendICECandidate callback for use with EselfSignaling
|
|
38
|
+
* (Not used with SRS - ICE candidates are bundled in SDP)
|
|
39
|
+
*/
|
|
40
|
+
createSendICECandidateCallback(): (connectionId: string, candidate: RTCIceCandidate) => Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Get the configured app name
|
|
43
|
+
*/
|
|
44
|
+
getAppName(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Get the base URL
|
|
47
|
+
*/
|
|
48
|
+
getBaseUrl(): string;
|
|
49
|
+
}
|
|
50
|
+
export default SrsSignalingAdapter;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP status codes used by the WHEP protocol.
|
|
3
|
+
*/
|
|
4
|
+
export declare enum WhepStatus {
|
|
5
|
+
OK = 200,
|
|
6
|
+
CREATED = 201,// Offer accepted, SDP answer returned
|
|
7
|
+
NO_ACTIVE_SESSION = 404,// session_id not in registry (no active session)
|
|
8
|
+
ALREADY_HAS_VIEWER = 409,// Session already has an active viewer (DELETE it first)
|
|
9
|
+
WRONG_CONTENT_TYPE = 415,// Wrong Content-Type (not application/sdp)
|
|
10
|
+
INTERNAL_SERVER_ERROR = 500
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* WhepSignalingAdapter: Adapter for standard WHEP (WebRTC-HTTP Egress Protocol)
|
|
14
|
+
*
|
|
15
|
+
* Handles the STV server's WHEP endpoint:
|
|
16
|
+
* - POST /whep/{sessionId} with plain SDP text → receives SDP answer + Location header
|
|
17
|
+
* - DELETE {Location} for session teardown
|
|
18
|
+
*
|
|
19
|
+
* The browser is the WHEP subscriber (viewer).
|
|
20
|
+
* The STV server is the WHIP publisher (ingestion side).
|
|
21
|
+
*/
|
|
22
|
+
export declare class WhepSignalingAdapter {
|
|
23
|
+
private logger;
|
|
24
|
+
private baseUrl;
|
|
25
|
+
private sessionLocations;
|
|
26
|
+
/**
|
|
27
|
+
* @param baseUrl - Base URL for STV server (e.g., 'http://localhost:8080')
|
|
28
|
+
*/
|
|
29
|
+
constructor(baseUrl: string);
|
|
30
|
+
/**
|
|
31
|
+
* Update the base URL for the WHEP adapter
|
|
32
|
+
* Allows changing STV server dynamically between joinSTV calls
|
|
33
|
+
*
|
|
34
|
+
* @param newUrl - New STV base URL (e.g., 'http://localhost:8080')
|
|
35
|
+
* @note Existing session locations (stored Location headers) are NOT cleared.
|
|
36
|
+
* If switching STV servers, ensure previous sessions are cleaned up first.
|
|
37
|
+
*/
|
|
38
|
+
updateBaseUrl(newUrl: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Construct WHEP endpoint URL
|
|
41
|
+
* Format: {baseUrl}/whep/session/{sessionId}
|
|
42
|
+
*/
|
|
43
|
+
private constructWhepUrl;
|
|
44
|
+
/**
|
|
45
|
+
* Create sendOffer callback for use with EselfSignaling.
|
|
46
|
+
* Handles the standard WHEP protocol:
|
|
47
|
+
* POST SDP offer → plain text SDP answer + stores Location header.
|
|
48
|
+
*/
|
|
49
|
+
createSendOfferCallback(): (connectionId: string, sdp: RTCSessionDescriptionInit) => Promise<RTCSessionDescriptionInit>;
|
|
50
|
+
/**
|
|
51
|
+
* Create sendAnswer callback — no-op for WHEP (client always sends offer).
|
|
52
|
+
*/
|
|
53
|
+
createSendAnswerCallback(): (_connectionId: string, _sdp: RTCSessionDescriptionInit) => Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Create sendICECandidate callback — no-op for WHEP (ICE bundled in SDP).
|
|
56
|
+
*/
|
|
57
|
+
createSendICECandidateCallback(): (connectionId: string, _candidate: RTCIceCandidate) => Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Teardown the WHEP session by sending DELETE to the Location URL.
|
|
60
|
+
* Call this when closing the viewer connection.
|
|
61
|
+
*
|
|
62
|
+
* @param connectionId - The connection ID used in joinSTV / sendOffer
|
|
63
|
+
*/
|
|
64
|
+
disconnect(connectionId: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Get the base URL.
|
|
67
|
+
*/
|
|
68
|
+
getBaseUrl(): string;
|
|
69
|
+
}
|
|
70
|
+
export default WhepSignalingAdapter;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { EselfSignaling, default as EselfSignalingDefault, } from './EselfSignaling';
|
|
2
|
+
export { KasSignalingAdapter } from './KasSignalingAdapter';
|
|
3
|
+
export { SrsSignalingAdapter } from './SrsSignalingAdapter';
|
|
4
|
+
export { WhepSignalingAdapter } from './WhepSignalingAdapter';
|
|
5
|
+
export * from './types';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { IceCandidateData } from '../session';
|
|
2
|
+
/**
|
|
3
|
+
* Signaling options for EselfSignaling
|
|
4
|
+
*
|
|
5
|
+
* Supports two modes:
|
|
6
|
+
* 1. HTTP Mode: Provide endpoint URLs, SDK will use fetch() for signaling
|
|
7
|
+
* 2. WebSocket Mode: Provide callback functions, app manages the WebSocket connection
|
|
8
|
+
*
|
|
9
|
+
* Can be mixed (e.g., HTTP for ASR, callbacks for STV)
|
|
10
|
+
*/
|
|
11
|
+
export type SignalingOptions = {
|
|
12
|
+
asrEndpoint?: string;
|
|
13
|
+
stvEndpoint?: string;
|
|
14
|
+
sendOfferCallback?: (connectionId: string, sdp: RTCSessionDescriptionInit, isReconnect: boolean) => Promise<RTCSessionDescriptionInit>;
|
|
15
|
+
sendAnswerCallback?: (connectionId: string, sdp: RTCSessionDescriptionInit) => Promise<void>;
|
|
16
|
+
sendICECandidateCallback?: (connectionId: string, candidate: IceCandidateData) => Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Signaling message types
|
|
20
|
+
*/
|
|
21
|
+
export declare enum SignalingMessageType {
|
|
22
|
+
OFFER = "offer",
|
|
23
|
+
ANSWER = "answer",
|
|
24
|
+
ICE_CANDIDATE = "iceCandidate"
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Signaling error types
|
|
28
|
+
*/
|
|
29
|
+
export declare class SignalingError extends Error {
|
|
30
|
+
readonly connectionId: string;
|
|
31
|
+
readonly messageType: SignalingMessageType;
|
|
32
|
+
readonly statusCode?: number | undefined;
|
|
33
|
+
constructor(message: string, connectionId: string, messageType: SignalingMessageType, statusCode?: number | undefined);
|
|
34
|
+
}
|