@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.
@@ -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
+ }