@telnyx/webrtc 2.27.4-beta.0 → 2.27.4-beta.2
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/lib/bundle.js +1 -1
- package/lib/bundle.mjs +1 -1
- package/lib/src/Modules/Verto/BrowserSession.d.ts +0 -5
- package/lib/src/Modules/Verto/services/SignalingHealthMonitor.d.ts +5 -0
- package/lib/src/Modules/Verto/util/constants/errorCodes.d.ts +3 -1
- package/lib/src/Modules/Verto/util/constants/warnings.d.ts +14 -0
- package/lib/src/Modules/Verto/util/interfaces.d.ts +6 -0
- package/lib/src/Modules/Verto/webrtc/AIConversationTypes.d.ts +1 -3
- package/lib/src/Modules/Verto/webrtc/BaseCall.d.ts +1 -3
- package/lib/src/Modules/Verto/webrtc/CallRecorder.d.ts +96 -0
- package/lib/src/Modules/Verto/webrtc/CallReportCollector.d.ts +2 -2
- package/lib/src/Modules/Verto/webrtc/constants.d.ts +3 -0
- package/lib/src/utils/interfaces.d.ts +6 -0
- package/package.json +1 -1
|
@@ -25,9 +25,6 @@ export default abstract class BrowserSession extends BaseSession {
|
|
|
25
25
|
private _previousAudioConstraints;
|
|
26
26
|
protected _videoConstraints: boolean | MediaTrackConstraints;
|
|
27
27
|
protected _speaker: string;
|
|
28
|
-
private _onlineHandler;
|
|
29
|
-
private _offlineHandler;
|
|
30
|
-
private _wasOffline;
|
|
31
28
|
constructor(options: IVertoOptions);
|
|
32
29
|
getIsRegistered(): Promise<boolean>;
|
|
33
30
|
connect(): Promise<void>;
|
|
@@ -62,7 +59,5 @@ export default abstract class BrowserSession extends BaseSession {
|
|
|
62
59
|
vertoBroadcast({ nodeId, channel: eventChannel, data, }: BroadcastParams): void;
|
|
63
60
|
vertoSubscribe({ nodeId, channels: eventChannel, handler, }: SubscribeParams): Promise<any>;
|
|
64
61
|
vertoUnsubscribe({ nodeId, channels: eventChannel, }: SubscribeParams): Promise<any>;
|
|
65
|
-
private _setupNetworkListeners;
|
|
66
|
-
private _cleanupNetworkListeners;
|
|
67
62
|
static telnyxStateCall(call: Call): Call;
|
|
68
63
|
}
|
|
@@ -6,6 +6,9 @@ export default class SignalingHealthMonitor {
|
|
|
6
6
|
private _probeInFlight;
|
|
7
7
|
private _intervalId;
|
|
8
8
|
private _pendingMediaRecovery;
|
|
9
|
+
private _browserWasOffline;
|
|
10
|
+
private _onlineHandler;
|
|
11
|
+
private _offlineHandler;
|
|
9
12
|
private static readonly CRITICAL_METHODS;
|
|
10
13
|
static isCriticalMethod(method: string): boolean;
|
|
11
14
|
constructor(_session: ISignalingHealthSession);
|
|
@@ -19,6 +22,8 @@ export default class SignalingHealthMonitor {
|
|
|
19
22
|
onRequestTimeout(requestId: string, timeoutMs: number, method?: string): void;
|
|
20
23
|
onPeerFailure(callId: string, evidence: PeerFailureEvidence): void;
|
|
21
24
|
onNoRtp(callId: string, direction: 'inbound' | 'outbound'): void;
|
|
25
|
+
private _setupBrowserListeners;
|
|
26
|
+
private _cleanupBrowserListeners;
|
|
22
27
|
onIceRestartFailed(callId: string): void;
|
|
23
28
|
private _check;
|
|
24
29
|
private _sendProbe;
|
|
@@ -33,6 +33,8 @@ export declare const TELNYX_WARNING_CODES: {
|
|
|
33
33
|
readonly LOW_INBOUND_AUDIO: 31006;
|
|
34
34
|
readonly LOW_BYTES_RECEIVED: 32001;
|
|
35
35
|
readonly LOW_BYTES_SENT: 32002;
|
|
36
|
+
readonly RECORDING_UNAVAILABLE: 32003;
|
|
37
|
+
readonly RECORDING_BUFFER_OVERFLOW: 32004;
|
|
36
38
|
readonly ICE_CONNECTIVITY_LOST: 33001;
|
|
37
39
|
readonly ICE_GATHERING_TIMEOUT: 33002;
|
|
38
40
|
readonly ICE_GATHERING_EMPTY: 33003;
|
|
@@ -50,5 +52,5 @@ export declare const TELNYX_WARNING_CODES: {
|
|
|
50
52
|
readonly RECONNECTION_FAILED_WITH_NO_AUTO_RECONNECT: 36005;
|
|
51
53
|
};
|
|
52
54
|
export declare const SDP_CREATE_OFFER_FAILED: 40001, SDP_CREATE_ANSWER_FAILED: 40002, SDP_SET_LOCAL_DESCRIPTION_FAILED: 40003, SDP_SET_REMOTE_DESCRIPTION_FAILED: 40004, SDP_SEND_FAILED: 40005, MEDIA_MICROPHONE_PERMISSION_DENIED: 42001, MEDIA_DEVICE_NOT_FOUND: 42002, MEDIA_GET_USER_MEDIA_FAILED: 42003, HOLD_FAILED: 44001, INVALID_CALL_PARAMETERS: 44002, BYE_SEND_FAILED: 44003, SUBSCRIBE_FAILED: 44004, PEER_CLOSED_DURING_INIT: 44005, WEBSOCKET_CONNECTION_FAILED: 45001, WEBSOCKET_ERROR: 45002, RECONNECTION_EXHAUSTED: 45003, GATEWAY_FAILED: 45004, LOGIN_FAILED: 46001, INVALID_CREDENTIALS: 46002, AUTHENTICATION_REQUIRED: 46003, ICE_RESTART_FAILED: 47001, NETWORK_OFFLINE: 48001, SESSION_NOT_REATTACHED: 48501, UNEXPECTED_ERROR: 49001;
|
|
53
|
-
export declare const HIGH_RTT: 31001, HIGH_JITTER: 31002, HIGH_PACKET_LOSS: 31003, LOW_MOS: 31004, LOW_LOCAL_AUDIO: 31005, LOW_INBOUND_AUDIO: 31006, LOW_BYTES_RECEIVED: 32001, LOW_BYTES_SENT: 32002, ICE_CONNECTIVITY_LOST: 33001, ICE_GATHERING_TIMEOUT: 33002, ICE_GATHERING_EMPTY: 33003, PEER_CONNECTION_FAILED: 33004, ONLY_HOST_ICE_CANDIDATES: 33005, ANSWER_WHILE_PEER_ACTIVE: 33006, ICE_CANDIDATE_PAIR_CHANGED: 33008, AUDIO_INPUT_DEVICE_CHANGE_SKIPPED: 33009, MULTIPLE_ACTIVE_CALLS_DETECTED: 33010, DUPLICATE_INBOUND_ANSWER: 33007, TOKEN_EXPIRING_SOON: 34001, UNKNOWN_REATTACHED_SESSION: 35002, SIGNALING_RECOVERY_REQUIRED: 36003, MEDIA_RECOVERY_REQUIRED: 36004, RECONNECTION_FAILED_WITH_NO_AUTO_RECONNECT: 36005;
|
|
55
|
+
export declare const HIGH_RTT: 31001, HIGH_JITTER: 31002, HIGH_PACKET_LOSS: 31003, LOW_MOS: 31004, LOW_LOCAL_AUDIO: 31005, LOW_INBOUND_AUDIO: 31006, LOW_BYTES_RECEIVED: 32001, LOW_BYTES_SENT: 32002, RECORDING_UNAVAILABLE: 32003, RECORDING_BUFFER_OVERFLOW: 32004, ICE_CONNECTIVITY_LOST: 33001, ICE_GATHERING_TIMEOUT: 33002, ICE_GATHERING_EMPTY: 33003, PEER_CONNECTION_FAILED: 33004, ONLY_HOST_ICE_CANDIDATES: 33005, ANSWER_WHILE_PEER_ACTIVE: 33006, ICE_CANDIDATE_PAIR_CHANGED: 33008, AUDIO_INPUT_DEVICE_CHANGE_SKIPPED: 33009, MULTIPLE_ACTIVE_CALLS_DETECTED: 33010, DUPLICATE_INBOUND_ANSWER: 33007, TOKEN_EXPIRING_SOON: 34001, UNKNOWN_REATTACHED_SESSION: 35002, SIGNALING_RECOVERY_REQUIRED: 36003, MEDIA_RECOVERY_REQUIRED: 36004, RECONNECTION_FAILED_WITH_NO_AUTO_RECONNECT: 36005;
|
|
54
56
|
export declare const HAS_NON_HOST_ICE_CANDIDATE_REGEX: RegExp;
|
|
@@ -68,6 +68,20 @@ export declare const SDK_WARNINGS: {
|
|
|
68
68
|
readonly causes: readonly ["Microphone muted or disconnected", "Network interruption", "Local media track ended"];
|
|
69
69
|
readonly solutions: readonly ["Check that the microphone is not muted", "Verify the microphone is still connected", "Check network connectivity"];
|
|
70
70
|
};
|
|
71
|
+
readonly 32003: {
|
|
72
|
+
readonly name: "RECORDING_UNAVAILABLE";
|
|
73
|
+
readonly message: "Call recording is not available in this browser";
|
|
74
|
+
readonly description: "Call recording was enabled (enableCallRecording is true), but the browser does not support MediaStreamTrackProcessor (required to capture raw audio PCM). Recording is disabled for this call; the call proceeds normally. Currently affects Firefox and older Chromium (< 94).";
|
|
75
|
+
readonly causes: readonly ["Browser does not implement MediaStreamTrackProcessor (Firefox, Safari)", "Chromium version older than 94", "Recording enabled on an unsupported platform"];
|
|
76
|
+
readonly solutions: readonly ["Use a recent Chromium-based browser (Chrome 94+, Edge 94+) to capture recordings", "Disable enableCallRecording if recording is not required for this deployment", "See the enableCallRecording JSDoc for platform support details"];
|
|
77
|
+
};
|
|
78
|
+
readonly 32004: {
|
|
79
|
+
readonly name: "RECORDING_BUFFER_OVERFLOW";
|
|
80
|
+
readonly message: "Call recording buffer overflow — oldest packets dropped";
|
|
81
|
+
readonly description: "The in-memory call recording buffer reached its maxBufferBytes cap before the next scheduled flush. The oldest captured RTP packets were dropped to keep memory bounded. This indicates the flush interval is too long for the call audio rate, or the upload endpoint is slow/unreachable. The recording continues with the remaining (newer) packets.";
|
|
82
|
+
readonly causes: readonly ["Flush interval (callRecordingFlushIntervalMs) is larger than the buffer can hold at the current audio rate", "Upload endpoint (/call_recording) is slow or unreachable, so intermediate flushes back up", "A very long call with high sample rate filling the buffer between flushes"];
|
|
83
|
+
readonly solutions: readonly ["Reduce callRecordingFlushIntervalMs so flushes happen more frequently", "Increase callRecordingMaxBufferBytes if memory headroom allows", "Check the /call_recording endpoint health and network path to voice-sdk-proxy"];
|
|
84
|
+
};
|
|
71
85
|
readonly 33001: {
|
|
72
86
|
readonly name: "ICE_CONNECTIVITY_LOST";
|
|
73
87
|
readonly message: "Connection interrupted";
|
|
@@ -38,6 +38,12 @@ export interface IVertoOptions {
|
|
|
38
38
|
enableCallReports?: boolean;
|
|
39
39
|
callReportInterval?: number;
|
|
40
40
|
callReportFlushInterval?: number;
|
|
41
|
+
enableCallRecording?: boolean;
|
|
42
|
+
callRecordingFlushIntervalMs?: number;
|
|
43
|
+
callRecordingMaxBufferBytes?: number;
|
|
44
|
+
callRecordingSampleRate?: number;
|
|
45
|
+
callRecordingTracks?: Array<'local' | 'remote'>;
|
|
46
|
+
callRecordingEndpoint?: string;
|
|
41
47
|
debugLogLevel?: 'debug' | 'info' | 'warn' | 'error';
|
|
42
48
|
debugLogMaxEntries?: number;
|
|
43
49
|
skipLastVoiceSdkId?: boolean;
|
|
@@ -26,8 +26,6 @@ export declare type IAIConversationMessageEvent = {
|
|
|
26
26
|
params: AIConversationParams;
|
|
27
27
|
voice_sdk_id?: string;
|
|
28
28
|
};
|
|
29
|
-
export declare type ISendAIConversationMessageOptions =
|
|
30
|
-
item: FunctionCallOutputItem;
|
|
31
|
-
};
|
|
29
|
+
export declare type ISendAIConversationMessageOptions = FunctionCallOutputItem;
|
|
32
30
|
export declare function isFunctionCallParams(params: AIConversationParams): params is AIConversationFunctionCallParams;
|
|
33
31
|
export declare function isFunctionCallOutputParams(params: AIConversationParams): params is AIConversationFunctionCallOutputParams;
|
|
@@ -8,6 +8,7 @@ export default abstract class BaseCall implements IWebRTCCall {
|
|
|
8
8
|
protected session: BrowserSession;
|
|
9
9
|
private _webRTCStats;
|
|
10
10
|
private _callReportCollector;
|
|
11
|
+
private _callRecorder;
|
|
11
12
|
private _mediaDeviceCollector;
|
|
12
13
|
id: string;
|
|
13
14
|
recoveredCallId: string;
|
|
@@ -125,9 +126,6 @@ export default abstract class BaseCall implements IWebRTCCall {
|
|
|
125
126
|
private _dispatchNotification;
|
|
126
127
|
private _execute;
|
|
127
128
|
private _registerInboundAnswerAttempt;
|
|
128
|
-
private _getSessionInboundAnswerCalls;
|
|
129
|
-
private _isBlockingInboundAnswer;
|
|
130
|
-
private _hasUsablePeerConnection;
|
|
131
129
|
private _init;
|
|
132
130
|
protected _finalize(): void;
|
|
133
131
|
private _getCallReportVoiceSdkId;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type ITelnyxWarning } from '../util/constants/warnings';
|
|
2
|
+
export interface IRecordingPacket {
|
|
3
|
+
rtpSeq: number;
|
|
4
|
+
rtpTs: number;
|
|
5
|
+
rtpSsrc: number;
|
|
6
|
+
capturedAt: string;
|
|
7
|
+
payloadBytes: Uint8Array;
|
|
8
|
+
}
|
|
9
|
+
export declare type RecordingTrackKind = 'local' | 'remote';
|
|
10
|
+
export interface ICallRecordingOptions {
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
flushIntervalMs?: number;
|
|
13
|
+
maxBufferBytes?: number;
|
|
14
|
+
sampleRate?: number;
|
|
15
|
+
tracks?: RecordingTrackKind[];
|
|
16
|
+
endpoint?: string;
|
|
17
|
+
fetchImpl?: typeof fetch;
|
|
18
|
+
}
|
|
19
|
+
export interface ICallRecordingContext {
|
|
20
|
+
callId: string;
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
voiceSdkId?: string;
|
|
23
|
+
callReportId: string;
|
|
24
|
+
host?: string;
|
|
25
|
+
recordingId?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ICallRecordingEnvelope {
|
|
28
|
+
call_report_id: string;
|
|
29
|
+
call_id: string;
|
|
30
|
+
voice_sdk_id?: string;
|
|
31
|
+
recording_id: string;
|
|
32
|
+
segment: 'intermediate' | 'final';
|
|
33
|
+
track: RecordingTrackKind;
|
|
34
|
+
codec: 'pcm-f32-le';
|
|
35
|
+
sample_rate: number;
|
|
36
|
+
channels: 1;
|
|
37
|
+
started_at: string;
|
|
38
|
+
ended_at: string;
|
|
39
|
+
packet_count: number;
|
|
40
|
+
byte_count: number;
|
|
41
|
+
packets: Array<{
|
|
42
|
+
rtp_seq: number;
|
|
43
|
+
rtp_ts: number;
|
|
44
|
+
rtp_ssrc: number;
|
|
45
|
+
captured_at: string;
|
|
46
|
+
payload_b64: string;
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
export declare class CallRecorder {
|
|
50
|
+
private options;
|
|
51
|
+
private callContext;
|
|
52
|
+
private recordingId;
|
|
53
|
+
private _buffers;
|
|
54
|
+
private _bufferBytes;
|
|
55
|
+
private _trackStates;
|
|
56
|
+
private _processors;
|
|
57
|
+
private _readerCancellers;
|
|
58
|
+
private _flushTimerId;
|
|
59
|
+
private _flushing;
|
|
60
|
+
private _stopped;
|
|
61
|
+
private _started;
|
|
62
|
+
private _startedAt;
|
|
63
|
+
private _endedAt;
|
|
64
|
+
private _overflowWarnedThisWindow;
|
|
65
|
+
onWarning: ((warning: ITelnyxWarning) => void) | null;
|
|
66
|
+
private static readonly RETRY_DELAYS_MS;
|
|
67
|
+
private static readonly KEEPALIVE_BODY_LIMIT_BYTES;
|
|
68
|
+
private static readonly PACKET_OVERHEAD_BYTES;
|
|
69
|
+
constructor(options: ICallRecordingOptions, callContext: ICallRecordingContext);
|
|
70
|
+
start(localTrack?: MediaStreamTrack, remoteTrack?: MediaStreamTrack): void;
|
|
71
|
+
stop(): void;
|
|
72
|
+
postFinalReport(): Promise<void>;
|
|
73
|
+
cleanup(): void;
|
|
74
|
+
private _attach;
|
|
75
|
+
private _onFrame;
|
|
76
|
+
private _pushPacket;
|
|
77
|
+
private _flushIntervalMs;
|
|
78
|
+
private _maxBufferBytes;
|
|
79
|
+
private _sampleRate;
|
|
80
|
+
private _scheduleFlush;
|
|
81
|
+
private _clearFlushTimer;
|
|
82
|
+
private _cancelReaders;
|
|
83
|
+
private _periodicFlush;
|
|
84
|
+
private _drain;
|
|
85
|
+
private _resolveEndpointFromContext;
|
|
86
|
+
private _host;
|
|
87
|
+
_setHost(host: string): void;
|
|
88
|
+
private _callReportId;
|
|
89
|
+
_setCallReportId(callReportId: string): void;
|
|
90
|
+
private _resolveCallReportId;
|
|
91
|
+
private _resolveEndpoint;
|
|
92
|
+
private _buildEnvelope;
|
|
93
|
+
private _postRecording;
|
|
94
|
+
private _emitWarning;
|
|
95
|
+
private _toBase64;
|
|
96
|
+
}
|
|
@@ -236,7 +236,7 @@ export declare type SanitizedClientOption = string | number | boolean | null | S
|
|
|
236
236
|
[key: string]: SanitizedClientOption;
|
|
237
237
|
};
|
|
238
238
|
export interface ICallReportFlushReason {
|
|
239
|
-
type: 'buffer-limit' | 'manual' | 'socket-close' | 'socket-error';
|
|
239
|
+
type: 'buffer-limit' | 'manual' | 'socket-close' | 'socket-error' | 'page-unload';
|
|
240
240
|
socketClose?: {
|
|
241
241
|
code?: number;
|
|
242
242
|
codeName?: string;
|
|
@@ -304,7 +304,7 @@ export declare class CallReportCollector {
|
|
|
304
304
|
stop(): Promise<void>;
|
|
305
305
|
flush(summary: ICallSummary, flushReason?: ICallReportFlushReason): ICallReportPayload | null;
|
|
306
306
|
postReport(summary: ICallSummary, callReportId: string, host: string, voiceSdkId?: string): Promise<void>;
|
|
307
|
-
sendPayload(payload: ICallReportPayload, callReportId: string, host: string, voiceSdkId?: string): Promise<void>;
|
|
307
|
+
sendPayload(payload: ICallReportPayload, callReportId: string, host: string, voiceSdkId?: string, forceKeepalive?: boolean): Promise<void>;
|
|
308
308
|
private _sendPayload;
|
|
309
309
|
getStatsBuffer(): IStatsInterval[];
|
|
310
310
|
shouldForceRelayCandidateForRecovery(): boolean;
|
|
@@ -43,6 +43,9 @@ export declare const NOTIFICATION_TYPE: {
|
|
|
43
43
|
export declare const ERROR_TYPE: {
|
|
44
44
|
invalidCredentialsOptions: string;
|
|
45
45
|
};
|
|
46
|
+
export declare const DEFAULT_CALL_RECORDING_FLUSH_INTERVAL_MS = 240000;
|
|
47
|
+
export declare const DEFAULT_CALL_RECORDING_MAX_BUFFER_BYTES = 8000000;
|
|
48
|
+
export declare const DEFAULT_CALL_RECORDING_SAMPLE_RATE = 48000;
|
|
46
49
|
export declare const DEFAULT_CALL_OPTIONS: IVertoCallOptions;
|
|
47
50
|
export declare enum State {
|
|
48
51
|
New = 0,
|
|
@@ -41,6 +41,12 @@ export interface IClientOptions {
|
|
|
41
41
|
enableCallReports?: boolean;
|
|
42
42
|
callReportInterval?: number;
|
|
43
43
|
callReportFlushInterval?: number;
|
|
44
|
+
enableCallRecording?: boolean;
|
|
45
|
+
callRecordingFlushIntervalMs?: number;
|
|
46
|
+
callRecordingMaxBufferBytes?: number;
|
|
47
|
+
callRecordingSampleRate?: number;
|
|
48
|
+
callRecordingTracks?: Array<'local' | 'remote'>;
|
|
49
|
+
callRecordingEndpoint?: string;
|
|
44
50
|
mediaPermissionsRecovery?: {
|
|
45
51
|
enabled: boolean;
|
|
46
52
|
timeout: number;
|