UNPKG

@observertc/observer-js

Version:

Server Side NodeJS Library for processing ObserveRTC Samples

402 lines (333 loc) 20.4 kB
import { ObservedCall } from './ObservedCall'; import { ObservedCertificate } from './ObservedCertificate'; import { ObservedClient, ObservedClientEvents } from './ObservedClient'; import { ObservedCodec } from './ObservedCodec'; import { ObservedDataChannel } from './ObservedDataChannel'; import { ObservedIceCandidate } from './ObservedIceCandidate'; import { ObservedIceCandidatePair } from './ObservedIceCandidatePair'; import { ObservedIceTransport } from './ObservedIceTransport'; import { ObservedInboundRtp } from './ObservedInboundRtp'; import { ObservedInboundTrack } from './ObservedInboundTrack'; import { ObservedMediaPlayout } from './ObservedMediaPlayout'; import { ObservedMediaSource } from './ObservedMediaSource'; import { ObservedOutboundRtp } from './ObservedOutboundRtp'; import { ObservedOutboundTrack } from './ObservedOutboundTrack'; import { ObservedPeerConnection } from './ObservedPeerConnection'; import { TrackReport } from './Reports'; import { ClientEvent, ClientIssue, ClientMetaData, ClientSample, ExtensionStat } from './schema/ClientSample'; export class ObservedCallEventMonitor<Context> { public constructor( public readonly call: ObservedCall, public readonly context: Context, ) { this._onPeerConnconnectionAdded = this._onPeerConnconnectionAdded.bind(this); this._onPeerConnectionRemoved = this._onPeerConnectionRemoved.bind(this); this._onCertificateAdded = this._onCertificateAdded.bind(this); this._onCertificateRemoved = this._onCertificateRemoved.bind(this); this._onInboundTrackAdded = this._onInboundTrackAdded.bind(this); this._onInboundTrackRemoved = this._onInboundTrackRemoved.bind(this); this._onOutboundTrackAdded = this._onOutboundTrackAdded.bind(this); this._onOutboundTrackRemoved = this._onOutboundTrackRemoved.bind(this); this._onInboundRtpAdded = this._onInboundRtpAdded.bind(this); this._onInboundRtpRemoved = this._onInboundRtpRemoved.bind(this); this._onOutboundRtpAdded = this._onOutboundRtpAdded.bind(this); this._onOutboundRtpRemoved = this._onOutboundRtpRemoved.bind(this); this._onDataChannelAdded = this._onDataChannelAdded.bind(this); this._onDataChannelRemoved = this._onDataChannelRemoved.bind(this); this._onAddedIceTransport = this._onAddedIceTransport.bind(this); this._onRemovedIceTransport = this._onRemovedIceTransport.bind(this); this._onIceCandidateAdded = this._onIceCandidateAdded.bind(this); this._onIceCandidateRemoved = this._onIceCandidateRemoved.bind(this); this._onAddedIceCandidatePair = this._onAddedIceCandidatePair.bind(this); this._onRemovedIceCandidatePair = this._onRemovedIceCandidatePair.bind(this); this._onAddedMediaCodec = this._onAddedMediaCodec.bind(this); this._onRemovedMediaCodec = this._onRemovedMediaCodec.bind(this); this._onAddedMediaPlayout = this._onAddedMediaPlayout.bind(this); this._onRemovedMediaPlayout = this._onRemovedMediaPlayout.bind(this); this._onMediaSourceAdded = this._onMediaSourceAdded.bind(this); this._onMediaSourceRemoved = this._onMediaSourceRemoved.bind(this); this._onClientIssue = this._onClientIssue.bind(this); this._onClientMetadata = this._onClientMetadata.bind(this); this._onClientJoined = this._onClientJoined.bind(this); this._onClientLeft = this._onClientLeft.bind(this); this._onUserMediaError = this._onUserMediaError.bind(this); this._onUsingTurn = this._onUsingTurn.bind(this); this._onClientAdded = this._onClientAdded.bind(this); this._onCallAdded = this._onCallAdded.bind(this); this._onClientRejoined = this._onClientRejoined.bind(this); this._onClientExtensionStats = this._onClientExtensionStats.bind(this); this._onCallAdded(call); } // Public event handlers public onCallClosed?: (call: ObservedCall, ctx: Context) => void; public onCallEmpty?: (call: ObservedCall, ctx: Context) => void; public onCallNotEmpty?: (call: ObservedCall, ctx: Context) => void; public onCallUpdated?: (call: ObservedCall, ctx: Context) => void; public onClientAdded?: (client: ObservedClient, ctx: Context) => void; public onClientClosed?: (client: ObservedClient, ctx: Context) => void; public onClientRejoined?: (client: ObservedClient, ctx: Context) => void; public onClientIssue?: (observedClent: ObservedClient, issue: ClientIssue, ctx: Context) => void; public onClientMetadata?: (observedClient: ObservedClient, metadata: ClientMetaData, ctx: Context) => void; public onClientExtensionStats?: (observedClient: ObservedClient, extensionStats: ExtensionStat, ctx: Context) => void; public onClientJoined?: (client: ObservedClient, ctx: Context) => void; public onClientLeft?: (client: ObservedClient, ctx: Context) => void; public onClientUserMediaError?: (observedClient: ObservedClient, error: string, ctx: Context) => void; public onClientUsingTurn?: (client: ObservedClient, usingTurn: boolean, ctx: Context) => void; public onClientUpdated?: (client: ObservedClient, sample: ClientSample, ctx: Context) => void; public onClientEvent?: (client: ObservedClient, event: ClientEvent, ctx: Context) => void; public onPeerConnectionAdded?: (peerConnection: ObservedPeerConnection, ctx: Context) => void; public onPeerConnectionRemoved?: (peerConnection: ObservedPeerConnection, ctx: Context) => void; public onSelectedCandidatePairChanged?: (peerConnection: ObservedPeerConnection, ctx: Context) => void; public onIceGatheringStateChange?: (peerConnection: ObservedPeerConnection, ctx: Context) => void; public onIceConnectionStateChange?: (peerConnection: ObservedPeerConnection, ctx: Context) => void; public onConnectionStateChange?: (peerConnection: ObservedPeerConnection, ctx: Context) => void; public onCertificateAdded?: (certificate: ObservedCertificate, ctx: Context) => void; public onCertificateRemoved?: (certificate: ObservedCertificate, ctx: Context) => void; public onInboundTrackAdded?: (inboundTrack: ObservedInboundTrack, ctx: Context) => void; public onInboundTrackRemoved?: (inboundTrack: ObservedInboundTrack, ctx: Context) => void; public onOutboundTrackAdded?: (outboundTrack: ObservedOutboundTrack, ctx: Context) => void; public onOutboundTrackRemoved?: (outboundTrack: ObservedOutboundTrack, ctx: Context) => void; public onInboundRtpAdded?: (inboundRtp: ObservedInboundRtp, ctx: Context) => void; public onInboundRtpRemoved?: (inboundRtp: ObservedInboundRtp, ctx: Context) => void; public onOutboundRtpAdded?: (outboundRtp: ObservedOutboundRtp, ctx: Context) => void; public onOutboundRtpRemoved?: (outboundRtp: ObservedOutboundRtp, ctx: Context) => void; public onDataChannelAdded?: (dataChannel: ObservedDataChannel, ctx: Context) => void; public onDataChannelRemoved?: (dataChannel: ObservedDataChannel, ctx: Context) => void; public onAddedIceTransport?: (iceTransport: ObservedIceTransport, ctx: Context) => void; public onRemovedIceTransport?: (iceTransport: ObservedIceTransport, ctx: Context) => void; public onIceCandidateAdded?: (iceCandidate: ObservedIceCandidate, ctx: Context) => void; public onIceCandidateRemoved?: (iceCandidate: ObservedIceCandidate, ctx: Context) => void; public onAddedIceCandidatePair?: (candidatePair: ObservedIceCandidatePair, ctx: Context) => void; public onRemovedIceCandidatePair?: (candidatePair: ObservedIceCandidatePair, ctx: Context) => void; public onAddedMediaCodec?: (codec: ObservedCodec, ctx: Context) => void; public onRemovedMediaCodec?: (codec: ObservedCodec, ctx: Context) => void; public onAddedMediaPlayout?: (mediaPlayout: ObservedMediaPlayout, ctx: Context) => void; public onRemovedMediaPlayout?: (mediaPlayout: ObservedMediaPlayout, ctx: Context) => void; public onMediaSourceAdded?: (mediaSource: ObservedMediaSource, ctx: Context) => void; public onMediaSourceRemoved?: (mediaSource: ObservedMediaSource, ctx: Context) => void; public onTrackReport?: (trackReport: TrackReport, ctx: Context) => void; private _onCallAdded(call: ObservedCall) { const onCallEmpty = () => this.onCallEmpty?.(call, this.context); const onCallNotEmpty = () => this.onCallNotEmpty?.(call, this.context); const onCallUpdated = () => this.onCallUpdated?.(call, this.context); call.once('close', () => { call.off('newclient', this._onClientAdded); call.off('empty', onCallEmpty); call.off('not-empty', onCallNotEmpty); call.off('update', onCallUpdated); this.onCallClosed?.(call, this.context); }); call.on('newclient', this._onClientAdded); call.on('empty', onCallEmpty); call.on('not-empty', onCallNotEmpty); call.on('update', onCallUpdated); } private _onClientAdded(observedClient: ObservedClient) { const onClientIssue = (issue: ClientIssue) => this._onClientIssue(observedClient, issue); const onClientMetadata = (metaData: ClientMetaData) => this._onClientMetadata(observedClient, metaData); const onClientJoined = () => this._onClientJoined(observedClient); const onClientLeft = () => this._onClientLeft(observedClient); const onClientRejoined = () => this._onClientRejoined(observedClient); const onClientExtensionStats = (extensionStats: ExtensionStat) => this._onClientExtensionStats(observedClient, extensionStats); const onUsingTurn = (usingTurn: boolean) => this._onUsingTurn(observedClient, usingTurn); const onUserMediaError = (error: string) => this._onUserMediaError(observedClient, error); const onClientUpdated = (...args: ObservedClientEvents['update']) => this.onClientUpdated?.(observedClient, args[0], this.context); const onClientEvent = (event: ClientEvent) => this.onClientEvent?.(observedClient, event, this.context); const onTrackReport = (trackReport: TrackReport) => this._onTrackReport(observedClient, trackReport); observedClient.once('close', () => { observedClient.off('newpeerconnection', this._onPeerConnconnectionAdded); observedClient.off('issue', onClientIssue); observedClient.off('metaData', onClientMetadata); observedClient.off('joined', onClientJoined); observedClient.off('left', onClientLeft); observedClient.off('rejoined', onClientJoined); observedClient.off('usermediaerror', onUserMediaError); observedClient.off('usingturn', onUsingTurn); observedClient.off('update', onClientUpdated); observedClient.off('clientEvent', onClientEvent); observedClient.off('trackreport', onTrackReport); this.onClientClosed?.(observedClient, this.context); }); observedClient.on('newpeerconnection', this._onPeerConnconnectionAdded); observedClient.on('issue', onClientIssue); observedClient.on('metaData', onClientMetadata); observedClient.on('joined', onClientJoined); observedClient.on('left', onClientLeft); observedClient.on('rejoined', onClientRejoined); observedClient.on('usermediaerror', onUserMediaError); observedClient.on('usingturn', onUsingTurn); observedClient.on('extensionStats', onClientExtensionStats); observedClient.on('update', onClientUpdated); observedClient.on('clientEvent', onClientEvent); observedClient.on('trackreport', onTrackReport); this.onClientAdded?.(observedClient, this.context); } private _onClientRejoined(observedClient: ObservedClient) { this.onClientRejoined?.(observedClient, this.context); } private _onPeerConnconnectionAdded(peerConnection: ObservedPeerConnection) { const onSelectedCandidatePairChanged = () => this.onSelectedCandidatePairChanged?.(peerConnection, this.context); const onIceGatheringStateChange = () => this.onIceGatheringStateChange?.(peerConnection, this.context); const onIceConnectionStateChange = () => this.onIceConnectionStateChange?.(peerConnection, this.context); const onConnectionStateChange = () => this.onConnectionStateChange?.(peerConnection, this.context); peerConnection.once('close', () => { peerConnection.off('added-certificate', this._onCertificateAdded); peerConnection.off('removed-certificate', this._onCertificateRemoved); peerConnection.off('added-inbound-track', this._onInboundTrackAdded); peerConnection.off('removed-inbound-track', this._onInboundTrackRemoved); peerConnection.off('added-outbound-track', this._onOutboundTrackAdded); peerConnection.off('removed-outbound-track', this._onOutboundTrackRemoved); peerConnection.off('added-inbound-rtp', this._onInboundRtpAdded); peerConnection.off('removed-inbound-rtp', this._onInboundRtpRemoved); peerConnection.off('added-outbound-rtp', this._onOutboundRtpAdded); peerConnection.off('removed-outbound-rtp', this._onOutboundRtpRemoved); peerConnection.off('added-data-channel', this._onDataChannelAdded); peerConnection.off('removed-data-channel', this._onDataChannelRemoved); peerConnection.off('added-ice-transport', this._onAddedIceTransport); peerConnection.off('removed-ice-transport', this._onRemovedIceTransport); peerConnection.off('added-ice-candidate', this._onIceCandidateAdded); peerConnection.off('removed-ice-candidate', this._onIceCandidateRemoved); peerConnection.off('added-ice-candidate-pair', this._onAddedIceCandidatePair); peerConnection.off('removed-ice-candidate-pair', this._onRemovedIceCandidatePair); peerConnection.off('added-codec', this._onAddedMediaCodec); peerConnection.off('removed-codec', this._onRemovedMediaCodec); peerConnection.off('added-media-playout', this._onAddedMediaPlayout); peerConnection.off('removed-media-playout', this._onRemovedMediaPlayout); peerConnection.off('added-media-source', this._onMediaSourceAdded); peerConnection.off('removed-media-source', this._onMediaSourceRemoved); peerConnection.off('selectedcandidatepair', onSelectedCandidatePairChanged); peerConnection.off('icegatheringstatechange', onIceGatheringStateChange); peerConnection.off('iceconnectionstatechange', onIceConnectionStateChange); peerConnection.off('connectionstatechange', onConnectionStateChange); this.onPeerConnectionRemoved?.(peerConnection, this.context); }); peerConnection.on('added-certificate', this._onCertificateAdded); peerConnection.on('removed-certificate', this._onCertificateRemoved); peerConnection.on('added-inbound-track', this._onInboundTrackAdded); peerConnection.on('removed-inbound-track', this._onInboundTrackRemoved); peerConnection.on('added-outbound-track', this._onOutboundTrackAdded); peerConnection.on('removed-outbound-track', this._onOutboundTrackRemoved); peerConnection.on('added-inbound-rtp', this._onInboundRtpAdded); peerConnection.on('removed-inbound-rtp', this._onInboundRtpRemoved); peerConnection.on('added-outbound-rtp', this._onOutboundRtpAdded); peerConnection.on('removed-outbound-rtp', this._onOutboundRtpRemoved); peerConnection.on('added-data-channel', this._onDataChannelAdded); peerConnection.on('removed-data-channel', this._onDataChannelRemoved); peerConnection.on('added-ice-transport', this._onAddedIceTransport); peerConnection.on('removed-ice-transport', this._onRemovedIceTransport); peerConnection.on('added-ice-candidate', this._onIceCandidateAdded); peerConnection.on('removed-ice-candidate', this._onIceCandidateRemoved); peerConnection.on('added-ice-candidate-pair', this._onAddedIceCandidatePair); peerConnection.on('removed-ice-candidate-pair', this._onRemovedIceCandidatePair); peerConnection.on('added-codec', this._onAddedMediaCodec); peerConnection.on('removed-codec', this._onRemovedMediaCodec); peerConnection.on('added-media-playout', this._onAddedMediaPlayout); peerConnection.on('removed-media-playout', this._onRemovedMediaPlayout); peerConnection.on('added-media-source', this._onMediaSourceAdded); peerConnection.on('removed-media-source', this._onMediaSourceRemoved); peerConnection.on('selectedcandidatepair', onSelectedCandidatePairChanged); peerConnection.on('icegatheringstatechange', onIceGatheringStateChange); peerConnection.on('iceconnectionstatechange', onIceConnectionStateChange); peerConnection.on('connectionstatechange', onConnectionStateChange); this.onPeerConnectionAdded?.(peerConnection, this.context); } private _onPeerConnectionRemoved(peerConnection: ObservedPeerConnection) { this.onPeerConnectionRemoved?.(peerConnection, this.context); } private _onCertificateAdded(certificate: ObservedCertificate) { this.onCertificateAdded?.(certificate, this.context); } private _onCertificateRemoved(certificate: ObservedCertificate) { this.onCertificateRemoved?.(certificate, this.context); } private _onInboundTrackAdded(inboundTrack: ObservedInboundTrack) { this.onInboundTrackAdded?.(inboundTrack, this.context); } private _onInboundTrackRemoved(inboundTrack: ObservedInboundTrack) { this.onInboundTrackRemoved?.(inboundTrack, this.context); } private _onOutboundTrackAdded(outboundTrack: ObservedOutboundTrack) { this.onOutboundTrackAdded?.(outboundTrack, this.context); } private _onOutboundTrackRemoved(outboundTrack: ObservedOutboundTrack) { this.onOutboundTrackRemoved?.(outboundTrack, this.context); } private _onInboundRtpAdded(inboundRtp: ObservedInboundRtp) { this.onInboundRtpAdded?.(inboundRtp, this.context); } private _onInboundRtpRemoved(inboundRtp: ObservedInboundRtp) { this.onInboundRtpRemoved?.(inboundRtp, this.context); } private _onOutboundRtpAdded(outboundRtp: ObservedOutboundRtp) { this.onOutboundRtpAdded?.(outboundRtp, this.context); } private _onOutboundRtpRemoved(outboundRtp: ObservedOutboundRtp) { this.onOutboundRtpRemoved?.(outboundRtp, this.context); } private _onDataChannelAdded(dataChannel: ObservedDataChannel) { this.onDataChannelAdded?.(dataChannel, this.context); } private _onDataChannelRemoved(dataChannel: ObservedDataChannel) { this.onDataChannelRemoved?.(dataChannel, this.context); } private _onAddedIceTransport(iceTransport: ObservedIceTransport) { this.onAddedIceTransport?.(iceTransport, this.context); } private _onRemovedIceTransport(iceTransport: ObservedIceTransport) { this.onRemovedIceTransport?.(iceTransport, this.context); } private _onIceCandidateAdded(iceCandidate: ObservedIceCandidate) { this.onIceCandidateAdded?.(iceCandidate, this.context); } private _onIceCandidateRemoved(iceCandidate: ObservedIceCandidate) { this.onIceCandidateRemoved?.(iceCandidate, this.context); } private _onAddedIceCandidatePair(candidatePair: ObservedIceCandidatePair) { this.onAddedIceCandidatePair?.(candidatePair, this.context); } private _onRemovedIceCandidatePair(candidatePair: ObservedIceCandidatePair) { this.onRemovedIceCandidatePair?.(candidatePair, this.context); } private _onAddedMediaCodec(codec: ObservedCodec) { this.onAddedMediaCodec?.(codec, this.context); } private _onRemovedMediaCodec(codec: ObservedCodec) { this.onRemovedMediaCodec?.(codec, this.context); } private _onAddedMediaPlayout(mediaPlayout: ObservedMediaPlayout) { this.onAddedMediaPlayout?.(mediaPlayout, this.context); } private _onRemovedMediaPlayout(mediaPlayout: ObservedMediaPlayout) { this.onRemovedMediaPlayout?.(mediaPlayout, this.context); } private _onMediaSourceAdded(mediaSource: ObservedMediaSource) { this.onMediaSourceAdded?.(mediaSource, this.context); } private _onMediaSourceRemoved(mediaSource: ObservedMediaSource) { this.onMediaSourceRemoved?.(mediaSource, this.context); } private _onClientIssue(observedClent: ObservedClient, issue: ClientIssue) { this.onClientIssue?.(observedClent, issue, this.context); } private _onClientMetadata(observedClient: ObservedClient, metadata: ClientMetaData) { this.onClientMetadata?.(observedClient, metadata, this.context); } private _onClientExtensionStats(observedClient: ObservedClient, extensionStats: ExtensionStat) { this.onClientExtensionStats?.(observedClient, extensionStats, this.context); } private _onClientJoined(observedClient: ObservedClient) { this.onClientJoined?.(observedClient, this.context); } private _onClientLeft(observedClient: ObservedClient) { this.onClientLeft?.(observedClient, this.context); } private _onUserMediaError(observedClient: ObservedClient, error: string) { this.onClientUserMediaError?.(observedClient, error, this.context); } private _onUsingTurn(observedClient: ObservedClient, usingTurn: boolean) { this.onClientUsingTurn?.(observedClient, usingTurn, this.context); } private _onTrackReport(client: ObservedClient, trackReport: TrackReport) { this.onTrackReport?.(trackReport, this.context); } }