@observertc/observer-js 0.9.27-beta → 0.30.0-e12fcb4.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.
- package/lib/ObservedCall.d.ts +54 -0
- package/lib/ObservedCall.d.ts.map +1 -0
- package/lib/ObservedCall.js +166 -0
- package/lib/ObservedClient.d.ts +73 -0
- package/lib/ObservedClient.d.ts.map +1 -0
- package/lib/ObservedClient.js +487 -0
- package/lib/ObservedInboundTrack.d.ts +65 -0
- package/lib/ObservedInboundTrack.d.ts.map +1 -0
- package/lib/ObservedInboundTrack.js +192 -0
- package/lib/ObservedOutboundTrack.d.ts +55 -0
- package/lib/ObservedOutboundTrack.d.ts.map +1 -0
- package/lib/ObservedOutboundTrack.js +166 -0
- package/lib/ObservedPeerConnection.d.ts +57 -0
- package/lib/ObservedPeerConnection.d.ts.map +1 -0
- package/lib/ObservedPeerConnection.js +217 -0
- package/lib/Observer.d.ts +26 -1465
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +53 -605
- package/lib/{sinks/ObserverSink.d.ts → ReportsCollector.d.ts} +7 -23
- package/lib/ReportsCollector.d.ts.map +1 -0
- package/lib/{sinks/ObserverSink.js → ReportsCollector.js} +27 -85
- package/lib/common/ReportsCollector.d.ts +21 -24
- package/lib/common/ReportsCollector.d.ts.map +1 -1
- package/lib/common/ReportsCollector.js +24 -0
- package/lib/common/SingleExecutor.d.ts +3 -0
- package/lib/common/SingleExecutor.d.ts.map +1 -0
- package/lib/common/SingleExecutor.js +31 -0
- package/lib/common/TypedEventEmitter.d.ts +22 -0
- package/lib/common/TypedEventEmitter.d.ts.map +1 -0
- package/lib/common/TypedEventEmitter.js +11 -0
- package/lib/common/callEventReports.d.ts.map +1 -0
- package/lib/common/logger.d.ts +3 -9
- package/lib/common/logger.d.ts.map +1 -1
- package/lib/common/logger.js +58 -141
- package/lib/common/types.d.ts +2 -14
- package/lib/common/types.d.ts.map +1 -1
- package/lib/common/utils.d.ts +1 -0
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +6 -1
- package/lib/index.d.ts +8 -19
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -2
- package/package.json +1 -1
- package/src/ObservedCall.ts +201 -0
- package/src/ObservedClient.ts +681 -0
- package/src/ObservedInboundTrack.ts +238 -0
- package/src/ObservedOutboundTrack.ts +205 -0
- package/src/ObservedPeerConnection.ts +249 -0
- package/src/Observer.ts +86 -442
- package/src/{sinks/ObserverSink.ts → ReportsCollector.ts} +29 -94
- package/src/common/ReportsCollector.ts +48 -23
- package/src/common/SingleExecutor.ts +36 -0
- package/src/common/TypedEventEmitter.ts +32 -0
- package/src/common/logger.ts +58 -161
- package/src/common/types.ts +4 -24
- package/src/common/utils.ts +6 -0
- package/src/index.ts +12 -23
- package/lib/Evaluator.d.ts +0 -43
- package/lib/Evaluator.d.ts.map +0 -1
- package/lib/Evaluator.js +0 -171
- package/lib/common/Semaphore.d.ts +0 -31
- package/lib/common/Semaphore.d.ts.map +0 -1
- package/lib/common/Semaphore.js +0 -16
- package/lib/entries/CallEntry.d.ts +0 -619
- package/lib/entries/CallEntry.d.ts.map +0 -1
- package/lib/entries/CallEntry.js +0 -75
- package/lib/entries/ClientEntry.d.ts +0 -478
- package/lib/entries/ClientEntry.d.ts.map +0 -1
- package/lib/entries/ClientEntry.js +0 -114
- package/lib/entries/InboundTrackEntry.d.ts +0 -682
- package/lib/entries/InboundTrackEntry.d.ts.map +0 -1
- package/lib/entries/InboundTrackEntry.js +0 -76
- package/lib/entries/OutboundTrackEntry.d.ts +0 -682
- package/lib/entries/OutboundTrackEntry.d.ts.map +0 -1
- package/lib/entries/OutboundTrackEntry.js +0 -73
- package/lib/entries/PeerConnectionEntry.d.ts +0 -505
- package/lib/entries/PeerConnectionEntry.d.ts.map +0 -1
- package/lib/entries/PeerConnectionEntry.js +0 -144
- package/lib/entries/SfuEntry.d.ts +0 -150
- package/lib/entries/SfuEntry.d.ts.map +0 -1
- package/lib/entries/SfuEntry.js +0 -77
- package/lib/entries/SfuInboundRtpPadEntry.d.ts +0 -14
- package/lib/entries/SfuInboundRtpPadEntry.d.ts.map +0 -1
- package/lib/entries/SfuInboundRtpPadEntry.js +0 -49
- package/lib/entries/SfuOutboundRtpPadEntry.d.ts +0 -14
- package/lib/entries/SfuOutboundRtpPadEntry.d.ts.map +0 -1
- package/lib/entries/SfuOutboundRtpPadEntry.js +0 -47
- package/lib/entries/SfuSctpChannelEntry.d.ts +0 -12
- package/lib/entries/SfuSctpChannelEntry.d.ts.map +0 -1
- package/lib/entries/SfuSctpChannelEntry.js +0 -43
- package/lib/entries/SfuTransportEntry.d.ts +0 -82
- package/lib/entries/SfuTransportEntry.d.ts.map +0 -1
- package/lib/entries/SfuTransportEntry.js +0 -122
- package/lib/evaluators/SetClientsCoordinateEvaluator.d.ts +0 -9
- package/lib/evaluators/SetClientsCoordinateEvaluator.d.ts.map +0 -1
- package/lib/evaluators/SetClientsCoordinateEvaluator.js +0 -95
- package/lib/middlewares/CallOperationsContext.d.ts +0 -18
- package/lib/middlewares/CallOperationsContext.d.ts.map +0 -1
- package/lib/middlewares/CallOperationsContext.js +0 -27
- package/lib/middlewares/CallProcessor.d.ts +0 -6
- package/lib/middlewares/CallProcessor.d.ts.map +0 -1
- package/lib/middlewares/CallProcessor.js +0 -36
- package/lib/middlewares/CommitTransactionMiddleware.d.ts +0 -6
- package/lib/middlewares/CommitTransactionMiddleware.d.ts.map +0 -1
- package/lib/middlewares/CommitTransactionMiddleware.js +0 -179
- package/lib/middlewares/DeleteOutdatedCallEntries.d.ts +0 -6
- package/lib/middlewares/DeleteOutdatedCallEntries.d.ts.map +0 -1
- package/lib/middlewares/DeleteOutdatedCallEntries.js +0 -121
- package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts +0 -6
- package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts.map +0 -1
- package/lib/middlewares/DeleteOutdatedSfuEntries.js +0 -127
- package/lib/middlewares/Middleware.d.ts +0 -3
- package/lib/middlewares/Middleware.d.ts.map +0 -1
- package/lib/middlewares/Middleware.js +0 -21
- package/lib/middlewares/Processor.d.ts +0 -9
- package/lib/middlewares/Processor.d.ts.map +0 -1
- package/lib/middlewares/Processor.js +0 -54
- package/lib/middlewares/TransactionContext.d.ts +0 -35
- package/lib/middlewares/TransactionContext.d.ts.map +0 -1
- package/lib/middlewares/TransactionContext.js +0 -90
- package/lib/middlewares/TransactoinProcessor.d.ts +0 -6
- package/lib/middlewares/TransactoinProcessor.d.ts.map +0 -1
- package/lib/middlewares/TransactoinProcessor.js +0 -17
- package/lib/middlewares/VisitObservedCallsMiddleware.d.ts +0 -7
- package/lib/middlewares/VisitObservedCallsMiddleware.d.ts.map +0 -1
- package/lib/middlewares/VisitObservedCallsMiddleware.js +0 -96
- package/lib/middlewares/VisitObservedSfusMiddleware.d.ts +0 -6
- package/lib/middlewares/VisitObservedSfusMiddleware.d.ts.map +0 -1
- package/lib/middlewares/VisitObservedSfusMiddleware.js +0 -151
- package/lib/middlewares/visitors/visitClient.d.ts +0 -5
- package/lib/middlewares/visitors/visitClient.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitClient.js +0 -174
- package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts +0 -5
- package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitInboundAudioTrack.js +0 -93
- package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts +0 -5
- package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitInboundVideoTrack.js +0 -94
- package/lib/middlewares/visitors/visitOutboundAudioTrack.d.ts +0 -5
- package/lib/middlewares/visitors/visitOutboundAudioTrack.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitOutboundAudioTrack.js +0 -90
- package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts +0 -5
- package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitOutboundVideoTarck.js +0 -90
- package/lib/middlewares/visitors/visitPeerConnection.d.ts +0 -5
- package/lib/middlewares/visitors/visitPeerConnection.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitPeerConnection.js +0 -111
- package/lib/middlewares/visitors/visitSfu.d.ts +0 -5
- package/lib/middlewares/visitors/visitSfu.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitSfu.js +0 -78
- package/lib/middlewares/visitors/visitSfuInboundRtpPad.d.ts +0 -5
- package/lib/middlewares/visitors/visitSfuInboundRtpPad.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitSfuInboundRtpPad.js +0 -56
- package/lib/middlewares/visitors/visitSfuOutboundRtpPad.d.ts +0 -5
- package/lib/middlewares/visitors/visitSfuOutboundRtpPad.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitSfuOutboundRtpPad.js +0 -56
- package/lib/middlewares/visitors/visitSfuSctpChannel.d.ts +0 -5
- package/lib/middlewares/visitors/visitSfuSctpChannel.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitSfuSctpChannel.js +0 -55
- package/lib/middlewares/visitors/visitSfuTransport.d.ts +0 -5
- package/lib/middlewares/visitors/visitSfuTransport.d.ts.map +0 -1
- package/lib/middlewares/visitors/visitSfuTransport.js +0 -56
- package/lib/processes/closePeerConnectionProcess.d.ts +0 -10
- package/lib/processes/closePeerConnectionProcess.d.ts.map +0 -1
- package/lib/processes/closePeerConnectionProcess.js +0 -51
- package/lib/processes/detachClientProcess.d.ts +0 -14
- package/lib/processes/detachClientProcess.d.ts.map +0 -1
- package/lib/processes/detachClientProcess.js +0 -106
- package/lib/processes/findRemoteMatches.d.ts +0 -9
- package/lib/processes/findRemoteMatches.d.ts.map +0 -1
- package/lib/processes/findRemoteMatches.js +0 -96
- package/lib/processes/inboundTrackRemoved.d.ts +0 -9
- package/lib/processes/inboundTrackRemoved.d.ts.map +0 -1
- package/lib/processes/inboundTrackRemoved.js +0 -22
- package/lib/processes/joinClientProcess.d.ts +0 -11
- package/lib/processes/joinClientProcess.d.ts.map +0 -1
- package/lib/processes/joinClientProcess.js +0 -120
- package/lib/processes/outboundTrackRemoved.d.ts +0 -9
- package/lib/processes/outboundTrackRemoved.d.ts.map +0 -1
- package/lib/processes/outboundTrackRemoved.js +0 -22
- package/lib/samples/ObservedCall.d.ts +0 -17
- package/lib/samples/ObservedCall.d.ts.map +0 -1
- package/lib/samples/ObservedCall.js +0 -29
- package/lib/samples/ObservedCalls.d.ts +0 -19
- package/lib/samples/ObservedCalls.d.ts.map +0 -1
- package/lib/samples/ObservedCalls.js +0 -113
- package/lib/samples/ObservedClient.d.ts +0 -28
- package/lib/samples/ObservedClient.d.ts.map +0 -1
- package/lib/samples/ObservedClient.js +0 -110
- package/lib/samples/ObservedInboundAudioTrack.d.ts +0 -17
- package/lib/samples/ObservedInboundAudioTrack.d.ts.map +0 -1
- package/lib/samples/ObservedInboundAudioTrack.js +0 -17
- package/lib/samples/ObservedInboundVideoTrack.d.ts +0 -17
- package/lib/samples/ObservedInboundVideoTrack.d.ts.map +0 -1
- package/lib/samples/ObservedInboundVideoTrack.js +0 -17
- package/lib/samples/ObservedOutboundAudioTrack.d.ts +0 -16
- package/lib/samples/ObservedOutboundAudioTrack.d.ts.map +0 -1
- package/lib/samples/ObservedOutboundAudioTrack.js +0 -17
- package/lib/samples/ObservedOutboundVideoTrack.d.ts +0 -16
- package/lib/samples/ObservedOutboundVideoTrack.d.ts.map +0 -1
- package/lib/samples/ObservedOutboundVideoTrack.js +0 -17
- package/lib/samples/ObservedPeerConnection.d.ts +0 -47
- package/lib/samples/ObservedPeerConnection.d.ts.map +0 -1
- package/lib/samples/ObservedPeerConnection.js +0 -130
- package/lib/samples/ObservedSfu.d.ts +0 -27
- package/lib/samples/ObservedSfu.d.ts.map +0 -1
- package/lib/samples/ObservedSfu.js +0 -65
- package/lib/samples/ObservedSfuInboundRtpPad.d.ts +0 -15
- package/lib/samples/ObservedSfuInboundRtpPad.d.ts.map +0 -1
- package/lib/samples/ObservedSfuInboundRtpPad.js +0 -17
- package/lib/samples/ObservedSfuOutboundRtpPad.d.ts +0 -15
- package/lib/samples/ObservedSfuOutboundRtpPad.d.ts.map +0 -1
- package/lib/samples/ObservedSfuOutboundRtpPad.js +0 -17
- package/lib/samples/ObservedSfuSctpChannel.d.ts +0 -15
- package/lib/samples/ObservedSfuSctpChannel.d.ts.map +0 -1
- package/lib/samples/ObservedSfuSctpChannel.js +0 -17
- package/lib/samples/ObservedSfuTransport.d.ts +0 -30
- package/lib/samples/ObservedSfuTransport.d.ts.map +0 -1
- package/lib/samples/ObservedSfuTransport.js +0 -86
- package/lib/samples/ObservedSfus.d.ts +0 -16
- package/lib/samples/ObservedSfus.d.ts.map +0 -1
- package/lib/samples/ObservedSfus.js +0 -72
- package/lib/sinks/ObserverSink.d.ts.map +0 -1
- package/lib/sinks/callEventReports.d.ts.map +0 -1
- package/lib/sources/ObservedCallSource.d.ts +0 -18
- package/lib/sources/ObservedCallSource.d.ts.map +0 -1
- package/lib/sources/ObservedCallSource.js +0 -2
- package/lib/sources/ObservedClientSource.d.ts +0 -19
- package/lib/sources/ObservedClientSource.d.ts.map +0 -1
- package/lib/sources/ObservedClientSource.js +0 -2
- package/lib/sources/ObservedSfuSource.d.ts +0 -15
- package/lib/sources/ObservedSfuSource.d.ts.map +0 -1
- package/lib/sources/ObservedSfuSource.js +0 -2
- package/lib/sources/Sources.d.ts +0 -49
- package/lib/sources/Sources.d.ts.map +0 -1
- package/lib/sources/Sources.js +0 -213
- package/src/Evaluator.ts +0 -229
- package/src/common/Semaphore.ts +0 -45
- package/src/entries/CallEntry.ts +0 -62
- package/src/entries/ClientEntry.ts +0 -106
- package/src/entries/InboundTrackEntry.ts +0 -74
- package/src/entries/OutboundTrackEntry.ts +0 -72
- package/src/entries/PeerConnectionEntry.ts +0 -133
- package/src/entries/SfuEntry.ts +0 -62
- package/src/entries/SfuInboundRtpPadEntry.ts +0 -46
- package/src/entries/SfuOutboundRtpPadEntry.ts +0 -44
- package/src/entries/SfuSctpChannelEntry.ts +0 -39
- package/src/entries/SfuTransportEntry.ts +0 -109
- package/src/evaluators/SetClientsCoordinateEvaluator.ts +0 -78
- package/src/middlewares/CallOperationsContext.ts +0 -56
- package/src/middlewares/CallProcessor.ts +0 -38
- package/src/middlewares/CommitTransactionMiddleware.ts +0 -328
- package/src/middlewares/DeleteOutdatedCallEntries.ts +0 -159
- package/src/middlewares/DeleteOutdatedSfuEntries.ts +0 -168
- package/src/middlewares/Middleware.ts +0 -10
- package/src/middlewares/Processor.ts +0 -59
- package/src/middlewares/TransactionContext.ts +0 -176
- package/src/middlewares/TransactoinProcessor.ts +0 -28
- package/src/middlewares/VisitObservedCallsMiddleware.ts +0 -172
- package/src/middlewares/VisitObservedSfusMiddleware.ts +0 -203
- package/src/middlewares/visitors/visitClient.ts +0 -239
- package/src/middlewares/visitors/visitInboundAudioTrack.ts +0 -113
- package/src/middlewares/visitors/visitInboundVideoTrack.ts +0 -117
- package/src/middlewares/visitors/visitOutboundAudioTrack.ts +0 -100
- package/src/middlewares/visitors/visitOutboundVideoTarck.ts +0 -102
- package/src/middlewares/visitors/visitPeerConnection.ts +0 -151
- package/src/middlewares/visitors/visitSfu.ts +0 -70
- package/src/middlewares/visitors/visitSfuInboundRtpPad.ts +0 -52
- package/src/middlewares/visitors/visitSfuOutboundRtpPad.ts +0 -53
- package/src/middlewares/visitors/visitSfuSctpChannel.ts +0 -50
- package/src/middlewares/visitors/visitSfuTransport.ts +0 -50
- package/src/processes/closePeerConnectionProcess.ts +0 -54
- package/src/processes/detachClientProcess.ts +0 -136
- package/src/processes/findRemoteMatches.ts +0 -104
- package/src/processes/inboundTrackRemoved.ts +0 -22
- package/src/processes/joinClientProcess.ts +0 -138
- package/src/processes/outboundTrackRemoved.ts +0 -22
- package/src/samples/ObservedCall.ts +0 -49
- package/src/samples/ObservedCalls.ts +0 -143
- package/src/samples/ObservedClient.ts +0 -172
- package/src/samples/ObservedInboundAudioTrack.ts +0 -35
- package/src/samples/ObservedInboundVideoTrack.ts +0 -36
- package/src/samples/ObservedOutboundAudioTrack.ts +0 -35
- package/src/samples/ObservedOutboundVideoTrack.ts +0 -35
- package/src/samples/ObservedPeerConnection.ts +0 -227
- package/src/samples/ObservedSfu.ts +0 -115
- package/src/samples/ObservedSfuInboundRtpPad.ts +0 -35
- package/src/samples/ObservedSfuOutboundRtpPad.ts +0 -35
- package/src/samples/ObservedSfuSctpChannel.ts +0 -35
- package/src/samples/ObservedSfuTransport.ts +0 -142
- package/src/samples/ObservedSfus.ts +0 -95
- package/src/sources/ObservedCallSource.ts +0 -26
- package/src/sources/ObservedClientSource.ts +0 -28
- package/src/sources/ObservedSfuSource.ts +0 -19
- package/src/sources/Sources.ts +0 -301
- /package/lib/{sinks → common}/callEventReports.d.ts +0 -0
- /package/lib/{sinks → common}/callEventReports.js +0 -0
- /package/src/{sinks → common}/callEventReports.ts +0 -0
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
import { ClientSample, IceLocalCandidate } from '@observertc/sample-schemas-js';
|
|
2
|
+
import { ObservedCall } from './ObservedCall';
|
|
3
|
+
import * as Models from './models/Models';
|
|
4
|
+
import { StorageProvider } from './storages/StorageProvider';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { createSingleExecutor } from './common/SingleExecutor';
|
|
7
|
+
import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
8
|
+
import { createLogger } from './common/logger';
|
|
9
|
+
import { CallMetaType, createCallMetaReport } from './common/callMetaReports';
|
|
10
|
+
// eslint-disable-next-line camelcase
|
|
11
|
+
import { Samples_ClientSample_Browser, Samples_ClientSample_Engine, Samples_ClientSample_OperationSystem, Samples_ClientSample_Platform } from './models/samples_pb';
|
|
12
|
+
import { IceCandidatePairReport } from '@observertc/report-schemas-js';
|
|
13
|
+
import { isValidUuid } from './common/utils';
|
|
14
|
+
|
|
15
|
+
const logger = createLogger('ObservedClient');
|
|
16
|
+
|
|
17
|
+
export type ObservedClientConfig<AppData extends Record<string, unknown> = Record<string, unknown>> = {
|
|
18
|
+
callId: string;
|
|
19
|
+
clientId: string;
|
|
20
|
+
mediaUnitId: string;
|
|
21
|
+
appData: AppData;
|
|
22
|
+
overflowingProcessingThreshold?: number;
|
|
23
|
+
joined?: number,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type ObservedClientEvents = {
|
|
27
|
+
update: [],
|
|
28
|
+
close: [],
|
|
29
|
+
'processing-sample-overflow': [],
|
|
30
|
+
'candidate-pair-change': [],
|
|
31
|
+
newpeerconnection: [ObservedPeerConnection],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export declare interface ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> {
|
|
35
|
+
on<U extends keyof ObservedClientEvents>(event: U, listener: (...args: ObservedClientEvents[U]) => void): this;
|
|
36
|
+
off<U extends keyof ObservedClientEvents>(event: U, listener: (...args: ObservedClientEvents[U]) => void): this;
|
|
37
|
+
once<U extends keyof ObservedClientEvents>(event: U, listener: (...args: ObservedClientEvents[U]) => void): this;
|
|
38
|
+
emit<U extends keyof ObservedClientEvents>(event: U, ...args: ObservedClientEvents[U]): boolean;
|
|
39
|
+
readonly appData: AppData;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> extends EventEmitter {
|
|
43
|
+
public static async create<T extends Record<string, unknown> = Record<string, unknown>>(
|
|
44
|
+
config: ObservedClientConfig<T>,
|
|
45
|
+
call: ObservedCall,
|
|
46
|
+
storageProvider: StorageProvider,
|
|
47
|
+
) {
|
|
48
|
+
const { callId, clientId, mediaUnitId } = config;
|
|
49
|
+
|
|
50
|
+
const model = new Models.Client({
|
|
51
|
+
roomId: call.roomId,
|
|
52
|
+
serviceId: call.serviceId,
|
|
53
|
+
callId,
|
|
54
|
+
clientId,
|
|
55
|
+
mediaUnitId,
|
|
56
|
+
peerConnectionIds: [],
|
|
57
|
+
joined: BigInt(config.joined ?? Date.now()),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const result = new ObservedClient<T>(model, call, storageProvider, config.appData);
|
|
61
|
+
|
|
62
|
+
const alreadyInserted = await storageProvider.clientStorage.insert(clientId, model);
|
|
63
|
+
|
|
64
|
+
if (alreadyInserted) throw new Error(`Client with id ${clientId} already exists`);
|
|
65
|
+
|
|
66
|
+
result._overflowingProcessingThreshold = config.overflowingProcessingThreshold ?? 0;
|
|
67
|
+
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private readonly _peerConnections = new Map<string, ObservedPeerConnection>();
|
|
72
|
+
private readonly _execute = createSingleExecutor();
|
|
73
|
+
|
|
74
|
+
private _overflowingProcessingThreshold = 0;
|
|
75
|
+
private _closed = false;
|
|
76
|
+
private _updated = Date.now();
|
|
77
|
+
private _acceptedSample = 0;
|
|
78
|
+
private _processingSample = 0;
|
|
79
|
+
private _iceLocalCandidate?: IceLocalCandidate;
|
|
80
|
+
private _iceRemoteCandidate?: IceLocalCandidate;
|
|
81
|
+
|
|
82
|
+
public readonly mediaDevices: string[] = [];
|
|
83
|
+
public readonly codecs: string[] = [];
|
|
84
|
+
public readonly userMediaErrors: string[] = [];
|
|
85
|
+
|
|
86
|
+
private constructor(
|
|
87
|
+
private readonly _model: Models.Client,
|
|
88
|
+
public readonly call: ObservedCall,
|
|
89
|
+
private readonly _storageProvider: StorageProvider,
|
|
90
|
+
public readonly appData: AppData
|
|
91
|
+
) {
|
|
92
|
+
super();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public get joined(): number {
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
97
|
+
return Number(this._model.joined!);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public get clientId(): string {
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
102
|
+
return this._model.clientId!;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public get roomId() {
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
107
|
+
return this._model.roomId!;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public get serviceId() {
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
112
|
+
return this._model.serviceId!;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public get callId() {
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
117
|
+
return this._model.callId!;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public get mediaUnitId() {
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
122
|
+
return this._model.mediaUnitId!;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public get reports() {
|
|
126
|
+
return this.call.reports;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public get userId() {
|
|
130
|
+
return this._model.userId;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public get iceLocalCandidate() {
|
|
134
|
+
return this._iceLocalCandidate;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public get iceRemoteCandidate() {
|
|
138
|
+
return this._iceRemoteCandidate;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public get marker() {
|
|
142
|
+
return this._model.marker;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public get browser() {
|
|
146
|
+
return this._model.browser;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public get engine() {
|
|
150
|
+
return this._model.engine;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public get operationSystem() {
|
|
154
|
+
return this._model.operationSystem;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public get platform() {
|
|
158
|
+
return this._model.platform;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public get acceptedSample() {
|
|
162
|
+
return this._acceptedSample;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public get updated() {
|
|
166
|
+
return this._updated;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public get closed() {
|
|
170
|
+
return this._closed;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public get peerConnections(): ReadonlyMap<string, ObservedPeerConnection> {
|
|
174
|
+
return this._peerConnections;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public close() {
|
|
178
|
+
if (this._closed) return;
|
|
179
|
+
this._closed = true;
|
|
180
|
+
|
|
181
|
+
Array.from(this._peerConnections.values()).forEach((peerConnection) => peerConnection.close());
|
|
182
|
+
|
|
183
|
+
this._execute(() => this._storageProvider.clientStorage.remove(this.clientId))
|
|
184
|
+
.catch(() => void 0)
|
|
185
|
+
.finally(() => this.emit('close'));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public async accept(sample: ClientSample): Promise<void> {
|
|
189
|
+
if (this._closed) throw new Error(`Client ${this.clientId} is closed`);
|
|
190
|
+
if (sample.clientId && sample.clientId !== 'NULL' && sample.clientId !== this.clientId) {
|
|
191
|
+
throw new Error(`Sample client id (${sample.clientId}) does not match the client id of the observed client (${this.clientId})`);
|
|
192
|
+
}
|
|
193
|
+
++this._acceptedSample;
|
|
194
|
+
++this._processingSample;
|
|
195
|
+
|
|
196
|
+
if (0 < this._overflowingProcessingThreshold && this._overflowingProcessingThreshold < this._processingSample) {
|
|
197
|
+
this.emit('processing-sample-overflow');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return this._execute(async () => {
|
|
201
|
+
let executeSave = false;
|
|
202
|
+
|
|
203
|
+
if (this.userId !== sample.userId) {
|
|
204
|
+
this._model.userId = sample.userId;
|
|
205
|
+
executeSave = true;
|
|
206
|
+
}
|
|
207
|
+
if (this._model.marker !== sample.marker) {
|
|
208
|
+
this._model.marker = sample.marker;
|
|
209
|
+
executeSave = true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (sample.os && (
|
|
213
|
+
this._model.operationSystem?.name !== sample.os.name ||
|
|
214
|
+
this._model.operationSystem?.version !== sample.os.version ||
|
|
215
|
+
this._model.operationSystem?.versionName !== sample.os.versionName
|
|
216
|
+
)) {
|
|
217
|
+
this._model.operationSystem = new Samples_ClientSample_OperationSystem({
|
|
218
|
+
...sample.os,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const callMetaReport = createCallMetaReport(
|
|
222
|
+
this.serviceId,
|
|
223
|
+
this.mediaUnitId,
|
|
224
|
+
this.roomId,
|
|
225
|
+
this.callId,
|
|
226
|
+
this.clientId,
|
|
227
|
+
{
|
|
228
|
+
type: CallMetaType.OPERATION_SYSTEM,
|
|
229
|
+
payload: sample.os,
|
|
230
|
+
}, this.userId);
|
|
231
|
+
|
|
232
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
233
|
+
executeSave = true;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (sample.engine && (
|
|
237
|
+
this._model.engine?.name !== sample.engine.name ||
|
|
238
|
+
this._model.engine?.version !== sample.engine.version
|
|
239
|
+
)) {
|
|
240
|
+
this._model.engine = new Samples_ClientSample_Engine({
|
|
241
|
+
...sample.engine,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const callMetaReport = createCallMetaReport(
|
|
245
|
+
this.serviceId,
|
|
246
|
+
this.mediaUnitId,
|
|
247
|
+
this.roomId,
|
|
248
|
+
this.callId,
|
|
249
|
+
this.clientId,
|
|
250
|
+
{
|
|
251
|
+
type: CallMetaType.ENGINE,
|
|
252
|
+
payload: sample.engine,
|
|
253
|
+
}, this.userId);
|
|
254
|
+
|
|
255
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
256
|
+
executeSave = true;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (sample.platform && (
|
|
260
|
+
this._model.platform?.model !== sample.platform.model ||
|
|
261
|
+
this._model.platform?.type !== sample.platform.type ||
|
|
262
|
+
this._model.platform?.vendor !== sample.platform.vendor
|
|
263
|
+
)) {
|
|
264
|
+
this._model.platform = new Samples_ClientSample_Platform({
|
|
265
|
+
...sample.platform,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const callMetaReport = createCallMetaReport(
|
|
269
|
+
this.serviceId,
|
|
270
|
+
this.mediaUnitId,
|
|
271
|
+
this.roomId,
|
|
272
|
+
this.callId,
|
|
273
|
+
this.clientId,
|
|
274
|
+
{
|
|
275
|
+
type: CallMetaType.PLATFORM,
|
|
276
|
+
payload: sample.platform,
|
|
277
|
+
}, this.userId);
|
|
278
|
+
|
|
279
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
280
|
+
executeSave = true;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (sample.browser && (
|
|
284
|
+
this._model.browser?.name !== sample.browser.name ||
|
|
285
|
+
this._model.browser?.version !== sample.browser.version
|
|
286
|
+
)) {
|
|
287
|
+
this._model.browser = new Samples_ClientSample_Browser({
|
|
288
|
+
...sample.browser,
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const callMetaReport = createCallMetaReport(
|
|
292
|
+
this.serviceId,
|
|
293
|
+
this.mediaUnitId,
|
|
294
|
+
this.roomId,
|
|
295
|
+
this.callId,
|
|
296
|
+
this.clientId,
|
|
297
|
+
{
|
|
298
|
+
type: CallMetaType.BROWSER,
|
|
299
|
+
payload: sample.browser,
|
|
300
|
+
}, this.userId);
|
|
301
|
+
|
|
302
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
303
|
+
executeSave = true;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
for (const mediaConstraint of sample.mediaConstraints ?? []) {
|
|
307
|
+
const callMetaReport = createCallMetaReport(
|
|
308
|
+
this.serviceId,
|
|
309
|
+
this.mediaUnitId,
|
|
310
|
+
this.roomId,
|
|
311
|
+
this.callId,
|
|
312
|
+
this.clientId,
|
|
313
|
+
{
|
|
314
|
+
type: CallMetaType.MEDIA_CONSTRAINT,
|
|
315
|
+
payload: mediaConstraint,
|
|
316
|
+
}, this.userId);
|
|
317
|
+
|
|
318
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
for (const localSDP of sample.localSDPs ?? []) {
|
|
322
|
+
const callMetaReport = createCallMetaReport(
|
|
323
|
+
this.serviceId,
|
|
324
|
+
this.mediaUnitId,
|
|
325
|
+
this.roomId,
|
|
326
|
+
this.callId,
|
|
327
|
+
this.clientId,
|
|
328
|
+
{
|
|
329
|
+
type: CallMetaType.LOCAL_SDP,
|
|
330
|
+
payload: localSDP,
|
|
331
|
+
}, this.userId);
|
|
332
|
+
|
|
333
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
for (const extensionStats of sample.extensionStats ?? []) {
|
|
337
|
+
this.reports.addClientExtensionReport({
|
|
338
|
+
serviceId: this.serviceId,
|
|
339
|
+
mediaUnitId: this.mediaUnitId,
|
|
340
|
+
roomId: this.roomId,
|
|
341
|
+
callId: this.callId,
|
|
342
|
+
clientId: this.clientId,
|
|
343
|
+
userId: this.userId,
|
|
344
|
+
timestamp: Date.now(),
|
|
345
|
+
payload: extensionStats.payload,
|
|
346
|
+
extensionType: extensionStats.type,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
for (const { timestamp = Date.now(), ...callEvent } of sample.customCallEvents ?? []) {
|
|
351
|
+
this.reports.addCallEventReport({
|
|
352
|
+
serviceId: this.serviceId,
|
|
353
|
+
mediaUnitId: this.mediaUnitId,
|
|
354
|
+
roomId: this.roomId,
|
|
355
|
+
callId: this.callId,
|
|
356
|
+
clientId: this.clientId,
|
|
357
|
+
userId: this.userId,
|
|
358
|
+
timestamp,
|
|
359
|
+
...callEvent,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
for (const userMediaError of sample.userMediaErrors ?? []) {
|
|
364
|
+
const callMetaReport = createCallMetaReport(
|
|
365
|
+
this.serviceId,
|
|
366
|
+
this.mediaUnitId,
|
|
367
|
+
this.roomId,
|
|
368
|
+
this.callId,
|
|
369
|
+
this.clientId, {
|
|
370
|
+
type: CallMetaType.USER_MEDIA_ERROR,
|
|
371
|
+
payload: userMediaError,
|
|
372
|
+
}, this.userId);
|
|
373
|
+
|
|
374
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
375
|
+
this.userMediaErrors.push(userMediaError);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
for (const certificate of sample.certificates ?? []) {
|
|
379
|
+
const callMetaReport = createCallMetaReport(
|
|
380
|
+
this.serviceId,
|
|
381
|
+
this.mediaUnitId,
|
|
382
|
+
this.roomId,
|
|
383
|
+
this.callId,
|
|
384
|
+
this.clientId, {
|
|
385
|
+
type: CallMetaType.CERTIFICATE,
|
|
386
|
+
payload: certificate,
|
|
387
|
+
}, this.userId);
|
|
388
|
+
|
|
389
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
for (const codec of sample.codecs ?? []) {
|
|
393
|
+
const callMetaReport = createCallMetaReport(
|
|
394
|
+
this.serviceId,
|
|
395
|
+
this.mediaUnitId,
|
|
396
|
+
this.roomId,
|
|
397
|
+
this.callId,
|
|
398
|
+
this.clientId, {
|
|
399
|
+
type: CallMetaType.CODEC,
|
|
400
|
+
payload: codec,
|
|
401
|
+
}, this.userId);
|
|
402
|
+
|
|
403
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
404
|
+
codec.mimeType && this.codecs.push(codec.mimeType);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
for (const iceServer of sample.iceServers ?? []) {
|
|
408
|
+
const callMetaReport = createCallMetaReport(
|
|
409
|
+
this.serviceId,
|
|
410
|
+
this.mediaUnitId,
|
|
411
|
+
this.roomId,
|
|
412
|
+
this.callId,
|
|
413
|
+
this.clientId, {
|
|
414
|
+
type: CallMetaType.ICE_SERVER,
|
|
415
|
+
payload: iceServer,
|
|
416
|
+
}, this.userId);
|
|
417
|
+
|
|
418
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
for (const mediaDevice of sample.mediaDevices ?? []) {
|
|
422
|
+
const callMetaReport = createCallMetaReport(
|
|
423
|
+
this.serviceId,
|
|
424
|
+
this.mediaUnitId,
|
|
425
|
+
this.roomId,
|
|
426
|
+
this.callId,
|
|
427
|
+
this.clientId, {
|
|
428
|
+
type: CallMetaType.MEDIA_DEVICE,
|
|
429
|
+
payload: mediaDevice,
|
|
430
|
+
}, this.userId);
|
|
431
|
+
|
|
432
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
433
|
+
mediaDevice.label && this.mediaDevices.push(mediaDevice.label);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
for (const mediaSource of sample.mediaSources ?? []) {
|
|
437
|
+
const callMetaReport = createCallMetaReport(
|
|
438
|
+
this.serviceId,
|
|
439
|
+
this.mediaUnitId,
|
|
440
|
+
this.roomId,
|
|
441
|
+
this.callId,
|
|
442
|
+
this.clientId, {
|
|
443
|
+
type: CallMetaType.MEDIA_SOURCE,
|
|
444
|
+
payload: mediaSource,
|
|
445
|
+
}, this.userId);
|
|
446
|
+
|
|
447
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
448
|
+
}
|
|
449
|
+
let selectedLocalCandidateId: string | undefined;
|
|
450
|
+
let selectedRemoteCandidateId: string | undefined;
|
|
451
|
+
|
|
452
|
+
for (const candidatePair of sample.iceCandidatePairs ?? []) {
|
|
453
|
+
if (candidatePair.nominated) {
|
|
454
|
+
if (!selectedLocalCandidateId) selectedLocalCandidateId = candidatePair.localCandidateId;
|
|
455
|
+
if (!selectedRemoteCandidateId) selectedRemoteCandidateId = candidatePair.remoteCandidateId;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const report: IceCandidatePairReport = {
|
|
459
|
+
serviceId: this.serviceId,
|
|
460
|
+
mediaUnitId: this.mediaUnitId,
|
|
461
|
+
roomId: this.roomId,
|
|
462
|
+
callId: this.callId,
|
|
463
|
+
clientId: this.clientId,
|
|
464
|
+
userId: this.userId,
|
|
465
|
+
timestamp: sample.timestamp,
|
|
466
|
+
...candidatePair,
|
|
467
|
+
sampleSeq: -1, // deprecated
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
this.reports.addIceCandidatePairReport(report);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
let changeIceCandidatePair = false;
|
|
474
|
+
|
|
475
|
+
for (const iceLocalCandidate of sample.iceLocalCandidates ?? []) {
|
|
476
|
+
if (
|
|
477
|
+
iceLocalCandidate.id && selectedLocalCandidateId &&
|
|
478
|
+
iceLocalCandidate.id === selectedLocalCandidateId &&
|
|
479
|
+
this._iceLocalCandidate?.id !== iceLocalCandidate.id
|
|
480
|
+
) {
|
|
481
|
+
this._iceLocalCandidate = iceLocalCandidate;
|
|
482
|
+
changeIceCandidatePair = true;
|
|
483
|
+
}
|
|
484
|
+
const callMetaReport = createCallMetaReport(
|
|
485
|
+
this.serviceId,
|
|
486
|
+
this.mediaUnitId,
|
|
487
|
+
this.roomId,
|
|
488
|
+
this.callId,
|
|
489
|
+
this.clientId, {
|
|
490
|
+
type: CallMetaType.ICE_LOCAL_CANDIDATE,
|
|
491
|
+
payload: iceLocalCandidate,
|
|
492
|
+
}, this.userId);
|
|
493
|
+
|
|
494
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
for (const iceRemoteCandidate of sample.iceRemoteCandidates ?? []) {
|
|
498
|
+
if (
|
|
499
|
+
iceRemoteCandidate.id && selectedRemoteCandidateId &&
|
|
500
|
+
iceRemoteCandidate.id === selectedRemoteCandidateId &&
|
|
501
|
+
this._iceRemoteCandidate?.id !== iceRemoteCandidate.id
|
|
502
|
+
) {
|
|
503
|
+
this._iceRemoteCandidate = iceRemoteCandidate;
|
|
504
|
+
changeIceCandidatePair = true;
|
|
505
|
+
}
|
|
506
|
+
const callMetaReport = createCallMetaReport(
|
|
507
|
+
this.serviceId,
|
|
508
|
+
this.mediaUnitId,
|
|
509
|
+
this.roomId,
|
|
510
|
+
this.callId,
|
|
511
|
+
this.clientId, {
|
|
512
|
+
type: CallMetaType.ICE_REMOTE_CANDIDATE,
|
|
513
|
+
payload: iceRemoteCandidate,
|
|
514
|
+
}, this.userId);
|
|
515
|
+
|
|
516
|
+
this.reports.addCallMetaReport(callMetaReport);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
for (const transport of sample.pcTransports ?? []) {
|
|
520
|
+
try {
|
|
521
|
+
const peerConnection = this._peerConnections.get(transport.transportId) ?? await this._createPeerConnection(transport.peerConnectionId);
|
|
522
|
+
|
|
523
|
+
peerConnection.update(transport, sample.timestamp);
|
|
524
|
+
} catch (err) {
|
|
525
|
+
logger.error(`Error creating peer connection: ${(err as Error)?.message}`);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
for (const track of sample.inboundAudioTracks ?? []) {
|
|
531
|
+
if (!track.peerConnectionId || !track.trackId) {
|
|
532
|
+
logger.warn(`InboundAudioTrack without peerConnectionId or trackId: ${JSON.stringify(track)}`);
|
|
533
|
+
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
try {
|
|
538
|
+
const peerConnection = this._peerConnections.get(track.peerConnectionId) ?? await this._createPeerConnection(track.peerConnectionId);
|
|
539
|
+
|
|
540
|
+
if (!peerConnection) continue;
|
|
541
|
+
|
|
542
|
+
const inboundAudioTrack = peerConnection.inboundAudioTracks.get(track.trackId) ?? await peerConnection.createInboundAudioTrack({
|
|
543
|
+
trackId: track.trackId,
|
|
544
|
+
sfuStreamId: track.sfuStreamId,
|
|
545
|
+
sfuSinkId: track.sfuSinkId,
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
await inboundAudioTrack.update(track, sample.timestamp);
|
|
549
|
+
|
|
550
|
+
const remoteOutboundTrack = this.call.sfuStreamIdToOutboundAudioTrack.get(track.sfuStreamId ?? '');
|
|
551
|
+
|
|
552
|
+
if (remoteOutboundTrack && inboundAudioTrack.sfuStreamId && !remoteOutboundTrack.remoteInboundTracks.has(inboundAudioTrack.sfuStreamId)) {
|
|
553
|
+
remoteOutboundTrack.connectInboundTrack(inboundAudioTrack);
|
|
554
|
+
}
|
|
555
|
+
} catch (err) {
|
|
556
|
+
logger.error(`Error creating inbound audio track: ${(err as Error)?.message}`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
for (const track of sample.inboundVideoTracks ?? []) {
|
|
561
|
+
if (!track.peerConnectionId || !track.trackId) {
|
|
562
|
+
logger.warn(`InboundVideoTrack without peerConnectionId or trackId: ${JSON.stringify(track)}`);
|
|
563
|
+
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
if (isValidUuid(track.trackId) === false) {
|
|
567
|
+
// mediasoup-probator trackId is not a valid UUID, no need to warn about it
|
|
568
|
+
if (track.trackId === 'probator') continue;
|
|
569
|
+
logger.warn(`InboundVideoTrack with invalid trackId: ${track.trackId}`);
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
try {
|
|
574
|
+
const peerConnection = this._peerConnections.get(track.peerConnectionId) ?? await this._createPeerConnection(track.peerConnectionId);
|
|
575
|
+
|
|
576
|
+
if (!peerConnection) continue;
|
|
577
|
+
|
|
578
|
+
const inboundVideoTrack = peerConnection.inboundVideoTracks.get(track.trackId) ?? await peerConnection.createInboundVideoTrack({
|
|
579
|
+
trackId: track.trackId,
|
|
580
|
+
sfuStreamId: track.sfuStreamId,
|
|
581
|
+
sfuSinkId: track.sfuSinkId,
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
await inboundVideoTrack.update(track, sample.timestamp);
|
|
585
|
+
|
|
586
|
+
const remoteOutboundTrack = this.call.sfuStreamIdToOutboundVideoTrack.get(inboundVideoTrack.sfuStreamId ?? '');
|
|
587
|
+
|
|
588
|
+
if (remoteOutboundTrack && inboundVideoTrack.sfuStreamId && !remoteOutboundTrack.remoteInboundTracks.has(inboundVideoTrack.sfuStreamId)) {
|
|
589
|
+
remoteOutboundTrack.connectInboundTrack(inboundVideoTrack);
|
|
590
|
+
}
|
|
591
|
+
} catch (err) {
|
|
592
|
+
logger.error(`Error creating inbound video track: ${(err as Error)?.message}`);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
for (const track of sample.outboundAudioTracks ?? []) {
|
|
597
|
+
if (!track.peerConnectionId || !track.trackId) {
|
|
598
|
+
logger.warn(`OutboundAudioTrack without peerConnectionId or trackId: ${JSON.stringify(track)}`);
|
|
599
|
+
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
try {
|
|
604
|
+
const peerConnection = this._peerConnections.get(track.peerConnectionId) ?? await this._createPeerConnection(track.peerConnectionId);
|
|
605
|
+
|
|
606
|
+
if (!peerConnection) continue;
|
|
607
|
+
|
|
608
|
+
const outboundAudioTrack = peerConnection.outboundAudioTracks.get(track.trackId) ?? await peerConnection.createOutboundAudioTrack({
|
|
609
|
+
trackId: track.trackId,
|
|
610
|
+
sfuStreamId: track.sfuStreamId,
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
await outboundAudioTrack.update(track, sample.timestamp);
|
|
614
|
+
} catch (err) {
|
|
615
|
+
logger.error(`Error creating outbound audio track: ${(err as Error)?.message}`);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
for (const track of sample.outboundVideoTracks ?? []) {
|
|
621
|
+
if (!track.peerConnectionId || !track.trackId) {
|
|
622
|
+
logger.warn(`OutboundVideoTrack without peerConnectionId or trackId: ${JSON.stringify(track)}`);
|
|
623
|
+
|
|
624
|
+
continue;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
try {
|
|
628
|
+
const peerConnection = this._peerConnections.get(track.peerConnectionId) ?? await this._createPeerConnection(track.peerConnectionId);
|
|
629
|
+
|
|
630
|
+
if (!peerConnection) continue;
|
|
631
|
+
|
|
632
|
+
const outboundVideoTrack = peerConnection.outboundVideoTracks.get(track.trackId) ?? await peerConnection.createOutboundVideoTrack({
|
|
633
|
+
trackId: track.trackId,
|
|
634
|
+
sfuStreamId: track.sfuStreamId,
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
await outboundVideoTrack.update(track, sample.timestamp);
|
|
638
|
+
|
|
639
|
+
} catch (err) {
|
|
640
|
+
logger.error(`Error creating outbound video track: ${(err as Error)?.message}`);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (changeIceCandidatePair) {
|
|
645
|
+
this.emit('candidate-pair-change');
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
if (executeSave) await this._save();
|
|
649
|
+
|
|
650
|
+
this._updated = sample.timestamp;
|
|
651
|
+
this.emit('update');
|
|
652
|
+
}).finally(() => {
|
|
653
|
+
--this._processingSample;
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
private async _createPeerConnection(peerConnectionId: string): Promise<ObservedPeerConnection> {
|
|
658
|
+
const result = await ObservedPeerConnection.create({
|
|
659
|
+
peerConnectionId,
|
|
660
|
+
}, this, this._storageProvider);
|
|
661
|
+
|
|
662
|
+
result.once('close', () => {
|
|
663
|
+
this._peerConnections.delete(peerConnectionId);
|
|
664
|
+
this._model.peerConnectionIds = this._model.peerConnectionIds.filter((id) => id !== peerConnectionId);
|
|
665
|
+
this._save().catch(() => void 0);
|
|
666
|
+
});
|
|
667
|
+
this._peerConnections.set(peerConnectionId, result);
|
|
668
|
+
this._model.peerConnectionIds.push(peerConnectionId);
|
|
669
|
+
await this._save();
|
|
670
|
+
|
|
671
|
+
this.emit('newpeerconnection', result);
|
|
672
|
+
|
|
673
|
+
return result;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
private async _save() {
|
|
677
|
+
if (this._closed) throw new Error(`Client ${this.clientId} is closed`);
|
|
678
|
+
|
|
679
|
+
return this._storageProvider.clientStorage.set(this.clientId, this._model);
|
|
680
|
+
}
|
|
681
|
+
}
|