UNPKG

webrtc-issue-detector

Version:

WebRTC diagnostic tool that detects issues with network or user devices

426 lines (425 loc) 12.4 kB
import PeriodicWebRTCStatsReporter from './parser/PeriodicWebRTCStatsReporter'; import { AddConnectionPayload } from './parser/CompositeRTCStatsParser'; import { WebRTCIssueEmitter } from './WebRTCIssueEmitter'; export interface WIDWindow { wid: { handleNewPeerConnection(pc: RTCPeerConnection, id?: string): void; }; } export declare type IssueDetectorResult = IssuePayload[]; export interface IssueDetector { detect(data: WebRTCStatsParsed, networkScores?: NetworkScores): IssueDetectorResult; } export interface INetworkScoresCalculator { calculate(data: WebRTCStatsParsed): NetworkScores; } export declare enum EventType { Issue = "issue", NetworkScoresUpdated = "network-scores-updated", StatsParsingFinished = "stats-parsing-finished" } export declare type EventPayload = IssueDetectorResult; export interface StatsReportItem { id: string; stats: WebRTCStatsParsed; timeTaken: number; } export interface ConnectionInfo { id: string; pc: RTCPeerConnection; } export interface CompositeStatsParser { addPeerConnection: (payload: AddConnectionPayload) => void; parse: () => Promise<StatsReportItem[]>; } export interface StatsParser { parse: (info: ConnectionInfo) => Promise<StatsReportItem | undefined>; } export declare type WebRTCIssueDetectorConstructorParams = { issueEmitter?: WebRTCIssueEmitter; networkScoresCalculator?: INetworkScoresCalculator; detectors?: IssueDetector[]; compositeStatsParser?: CompositeStatsParser; statsReporter?: PeriodicWebRTCStatsReporter; logger?: Logger; onIssues?: (payload: IssueDetectorResult) => void; onNetworkScoresUpdated?: (payload: NetworkScores) => void; onStats?: (payload: StatsReportItem[]) => void; ignoreSSRCList?: number[]; getStatsInterval?: number; autoAddPeerConnections?: boolean; }; export declare enum IssueType { Network = "network", CPU = "cpu", Server = "server", Stream = "stream" } export declare enum IssueReason { OutboundNetworkQuality = "outbound-network-quality", InboundNetworkQuality = "inbound-network-quality", OutboundNetworkMediaLatency = "outbound-network-media-latency", InboundNetworkMediaLatency = "inbound-network-media-latency", NetworkMediaSyncFailure = "network-media-sync-failure", OutboundNetworkThroughput = "outbound-network-throughput", InboundNetworkThroughput = "inbound-network-throughput", EncoderCPUThrottling = "encoder-cpu-throttling", DecoderCPUThrottling = "decoder-cpu-throttling", ServerIssue = "server-issue", UnknownVideoDecoderIssue = "unknown-video-decoder", LowInboundMOS = "low-inbound-mean-opinion-score", LowOutboundMOS = "low-outbound-mean-opinion-score", FrozenVideoTrack = "frozen-video-track", MissingVideoStreamData = "missing-video-stream-data", MissingAudioStreamData = "missing-audio-stream-data" } export declare type IssuePayload = { type: IssueType; reason: IssueReason; ssrc?: number; iceCandidate?: string; data?: number; statsSample?: Record<string, unknown>; trackIdentifier?: string; }; export declare type DetectIssuesPayload = { data: WebRTCStatsParsed; }; export declare type NetworkScore = number; export declare type NetworkQualityStatsSample = { avgJitter: number; rtt: number; packetsLoss: number; }; export declare type NetworkScores = { outbound?: NetworkScore; inbound?: NetworkScore; connectionId?: string; statsSamples: { outboundStatsSample?: NetworkQualityStatsSample; inboundStatsSample?: NetworkQualityStatsSample; }; }; export declare type StatsParsingFinishedPayload = { timeTaken: number; ts: number; }; export declare type ParsedInboundAudioStreamStats = { audioLevel: number; bitrate: number; bytesReceived: number; clockRate: number; codecId: string; concealedSamples: number; concealmentEvents: number; fecPacketsDiscarded: number; fecPacketsReceived: number; headerBytesReceived: number; id: string; insertedSamplesForDeceleration: number; jitter: number; jitterBufferDelay: number; jitterBufferEmittedCount: number; kind: 'audio'; lastPacketReceivedTimestamp: number; mediaType: string; mimeType: string; packetRate: number; packetsDiscarded: number; packetsLost: number; packetsReceived: number; payloadType: number; remoteId: string; removedSamplesForAcceleration: number; silentConcealedSamples: number; ssrc: number; timestamp: number; totalAudioEnergy: number; totalSamplesDuration: number; totalSamplesReceived: number; track: { audioLevel: number; concealedSamples: number; concealmentEvents: number; detached: boolean; ended: boolean; id: string; insertedSamplesForDeceleration: number; jitterBufferDelay: number; jitterBufferEmittedCount: number; kind: 'audio'; remoteSource: boolean; removedSamplesForAcceleration: number; silentConcealedSamples: number; timestamp: number; totalAudioEnergy: number; totalSamplesDuration: number; totalSamplesReceived: number; trackIdentifier: string; type: string; }; trackId: string; transportId: string; trackIdentifier: string; }; export declare type ParsedOutboundAudioStreamStats = { bitrate: number; bytesSent: number; clockRate: number; codecId: string; headerBytesSent: number; id: string; kind: string; mediaSourceId: string; mediaType: string; mimeType: string; nackCount: number; packetRate: number; packetsSent: number; payloadType: number; remoteId: string; retransmittedBytesSent: number; retransmittedPacketsSent: number; ssrc: number; timestamp: number; targetBitrate: number; track: { audioLevel: number; echoReturnLoss: number; echoReturnLossEnhancement: number; id: string; kind: string; timestamp: number; totalAudioEnergy: number; totalSamplesDuration: number; trackIdentifier: string; type: string; }; trackId: string; transportId: string; }; export declare type ParsedInboundVideoStreamStats = { bitrate: number; bytesReceived: number; clockRate: number; codecId: string; decoderImplementation: string; firCount: number; frameHeight: number; frameWidth: number; framesDecoded: number; framesDropped: number; framesPerSecond: number; framesReceived: number; headerBytesReceived: number; id: string; jitter: number; jitterBufferDelay: number; jitterBufferEmittedCount: number; keyFramesDecoded: number; kind: 'video'; mediaType: string; mimeType: string; nackCount: number; packetRate: number; packetsLost: number; packetsReceived: number; payloadType: number; pliCount: number; ssrc: number; timestamp: number; totalDecodeTime: number; totalInterFrameDelay: number; totalSquaredInterFrameDelay: number; freezeCount: number; totalFreezesDuration: number; track: { detached: boolean; ended: boolean; frameHeight: number; frameWidth: number; framesDecoded: number; framesDropped: number; framesReceived: number; id: string; jitterBufferDelay: number; jitterBufferEmittedCount: number; kind: 'video'; remoteSource: boolean; timestamp: number; trackIdentifier: string; type: string; }; trackId: string; transportId: string; trackIdentifier: string; }; export declare type ParsedOutboundVideoStreamStats = { bitrate: number; bytesSent: number; clockRate: number; codecId: string; encoderImplementation: string; firCount: number; frameHeight: number; frameWidth: number; framesEncoded: number; framesPerSecond: number; framesSent: number; headerBytesSent: number; hugeFramesSent: number; id: string; keyFramesEncoded: number; kind: string; mediaSourceId: string; mediaType: string; mimeType: string; nackCount: number; packetRate: number; packetsSent: number; payloadType: number; pliCount: number; qpSum: number; qualityLimitationDurations: { other: number; cpu: number; bandwidth: number; none: number; }; qualityLimitationReason: 'none' | 'bandwidth' | 'cpu' | 'other'; qualityLimitationResolutionChanges: number; remoteId: string; retransmittedBytesSent: number; retransmittedPacketsSent: number; rid: string; ssrc: number; timestamp: number; totalEncodeTime: number; totalEncodedBytesTarget: number; totalPacketSendDelay: number; track: { id: string; frames: number; framesPerSecond: number; height: number; timestamp: number; type: string; trackIdentifier: string; kind: string; width: number; }; trackId: string; transportId: string; type: string; }; export declare type ParsedConnectionStats = { availableOutgoingBitrate: number; bytesReceived: number; bytesSent: number; currentRoundTripTime: number; id: string; transportId: string; packetsReceived: number; packetsSent: number; state: string; totalRoundTripTime: number; type: string; local: IceCandidateConnectionStats; remote: IceCandidateConnectionStats; }; export declare type IceCandidateConnectionStats = { address: string; candidateType: string; id: string; ip: string; isRemote: boolean; networkType?: string; port: number; priority: number; protocol: 'udp' | 'tcp'; timestamp: number; transportId: string; type: 'local-candidate' | 'remote-candidate'; }; export declare type ParsedRemoteInboundStreamStats = { clockRate: number; codecId: string; fractionLost: number; id: string; jitter: number; kind: string; localId: string; mimeType: string; packetsLost: number; payloadType: number; roundTripTime: number; roundTripTimeMeasurements: number; ssrc: number; timestamp: number; totalRoundTripTime: number; transportId: string; type: string; }; export declare type ParsedRemoteOutboundStreamStats = { bytesSent: number; clockRate: number; codecId: string; id: string; kind: string; localId: string; mimeType: string; packetsSent: number; payloadType: number; remoteTimestamp: number; reportsSent: number; roundTripTimeMeasurements: number; ssrc: number; timestamp: number; totalRoundTripTime: number; transportId: string; type: string; }; export declare type RemoteParsedStats = { video: { inbound: ParsedRemoteInboundStreamStats[]; outbound: ParsedRemoteOutboundStreamStats[]; }; audio: { inbound: ParsedRemoteInboundStreamStats[]; outbound: ParsedRemoteOutboundStreamStats[]; }; }; export declare type WebRTCStatsParsed = { audio: { inbound: ParsedInboundAudioStreamStats[]; outbound: ParsedOutboundAudioStreamStats[]; }; video: { inbound: ParsedInboundVideoStreamStats[]; outbound: ParsedOutboundVideoStreamStats[]; }; connection: ParsedConnectionStats; remote: RemoteParsedStats; }; export interface Logger { debug: (msg: any, ...meta: any[]) => void; info: (msg: any, ...meta: any[]) => void; warn: (msg: any, ...meta: any[]) => void; error: (msg: any, ...meta: any[]) => void; } export declare enum MosQuality { BAD = 2.1, POOR = 2.6, FAIR = 3.1, GOOD = 3.8, EXCELLENT = 4.3 } export declare type WebRTCStatsParsedWithNetworkScores = WebRTCStatsParsed & { networkScores: NetworkScores; }; declare type CommonKeys<T, U> = Extract<keyof T, keyof U>; declare type CommonFields<T, U> = { [K in CommonKeys<T, U>]: T[K] extends object ? U[K] extends object ? CommonFields<T[K], U[K]> : never : T[K]; }; export declare type CommonParsedInboundStreamStats = CommonFields<ParsedInboundVideoStreamStats, ParsedInboundAudioStreamStats>; export {};