@telnyx/webrtc
Version:
Telnyx WebRTC Client
347 lines (346 loc) • 11.6 kB
TypeScript
import { ILogEntry } from '../../../Modules/Verto/util/LogCollector';
import { type ITelnyxWarning } from '../../../Modules/Verto/util/errors';
export interface ILocalAudioTrackSnapshot {
id?: string;
label?: string;
enabled?: boolean;
muted?: boolean;
readyState?: MediaStreamTrackState;
contentHint?: string;
settings?: {
deviceId?: string;
groupId?: string;
channelCount?: number;
sampleRate?: number;
sampleSize?: number;
latency?: number;
echoCancellation?: boolean;
noiseSuppression?: boolean;
autoGainControl?: boolean;
};
}
export interface ILocalAudioSourceStats {
id?: string;
trackIdentifier?: string;
audioLevel?: number;
totalAudioEnergy?: number;
totalSamplesDuration?: number;
echoReturnLoss?: number;
echoReturnLossEnhancement?: number;
}
interface ICECandidateInfo {
id?: string;
address?: string;
port?: number;
candidateType?: string;
protocol?: string;
networkType?: string;
url?: string;
relayProtocol?: string;
}
export interface IICECandidatePair {
id?: string;
localCandidateId?: string;
remoteCandidateId?: string;
state?: string;
nominated?: boolean;
writable?: boolean;
currentRoundTripTime?: number;
local?: ICECandidateInfo;
remote?: ICECandidateInfo;
requestsSent?: number;
responsesReceived?: number;
}
export interface ITransportStats {
iceState?: string;
dtlsState?: string;
srtpCipher?: string;
tlsVersion?: string;
selectedCandidatePairChanges?: number;
selectedCandidatePairId?: string;
}
export interface ICallReportOptions {
enabled: boolean;
interval: number;
intermediateReportInterval?: number;
}
export interface ILogCollectorOptions {
enabled: boolean;
level: 'debug' | 'info' | 'warn' | 'error';
maxEntries: number;
}
export interface IStatsInterval {
intervalStartUtc: string;
intervalEndUtc: string;
audio?: {
outbound?: {
packetsSent?: number;
bytesSent?: number;
audioLevelAvg?: number;
bitrateAvg?: number;
localTrack?: ILocalAudioTrackSnapshot;
mediaSource?: ILocalAudioSourceStats;
retransmittedPacketsSent?: number;
retransmittedBytesSent?: number;
headerBytesSent?: number;
nackCount?: number;
targetBitrate?: number;
totalPacketSendDelay?: number;
active?: boolean;
codec?: {
mimeType?: string;
clockRate?: number;
channels?: number;
payloadType?: number;
sdpFmtpLine?: string;
codecId?: string;
};
};
inbound?: {
packetsReceived?: number;
bytesReceived?: number;
packetsLost?: number;
packetsDiscarded?: number;
jitterBufferDelay?: number;
jitterBufferEmittedCount?: number;
totalSamplesReceived?: number;
concealedSamples?: number;
concealmentEvents?: number;
audioLevelAvg?: number;
jitterAvg?: number;
bitrateAvg?: number;
nackCount?: number;
headerBytesReceived?: number;
fecPacketsReceived?: number;
fecPacketsDiscarded?: number;
jitterBufferTargetDelay?: number;
jitterBufferMinimumDelay?: number;
totalSamplesDecoded?: number;
samplesDecodedWithSilence?: number;
samplesDecodedWithConcealment?: number;
totalAudioEnergy?: number;
totalSamplesDuration?: number;
codec?: {
mimeType?: string;
clockRate?: number;
channels?: number;
payloadType?: number;
sdpFmtpLine?: string;
codecId?: string;
};
};
};
connection?: {
roundTripTimeAvg?: number;
currentRoundTripTime?: number;
roundTripTimeSource?: string;
packetsSent?: number;
packetsReceived?: number;
bytesSent?: number;
bytesReceived?: number;
};
ice?: IICECandidatePair;
transport?: ITransportStats;
mediaPlayout?: {
synthesizedSamples?: number;
synthesizedDuration?: number;
totalPlayoutDelay?: number;
totalSampleCount?: number;
};
remoteRtcp?: {
inbound?: {
packetsReceived?: number;
packetsLost?: number;
fractionLost?: number;
jitter?: number;
roundTripTime?: number;
totalRoundTripTime?: number;
roundTripTimeMeasurements?: number;
roundTripTimeAvg?: number;
nackCount?: number;
reportsReceived?: number;
packetsDiscarded?: number;
};
outbound?: {
packetsSent?: number;
bytesSent?: number;
reportsCount?: number;
roundTripTime?: number;
totalPacketSendDelay?: number;
};
};
}
export interface ICallSummary {
callId: string;
destinationNumber?: string;
callerNumber?: string;
direction?: 'inbound' | 'outbound';
state?: string;
durationSeconds?: number;
telnyxSessionId?: string;
telnyxLegId?: string;
voiceSdkSessionId?: string;
sdkVersion?: string;
startTimestamp?: string;
endTimestamp?: string;
clientSummary?: IClientSummary;
}
export interface IClientSummary {
authentication?: {
type?: 'anonymous_login' | 'login_token' | 'login_password' | 'token' | 'unknown';
anonymousLogin?: {
targetType?: string;
targetId?: string;
targetVersionId?: string;
targetParams?: SanitizedClientOption;
};
};
connection?: {
env?: string;
host?: string;
project?: string;
region?: string;
dc?: string;
rtcIp?: string;
rtcPort?: number;
autoReconnect?: boolean;
maxReconnectAttempts?: number;
keepConnectionAliveOnSocketClose?: boolean;
hangupOnBeforeUnload?: boolean;
useCanaryRtcServer?: boolean;
skipLastVoiceSdkId?: boolean;
skipTrailing?: boolean;
};
media?: {
audio?: unknown;
video?: unknown;
mutedMicOnStart?: boolean;
prefetchIceCandidates?: boolean;
forceRelayCandidate?: boolean;
trickleIce?: boolean;
iceServers?: Array<{
urls?: string | string[];
hasUsername?: boolean;
hasCredential?: boolean;
}>;
};
callReports?: {
enabled?: boolean;
intervalMs?: number;
flushIntervalMs?: number;
debugLogLevel?: string;
debugLogMaxEntries?: number;
};
}
export declare type SanitizedClientOption = string | number | boolean | null | SanitizedClientOption[] | {
[key: string]: SanitizedClientOption;
};
export interface ICallReportFlushReason {
type: 'buffer-limit' | 'manual' | 'socket-close' | 'socket-error' | 'page-unload';
socketClose?: {
code?: number;
codeName?: string;
reason?: string;
wasClean?: boolean;
error?: string;
};
}
export interface ICallReportPayload {
summary: ICallSummary;
stats: IStatsInterval[];
logs?: ILogEntry[];
segment?: number;
flushReason?: ICallReportFlushReason;
}
export declare class CallReportCollector {
private options;
private logCollectorOptions;
private peerConnection;
private intervalId;
private statsBuffer;
private intervalStartTime;
private callStartTime;
private callEndTime;
private logCollector;
private intervalAudioLevels;
private intervalJitters;
private intervalRTTs;
private intervalBitrates;
private previousStats;
private previousCandidatePairSnapshot;
private static readonly INITIAL_COLLECTION_INTERVAL_MS;
private readonly MAX_BUFFER_SIZE;
private static readonly STATS_FLUSH_THRESHOLD;
private static readonly LOGS_FLUSH_THRESHOLD;
private static readonly DEFAULT_INTERMEDIATE_REPORT_INTERVAL_MS;
onFlushNeeded: (() => void) | null;
onWarning: ((warning: ITelnyxWarning) => void) | null;
private static readonly CONSECUTIVE_BREACHES_REQUIRED;
private static readonly THRESHOLD_RTT_MS;
private static readonly THRESHOLD_JITTER_MS;
private static readonly THRESHOLD_PACKET_LOSS_PCT;
private static readonly THRESHOLD_MOS;
private static readonly THRESHOLD_LOCAL_AUDIO_LEVEL;
private static readonly CONFIRMED_LOCAL_AUDIO_SILENCE_MS;
private static readonly THRESHOLD_INBOUND_AUDIO_LEVEL;
private _breachCounters;
private _activeWarnings;
private _lastWarningEmitted;
private static readonly WARNING_THROTTLE_MS;
private _prevPacketsReceived;
private _prevPacketsLost;
private _previousStatsEntryForWarnings;
private _lastLocalAudioTrackSnapshotJson;
private _hasConfirmedLocalAudio;
private _confirmedLocalAudioSilenceMs;
private _segmentIndex;
private _lastIntermediateFlushTime;
private _flushing;
private _stopped;
private static readonly RETRY_DELAYS_MS;
private static readonly KEEPALIVE_BODY_LIMIT_BYTES;
constructor(options: ICallReportOptions, logCollectorOptions?: ILogCollectorOptions);
start(peerConnection: RTCPeerConnection): void;
stop(): Promise<void>;
flush(summary: ICallSummary, flushReason?: ICallReportFlushReason): ICallReportPayload | null;
postReport(summary: ICallSummary, callReportId: string, host: string, voiceSdkId?: string): Promise<void>;
sendPayload(payload: ICallReportPayload, callReportId: string, host: string, voiceSdkId?: string, forceKeepalive?: boolean): Promise<void>;
private _sendPayload;
getStatsBuffer(): IStatsInterval[];
shouldForceRelayCandidateForRecovery(): boolean;
getLogs(): ILogEntry[];
private _positiveDelta;
cleanup(): void;
private _scheduleNextCollection;
private _collectionIntervalFor;
private _positiveInterval;
private _collectStats;
private _getIntermediateReportInterval;
private _requestIntermediateFlushIfNeeded;
private _checkQualityWarnings;
private _trackLowLocalAudio;
private _resetLowLocalAudioWarning;
private _getStatsIntervalDurationMs;
private _trackLowInboundAudio;
private _trackBreach;
private _emitWarningOncePerEpisode;
private _emitWarning;
private _createStatsEntry;
private _resolveCandidate;
private _getCodec;
private _buildCodecSnapshot;
private _getOutboundMediaSource;
private _getLocalAudioTrackSnapshot;
private _getOutboundAudioSourceStats;
private _logLocalAudioTrackSnapshot;
private _withoutUndefined;
private _stableStringify;
private _sortObjectKeys;
private _getOutboundAudioLevel;
private _getInboundAudioLevel;
private _computeAudioLevelFromEnergy;
private _getTrackAudioLevel;
private _average;
private _resetIntervalAccumulators;
}
export {};