@observertc/observer-js 0.9.10-beta → 0.9.12-beta
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/Evaluator.d.ts +2 -0
- package/lib/Evaluator.d.ts.map +1 -1
- package/lib/Evaluator.js +2 -4
- package/lib/Observer.d.ts.map +1 -1
- package/lib/Observer.js +1 -0
- package/lib/common/callMetaReports.d.ts +1 -1
- package/lib/common/callMetaReports.d.ts.map +1 -1
- package/lib/common/callMetaReports.js +2 -1
- package/lib/common/utils.d.ts +1 -0
- package/lib/common/utils.d.ts.map +1 -1
- package/lib/common/utils.js +12 -0
- package/lib/middlewares/DeleteOutdatedCallEntries.d.ts +6 -0
- package/lib/middlewares/DeleteOutdatedCallEntries.d.ts.map +1 -0
- package/lib/middlewares/DeleteOutdatedCallEntries.js +112 -0
- package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts +6 -0
- package/lib/middlewares/DeleteOutdatedSfuEntries.d.ts.map +1 -0
- package/lib/middlewares/DeleteOutdatedSfuEntries.js +118 -0
- package/lib/middlewares/TransactionContext.d.ts.map +1 -1
- package/lib/middlewares/TransactionContext.js +42 -26
- package/lib/middlewares/TransactoinProcessor.d.ts +1 -1
- package/lib/middlewares/TransactoinProcessor.d.ts.map +1 -1
- package/lib/middlewares/TransactoinProcessor.js +4 -2
- package/lib/middlewares/VisitObservedCallsMiddleware.d.ts +2 -1
- package/lib/middlewares/VisitObservedCallsMiddleware.d.ts.map +1 -1
- package/lib/middlewares/VisitObservedCallsMiddleware.js +20 -90
- package/lib/middlewares/visitors/visitClient.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitClient.js +26 -17
- package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts +1 -1
- package/lib/middlewares/visitors/visitInboundAudioTrack.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitInboundAudioTrack.js +10 -2
- package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts +1 -1
- package/lib/middlewares/visitors/visitInboundVideoTrack.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitInboundVideoTrack.js +10 -2
- package/lib/middlewares/visitors/visitOutboundAudioTrack.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitOutboundAudioTrack.js +5 -1
- package/lib/middlewares/visitors/visitOutboundVideoTarck.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitOutboundVideoTarck.js +5 -1
- package/lib/middlewares/visitors/visitPeerConnection.d.ts.map +1 -1
- package/lib/middlewares/visitors/visitPeerConnection.js +15 -0
- package/lib/models/Models.d.ts +26 -22
- package/lib/models/Models.d.ts.map +1 -1
- package/lib/models/Models.js +16 -11
- package/lib/processes/findRemoteMatches.d.ts +9 -0
- package/lib/processes/findRemoteMatches.d.ts.map +1 -0
- package/lib/processes/findRemoteMatches.js +83 -0
- package/lib/processes/joinClientProcess.d.ts.map +1 -1
- package/lib/processes/joinClientProcess.js +1 -2
- package/lib/samples/ObservedCalls.d.ts.map +1 -1
- package/lib/samples/ObservedCalls.js +16 -7
- package/lib/samples/ObservedInboundAudioTrack.d.ts +2 -0
- package/lib/samples/ObservedInboundAudioTrack.d.ts.map +1 -1
- package/lib/samples/ObservedInboundVideoTrack.d.ts +2 -0
- package/lib/samples/ObservedInboundVideoTrack.d.ts.map +1 -1
- package/lib/samples/ObservedOutboundAudioTrack.d.ts +1 -0
- package/lib/samples/ObservedOutboundAudioTrack.d.ts.map +1 -1
- package/lib/samples/ObservedOutboundVideoTrack.d.ts +1 -0
- package/lib/samples/ObservedOutboundVideoTrack.d.ts.map +1 -1
- package/lib/samples/ObservedPeerConnection.d.ts.map +1 -1
- package/lib/samples/ObservedPeerConnection.js +15 -8
- package/lib/samples/ObservedSfus.d.ts.map +1 -1
- package/lib/samples/ObservedSfus.js +10 -4
- package/lib/storages/ObserverStorage.d.ts +4 -0
- package/lib/storages/ObserverStorage.d.ts.map +1 -1
- package/lib/storages/SimpleStorage.d.ts +1 -0
- package/lib/storages/SimpleStorage.d.ts.map +1 -1
- package/lib/storages/SimpleStorage.js +3 -0
- package/package.json +1 -1
- package/src/Evaluator.ts +7 -6
- package/src/Observer.ts +1 -0
- package/src/common/callMetaReports.ts +2 -0
- package/src/common/utils.ts +11 -0
- package/src/middlewares/DeleteOutdatedCallEntries.ts +151 -0
- package/src/middlewares/DeleteOutdatedSfuEntries.ts +159 -0
- package/src/middlewares/TransactionContext.ts +61 -29
- package/src/middlewares/TransactoinProcessor.ts +8 -2
- package/src/middlewares/VisitObservedCallsMiddleware.ts +42 -128
- package/src/middlewares/visitors/visitClient.ts +34 -18
- package/src/middlewares/visitors/visitInboundAudioTrack.ts +15 -5
- package/src/middlewares/visitors/visitInboundVideoTrack.ts +14 -2
- package/src/middlewares/visitors/visitOutboundAudioTrack.ts +6 -2
- package/src/middlewares/visitors/visitOutboundVideoTarck.ts +5 -1
- package/src/middlewares/visitors/visitPeerConnection.ts +17 -1
- package/src/models/Models.ts +40 -34
- package/src/processes/findRemoteMatches.ts +94 -0
- package/src/processes/joinClientProcess.ts +1 -3
- package/src/samples/ObservedCalls.ts +17 -7
- package/src/samples/ObservedInboundAudioTrack.ts +2 -0
- package/src/samples/ObservedInboundVideoTrack.ts +3 -1
- package/src/samples/ObservedOutboundAudioTrack.ts +2 -1
- package/src/samples/ObservedOutboundVideoTrack.ts +2 -1
- package/src/samples/ObservedPeerConnection.ts +29 -8
- package/src/samples/ObservedSfus.ts +10 -5
- package/src/storages/ObserverStorage.ts +5 -0
- package/src/storages/SimpleStorage.ts +4 -0
|
@@ -12,7 +12,7 @@ export function visitOutboundAudioTrack(
|
|
|
12
12
|
reports: ReportsCollector,
|
|
13
13
|
fetchSamples: boolean
|
|
14
14
|
) {
|
|
15
|
-
const { trackId } = observedOutboundAudioTrack;
|
|
15
|
+
const { trackId, sfuStreamId } = observedOutboundAudioTrack;
|
|
16
16
|
|
|
17
17
|
const { peerConnectionId } = observedOutboundAudioTrack.peerConnection;
|
|
18
18
|
|
|
@@ -33,10 +33,12 @@ export function visitOutboundAudioTrack(
|
|
|
33
33
|
roomId,
|
|
34
34
|
callId,
|
|
35
35
|
clientId,
|
|
36
|
+
kind: 'audio',
|
|
36
37
|
peerConnectionId,
|
|
37
38
|
mediaUnitId,
|
|
38
39
|
trackId,
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
sfuStreamId,
|
|
40
42
|
userId,
|
|
41
43
|
marker,
|
|
42
44
|
});
|
|
@@ -57,6 +59,7 @@ export function visitOutboundAudioTrack(
|
|
|
57
59
|
roomId,
|
|
58
60
|
callId,
|
|
59
61
|
clientId,
|
|
62
|
+
userId,
|
|
60
63
|
mediaUnitId,
|
|
61
64
|
peerConnectionId,
|
|
62
65
|
...outboundAudioSample,
|
|
@@ -88,5 +91,6 @@ export function visitOutboundAudioTrack(
|
|
|
88
91
|
statsMap.set(ssrc, audioStats);
|
|
89
92
|
}
|
|
90
93
|
}
|
|
94
|
+
storedOutboundAudioTrack.ssrc = [...statsMap.keys()];
|
|
91
95
|
storedOutboundAudioTrack.audioStats = Array.from(statsMap.values());
|
|
92
96
|
}
|
|
@@ -12,7 +12,7 @@ export function visitOutboundVideoTrack(
|
|
|
12
12
|
reports: ReportsCollector,
|
|
13
13
|
fetchSamples: boolean
|
|
14
14
|
) {
|
|
15
|
-
const { trackId } = observedOutboundVideoTrack;
|
|
15
|
+
const { trackId, sfuStreamId } = observedOutboundVideoTrack;
|
|
16
16
|
|
|
17
17
|
const { peerConnectionId } = observedOutboundVideoTrack.peerConnection;
|
|
18
18
|
|
|
@@ -33,10 +33,12 @@ export function visitOutboundVideoTrack(
|
|
|
33
33
|
roomId,
|
|
34
34
|
callId,
|
|
35
35
|
clientId,
|
|
36
|
+
kind: 'video',
|
|
36
37
|
peerConnectionId,
|
|
37
38
|
mediaUnitId,
|
|
38
39
|
trackId,
|
|
39
40
|
|
|
41
|
+
sfuStreamId,
|
|
40
42
|
userId,
|
|
41
43
|
marker,
|
|
42
44
|
});
|
|
@@ -57,6 +59,7 @@ export function visitOutboundVideoTrack(
|
|
|
57
59
|
roomId,
|
|
58
60
|
callId,
|
|
59
61
|
clientId,
|
|
62
|
+
userId,
|
|
60
63
|
mediaUnitId,
|
|
61
64
|
peerConnectionId,
|
|
62
65
|
...outboundVideoSample,
|
|
@@ -90,5 +93,6 @@ export function visitOutboundVideoTrack(
|
|
|
90
93
|
statsMap.set(ssrc, videoStats);
|
|
91
94
|
}
|
|
92
95
|
}
|
|
96
|
+
storedOutboundVideoTrack.ssrc = [...statsMap.keys()];
|
|
93
97
|
storedOutboundVideoTrack.videoStats = Array.from(statsMap.values());
|
|
94
98
|
}
|
|
@@ -2,7 +2,7 @@ import { ObservedPeerConnection } from '../../samples/ObservedPeerConnection';
|
|
|
2
2
|
import * as Models from '../../models/Models';
|
|
3
3
|
import { ReportsCollector } from '../../common/ReportsCollector';
|
|
4
4
|
import { logger } from '../VisitObservedCallsMiddleware';
|
|
5
|
-
import { PeerConnectionTransportReport } from '@observertc/report-schemas-js';
|
|
5
|
+
import { IceCandidatePairReport, PeerConnectionTransportReport } from '@observertc/report-schemas-js';
|
|
6
6
|
import { Samples_ClientSample_IceCandidatePair, Samples_ClientSample_IceLocalCandidate, Samples_ClientSample_IceRemoteCandidate, Samples_ClientSample_PeerConnectionTransport } from '../../models/samples_pb';
|
|
7
7
|
|
|
8
8
|
export function visitPeerConnection(
|
|
@@ -47,6 +47,7 @@ export function visitPeerConnection(
|
|
|
47
47
|
roomId,
|
|
48
48
|
callId,
|
|
49
49
|
clientId,
|
|
50
|
+
userId,
|
|
50
51
|
mediaUnitId,
|
|
51
52
|
...pcTransport,
|
|
52
53
|
timestamp,
|
|
@@ -55,6 +56,21 @@ export function visitPeerConnection(
|
|
|
55
56
|
reports.addPeerConnectionTransportReports(report);
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
for (const iceCandidatePair of observedPeerConnection.iceCandidatePairs()) {
|
|
60
|
+
const report: IceCandidatePairReport = {
|
|
61
|
+
serviceId,
|
|
62
|
+
roomId,
|
|
63
|
+
callId,
|
|
64
|
+
userId,
|
|
65
|
+
clientId,
|
|
66
|
+
mediaUnitId,
|
|
67
|
+
...iceCandidatePair,
|
|
68
|
+
timestamp,
|
|
69
|
+
sampleSeq: -1, // deprecated
|
|
70
|
+
};
|
|
71
|
+
reports.addIceCandidatePairReport(report);
|
|
72
|
+
}
|
|
73
|
+
|
|
58
74
|
if (fetchSamples) {
|
|
59
75
|
storedPeerConnection.icelocalCandidates = [];
|
|
60
76
|
for (const iceLocalCandidate of observedPeerConnection.iceLocalCandidates()) {
|
package/src/models/Models.ts
CHANGED
|
@@ -273,6 +273,11 @@ export class PeerConnection extends Message<PeerConnection> {
|
|
|
273
273
|
*/
|
|
274
274
|
transports: Samples_ClientSample_PeerConnectionTransport[] = [];
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
* @generated from field: optional uint64 touched = 17;
|
|
278
|
+
*/
|
|
279
|
+
touched?: bigint;
|
|
280
|
+
|
|
276
281
|
constructor(data?: PartialMessage<PeerConnection>) {
|
|
277
282
|
super();
|
|
278
283
|
proto2.util.initPartial(data, this);
|
|
@@ -297,6 +302,7 @@ export class PeerConnection extends Message<PeerConnection> {
|
|
|
297
302
|
{ no: 14, name: "iceRemoteCandidates", kind: "message", T: Samples_ClientSample_IceRemoteCandidate, repeated: true },
|
|
298
303
|
{ no: 15, name: "iceCandidatePairs", kind: "message", T: Samples_ClientSample_IceCandidatePair, repeated: true },
|
|
299
304
|
{ no: 16, name: "transports", kind: "message", T: Samples_ClientSample_PeerConnectionTransport, repeated: true },
|
|
305
|
+
{ no: 17, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
300
306
|
]);
|
|
301
307
|
|
|
302
308
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): PeerConnection {
|
|
@@ -386,15 +392,25 @@ export class InboundTrack extends Message<InboundTrack> {
|
|
|
386
392
|
sfuStreamId?: string;
|
|
387
393
|
|
|
388
394
|
/**
|
|
389
|
-
* @generated from field: repeated
|
|
395
|
+
* @generated from field: repeated int64 ssrc = 14;
|
|
396
|
+
*/
|
|
397
|
+
ssrc: bigint[] = [];
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* @generated from field: repeated org.observertc.schemas.protobuf.Samples.ClientSample.InboundAudioTrack audioStats = 15;
|
|
390
401
|
*/
|
|
391
402
|
audioStats: Samples_ClientSample_InboundAudioTrack[] = [];
|
|
392
403
|
|
|
393
404
|
/**
|
|
394
|
-
* @generated from field: repeated org.observertc.schemas.protobuf.Samples.ClientSample.InboundVideoTrack videoStats =
|
|
405
|
+
* @generated from field: repeated org.observertc.schemas.protobuf.Samples.ClientSample.InboundVideoTrack videoStats = 16;
|
|
395
406
|
*/
|
|
396
407
|
videoStats: Samples_ClientSample_InboundVideoTrack[] = [];
|
|
397
408
|
|
|
409
|
+
/**
|
|
410
|
+
* @generated from field: optional uint64 touched = 17;
|
|
411
|
+
*/
|
|
412
|
+
touched?: bigint;
|
|
413
|
+
|
|
398
414
|
constructor(data?: PartialMessage<InboundTrack>) {
|
|
399
415
|
super();
|
|
400
416
|
proto2.util.initPartial(data, this);
|
|
@@ -416,8 +432,10 @@ export class InboundTrack extends Message<InboundTrack> {
|
|
|
416
432
|
{ no: 11, name: "marker", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
417
433
|
{ no: 12, name: "sfuSinkId", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
418
434
|
{ no: 13, name: "sfuStreamId", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
419
|
-
{ no: 14, name: "
|
|
420
|
-
{ no: 15, name: "
|
|
435
|
+
{ no: 14, name: "ssrc", kind: "scalar", T: 3 /* ScalarType.INT64 */, repeated: true },
|
|
436
|
+
{ no: 15, name: "audioStats", kind: "message", T: Samples_ClientSample_InboundAudioTrack, repeated: true },
|
|
437
|
+
{ no: 16, name: "videoStats", kind: "message", T: Samples_ClientSample_InboundVideoTrack, repeated: true },
|
|
438
|
+
{ no: 17, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
421
439
|
]);
|
|
422
440
|
|
|
423
441
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): InboundTrack {
|
|
@@ -516,6 +534,11 @@ export class OutboundTrack extends Message<OutboundTrack> {
|
|
|
516
534
|
*/
|
|
517
535
|
videoStats: Samples_ClientSample_OutboundVideoTrack[] = [];
|
|
518
536
|
|
|
537
|
+
/**
|
|
538
|
+
* @generated from field: optional uint64 touched = 16;
|
|
539
|
+
*/
|
|
540
|
+
touched?: bigint;
|
|
541
|
+
|
|
519
542
|
constructor(data?: PartialMessage<OutboundTrack>) {
|
|
520
543
|
super();
|
|
521
544
|
proto2.util.initPartial(data, this);
|
|
@@ -539,6 +562,7 @@ export class OutboundTrack extends Message<OutboundTrack> {
|
|
|
539
562
|
{ no: 13, name: "ssrc", kind: "scalar", T: 3 /* ScalarType.INT64 */, repeated: true },
|
|
540
563
|
{ no: 14, name: "audioStats", kind: "message", T: Samples_ClientSample_OutboundAudioTrack, repeated: true },
|
|
541
564
|
{ no: 15, name: "videoStats", kind: "message", T: Samples_ClientSample_OutboundVideoTrack, repeated: true },
|
|
565
|
+
{ no: 16, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
542
566
|
]);
|
|
543
567
|
|
|
544
568
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): OutboundTrack {
|
|
@@ -703,9 +727,9 @@ export class SfuTransport extends Message<SfuTransport> {
|
|
|
703
727
|
sctpChannelIds: string[] = [];
|
|
704
728
|
|
|
705
729
|
/**
|
|
706
|
-
* @generated from field: optional uint64
|
|
730
|
+
* @generated from field: optional uint64 touched = 12;
|
|
707
731
|
*/
|
|
708
|
-
|
|
732
|
+
touched?: bigint;
|
|
709
733
|
|
|
710
734
|
constructor(data?: PartialMessage<SfuTransport>) {
|
|
711
735
|
super();
|
|
@@ -726,7 +750,7 @@ export class SfuTransport extends Message<SfuTransport> {
|
|
|
726
750
|
{ no: 9, name: "inboundRtpPadIds", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
|
727
751
|
{ no: 10, name: "outboundRtpPadIds", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
|
728
752
|
{ no: 11, name: "sctpChannelIds", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true },
|
|
729
|
-
{ no: 12, name: "
|
|
753
|
+
{ no: 12, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
730
754
|
]);
|
|
731
755
|
|
|
732
756
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SfuTransport {
|
|
@@ -791,9 +815,9 @@ export class SfuInboundRtpPad extends Message<SfuInboundRtpPad> {
|
|
|
791
815
|
added?: bigint;
|
|
792
816
|
|
|
793
817
|
/**
|
|
794
|
-
* @generated from field: optional uint64
|
|
818
|
+
* @generated from field: optional uint64 touched = 9;
|
|
795
819
|
*/
|
|
796
|
-
|
|
820
|
+
touched?: bigint;
|
|
797
821
|
|
|
798
822
|
/**
|
|
799
823
|
* @generated from field: optional string mediaUnitId = 10;
|
|
@@ -805,11 +829,6 @@ export class SfuInboundRtpPad extends Message<SfuInboundRtpPad> {
|
|
|
805
829
|
*/
|
|
806
830
|
marker?: string;
|
|
807
831
|
|
|
808
|
-
/**
|
|
809
|
-
* @generated from field: optional uint64 serverTouched = 12;
|
|
810
|
-
*/
|
|
811
|
-
serverTouched?: bigint;
|
|
812
|
-
|
|
813
832
|
constructor(data?: PartialMessage<SfuInboundRtpPad>) {
|
|
814
833
|
super();
|
|
815
834
|
proto2.util.initPartial(data, this);
|
|
@@ -826,10 +845,9 @@ export class SfuInboundRtpPad extends Message<SfuInboundRtpPad> {
|
|
|
826
845
|
{ no: 6, name: "ssrc", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
|
827
846
|
{ no: 7, name: "internal", kind: "scalar", T: 8 /* ScalarType.BOOL */, default: false },
|
|
828
847
|
{ no: 8, name: "added", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
|
|
829
|
-
{ no: 9, name: "
|
|
848
|
+
{ no: 9, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
830
849
|
{ no: 10, name: "mediaUnitId", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
831
850
|
{ no: 11, name: "marker", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
832
|
-
{ no: 12, name: "serverTouched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
833
851
|
]);
|
|
834
852
|
|
|
835
853
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SfuInboundRtpPad {
|
|
@@ -899,9 +917,9 @@ export class SfuOutboundRtpPad extends Message<SfuOutboundRtpPad> {
|
|
|
899
917
|
added?: bigint;
|
|
900
918
|
|
|
901
919
|
/**
|
|
902
|
-
* @generated from field: optional uint64
|
|
920
|
+
* @generated from field: optional uint64 touched = 10;
|
|
903
921
|
*/
|
|
904
|
-
|
|
922
|
+
touched?: bigint;
|
|
905
923
|
|
|
906
924
|
/**
|
|
907
925
|
* @generated from field: optional string mediaUnitId = 11;
|
|
@@ -913,11 +931,6 @@ export class SfuOutboundRtpPad extends Message<SfuOutboundRtpPad> {
|
|
|
913
931
|
*/
|
|
914
932
|
marker?: string;
|
|
915
933
|
|
|
916
|
-
/**
|
|
917
|
-
* @generated from field: optional uint64 serverTouched = 13;
|
|
918
|
-
*/
|
|
919
|
-
serverTouched?: bigint;
|
|
920
|
-
|
|
921
934
|
constructor(data?: PartialMessage<SfuOutboundRtpPad>) {
|
|
922
935
|
super();
|
|
923
936
|
proto2.util.initPartial(data, this);
|
|
@@ -935,10 +948,9 @@ export class SfuOutboundRtpPad extends Message<SfuOutboundRtpPad> {
|
|
|
935
948
|
{ no: 7, name: "ssrc", kind: "scalar", T: 3 /* ScalarType.INT64 */ },
|
|
936
949
|
{ no: 8, name: "internal", kind: "scalar", T: 8 /* ScalarType.BOOL */, default: false },
|
|
937
950
|
{ no: 9, name: "added", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
|
|
938
|
-
{ no: 10, name: "
|
|
951
|
+
{ no: 10, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
939
952
|
{ no: 11, name: "mediaUnitId", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
940
953
|
{ no: 12, name: "marker", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
941
|
-
{ no: 13, name: "serverTouched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
942
954
|
]);
|
|
943
955
|
|
|
944
956
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SfuOutboundRtpPad {
|
|
@@ -993,9 +1005,9 @@ export class SfuSctpChannel extends Message<SfuSctpChannel> {
|
|
|
993
1005
|
opened?: bigint;
|
|
994
1006
|
|
|
995
1007
|
/**
|
|
996
|
-
* @generated from field: optional uint64
|
|
1008
|
+
* @generated from field: optional uint64 touched = 7;
|
|
997
1009
|
*/
|
|
998
|
-
|
|
1010
|
+
touched?: bigint;
|
|
999
1011
|
|
|
1000
1012
|
/**
|
|
1001
1013
|
* @generated from field: optional string mediaUnitId = 8;
|
|
@@ -1007,11 +1019,6 @@ export class SfuSctpChannel extends Message<SfuSctpChannel> {
|
|
|
1007
1019
|
*/
|
|
1008
1020
|
marker?: string;
|
|
1009
1021
|
|
|
1010
|
-
/**
|
|
1011
|
-
* @generated from field: optional uint64 serverTouched = 10;
|
|
1012
|
-
*/
|
|
1013
|
-
serverTouched?: bigint;
|
|
1014
|
-
|
|
1015
1022
|
constructor(data?: PartialMessage<SfuSctpChannel>) {
|
|
1016
1023
|
super();
|
|
1017
1024
|
proto2.util.initPartial(data, this);
|
|
@@ -1026,10 +1033,9 @@ export class SfuSctpChannel extends Message<SfuSctpChannel> {
|
|
|
1026
1033
|
{ no: 4, name: "sfuSctpStreamId", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1027
1034
|
{ no: 5, name: "sfuSctpChannelId", kind: "scalar", T: 9 /* ScalarType.STRING */ },
|
|
1028
1035
|
{ no: 6, name: "opened", kind: "scalar", T: 4 /* ScalarType.UINT64 */ },
|
|
1029
|
-
{ no: 7, name: "
|
|
1036
|
+
{ no: 7, name: "touched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
1030
1037
|
{ no: 8, name: "mediaUnitId", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
1031
1038
|
{ no: 9, name: "marker", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
|
|
1032
|
-
{ no: 10, name: "serverTouched", kind: "scalar", T: 4 /* ScalarType.UINT64 */, opt: true },
|
|
1033
1039
|
]);
|
|
1034
1040
|
|
|
1035
1041
|
static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): SfuSctpChannel {
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { InboundAudioTrack, InboundVideoTrack } from "@observertc/sample-schemas-js";
|
|
2
|
+
import { createLogger } from "../common/logger";
|
|
3
|
+
import { Client, InboundTrack, OutboundTrack, PeerConnection } from "../models/Models";
|
|
4
|
+
import { StorageProvider } from "../storages/StorageProvider";
|
|
5
|
+
|
|
6
|
+
export const logger = createLogger('findRemoteMatches');
|
|
7
|
+
|
|
8
|
+
function groupToMap<T>(input: ReadonlyMap<string, T>, getGroupKey: (value: T) => string | undefined) {
|
|
9
|
+
const result = new Map<string, T[]>();
|
|
10
|
+
for (const [key, value] of input.entries()) {
|
|
11
|
+
const groupKey = getGroupKey(value);
|
|
12
|
+
if (!groupKey) continue;
|
|
13
|
+
|
|
14
|
+
let group = result.get(groupKey);
|
|
15
|
+
if (group === undefined) {
|
|
16
|
+
group = [];
|
|
17
|
+
result.set(groupKey, group);
|
|
18
|
+
}
|
|
19
|
+
group.push(value);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export async function findRemoteMatches(
|
|
26
|
+
storages: StorageProvider,
|
|
27
|
+
clients: ReadonlyMap<string, Client>,
|
|
28
|
+
inboundTracks: ReadonlyMap<string, InboundTrack>,
|
|
29
|
+
) {
|
|
30
|
+
const NOT_EXISTS = "NotExists";
|
|
31
|
+
const remoteTrackIds = new Map<string, string>();
|
|
32
|
+
const remotePeerConnectionIds = new Map<string, string>();
|
|
33
|
+
const remoteClientIds = new Map<string, string>();
|
|
34
|
+
|
|
35
|
+
async function setupMatches(callId: string, callClients: Client[], callIboundTracks: InboundTrack[]) {
|
|
36
|
+
const peerConnectionIds = Array.from(callClients.values()).flatMap(client => client.peerConnectionIds);
|
|
37
|
+
const peerConnections = await storages.peerConnectionStorage.getAll(peerConnectionIds).catch(err => {
|
|
38
|
+
logger.warn(`Error while fetching for remote matching peer connections for call ${callId} `, err)
|
|
39
|
+
return new Map<string, PeerConnection>() as ReadonlyMap<string, PeerConnection>;
|
|
40
|
+
});
|
|
41
|
+
const outboundTrackIds = Array.from(peerConnections.values()).flatMap(pc => pc.outboundTrackIds);
|
|
42
|
+
const outboundTracks = await storages.outboundTrackStorage.getAll(outboundTrackIds).catch(err => {
|
|
43
|
+
logger.warn(`Error while fetching for remote matching outbound tracks for call ${callId} `, err)
|
|
44
|
+
return new Map<string, OutboundTrack>() as ReadonlyMap<string, OutboundTrack>;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// console.warn("setupMatches", peerConnectionIds, outboundTrackIds, callsClients, callsInbTracks);
|
|
48
|
+
|
|
49
|
+
const ssrcToOutb = new Map<bigint, OutboundTrack>();
|
|
50
|
+
const sfuStreamToTrackIds = new Map<string, OutboundTrack>();
|
|
51
|
+
for (const outbTrack of outboundTracks.values()) {
|
|
52
|
+
if (outbTrack.sfuStreamId) {
|
|
53
|
+
sfuStreamToTrackIds.set(outbTrack.sfuStreamId, outbTrack);
|
|
54
|
+
}
|
|
55
|
+
for (const ssrc of outbTrack.ssrc) {
|
|
56
|
+
ssrcToOutb.set(ssrc, outbTrack);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (const inbTrack of callIboundTracks) {
|
|
60
|
+
let outbTrack: OutboundTrack | undefined;
|
|
61
|
+
if (inbTrack.sfuStreamId) {
|
|
62
|
+
outbTrack = sfuStreamToTrackIds.get(inbTrack.sfuStreamId);
|
|
63
|
+
} else {
|
|
64
|
+
outbTrack = inbTrack.ssrc.map(ssrc => ssrcToOutb.get(ssrc)).find(outb => outb !== undefined);
|
|
65
|
+
}
|
|
66
|
+
if (outbTrack) {
|
|
67
|
+
remoteTrackIds.set(inbTrack.trackId ?? NOT_EXISTS, outbTrack.trackId ?? NOT_EXISTS);
|
|
68
|
+
remotePeerConnectionIds.set(inbTrack.trackId ?? NOT_EXISTS, outbTrack.peerConnectionId ?? NOT_EXISTS);
|
|
69
|
+
remoteClientIds.set(inbTrack.trackId ?? NOT_EXISTS, outbTrack.clientId ?? NOT_EXISTS);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const callsClients = groupToMap<Client>(clients, client => client.callId);
|
|
74
|
+
const callsInbTracks = groupToMap<InboundTrack>(inboundTracks, inbTrack => inbTrack.callId)
|
|
75
|
+
|
|
76
|
+
const promises: Promise<void>[] = [];
|
|
77
|
+
for (const [callId, callClients] of callsClients) {
|
|
78
|
+
const callIboundTracks = callsInbTracks.get(callId) ?? [];
|
|
79
|
+
const promise = setupMatches(
|
|
80
|
+
callId,
|
|
81
|
+
callClients,
|
|
82
|
+
callIboundTracks
|
|
83
|
+
);
|
|
84
|
+
promises.push(promise);
|
|
85
|
+
}
|
|
86
|
+
await Promise.all(promises).catch(err => {
|
|
87
|
+
logger.warn(`Error occurred while fetching remote pair matches`, err);
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
remoteTrackIds,
|
|
91
|
+
remotePeerConnectionIds,
|
|
92
|
+
remoteClientIds
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -3,11 +3,9 @@ import { StorageProvider } from '../storages/StorageProvider';
|
|
|
3
3
|
import * as Models from '../models/Models';
|
|
4
4
|
import { createCallStartedEventReport, createClientJoinedEventReport } from '../sinks/callEventReports';
|
|
5
5
|
import { ReportsCollector } from '../common/ReportsCollector';
|
|
6
|
-
import { createClosePeerConnectionProcess } from './closePeerConnectionProcess';
|
|
7
6
|
import { createLogger } from '../common/logger';
|
|
8
7
|
import { ObservedClientSourceConfig } from '../sources/ObservedClientSource';
|
|
9
8
|
import { Writable } from '../common/utils';
|
|
10
|
-
import { Semaphore } from '../common/Semaphore';
|
|
11
9
|
|
|
12
10
|
const logger = createLogger('ClientLeftProcess');
|
|
13
11
|
|
|
@@ -21,7 +19,6 @@ export function createJoinClientProcess(
|
|
|
21
19
|
storageProvider: StorageProvider,
|
|
22
20
|
reports: ReportsCollector
|
|
23
21
|
): (input: JoinClientProcessInput) => Promise<void> {
|
|
24
|
-
const peerConnectionClosedProcess = createClosePeerConnectionProcess(storageProvider);
|
|
25
22
|
const process = async (context: JoinClientProcessInput) => {
|
|
26
23
|
const { clients: joinedClients, evaluatorContext } = context;
|
|
27
24
|
if (joinedClients.length < 1) {
|
|
@@ -60,6 +57,7 @@ export function createJoinClientProcess(
|
|
|
60
57
|
roomId,
|
|
61
58
|
callId,
|
|
62
59
|
clientId,
|
|
60
|
+
joined: BigInt(timestamp),
|
|
63
61
|
timeZoneId,
|
|
64
62
|
marker,
|
|
65
63
|
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { iteratorConverter } from '../common/utils';
|
|
1
2
|
import { ObservedCall, ObservedCallBuilder } from './ObservedCall';
|
|
2
3
|
|
|
3
4
|
export interface ObservedCalls {
|
|
@@ -35,21 +36,23 @@ export class ObservedCallsBuilder {
|
|
|
35
36
|
public build(): ObservedCalls {
|
|
36
37
|
const observedCalls = new Map<string, ObservedCall>();
|
|
37
38
|
|
|
38
|
-
const
|
|
39
|
+
const callIdsGenerator = function* () {
|
|
39
40
|
for (const observedCall of observedCalls.values()) {
|
|
40
41
|
yield observedCall.callId;
|
|
41
42
|
}
|
|
42
43
|
};
|
|
44
|
+
const callIds = () => iteratorConverter<string>(callIdsGenerator());
|
|
43
45
|
|
|
44
|
-
const
|
|
46
|
+
const clientIdsGenerator = function* () {
|
|
45
47
|
for (const observedCall of observedCalls.values()) {
|
|
46
48
|
for (const observedClient of observedCall.observedClients()) {
|
|
47
49
|
yield observedClient.clientId;
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
};
|
|
53
|
+
const clientIds = () => iteratorConverter<string>(clientIdsGenerator());
|
|
51
54
|
|
|
52
|
-
const
|
|
55
|
+
const peerConnectionIdsGenerator = function* () {
|
|
53
56
|
for (const observedCall of observedCalls.values()) {
|
|
54
57
|
for (const observedClient of observedCall.observedClients()) {
|
|
55
58
|
for (const observedPeerConnection of observedClient.observedPeerConnections()) {
|
|
@@ -58,8 +61,9 @@ export class ObservedCallsBuilder {
|
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
};
|
|
64
|
+
const peerConnectionIds = () => iteratorConverter<string>(peerConnectionIdsGenerator());
|
|
61
65
|
|
|
62
|
-
const
|
|
66
|
+
const inboundAudioTrackIdsGenerator = function* () {
|
|
63
67
|
for (const observedCall of observedCalls.values()) {
|
|
64
68
|
for (const observedClient of observedCall.observedClients()) {
|
|
65
69
|
for (const observedPeerConnection of observedClient.observedPeerConnections()) {
|
|
@@ -70,8 +74,9 @@ export class ObservedCallsBuilder {
|
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
};
|
|
77
|
+
const inboundAudioTrackIds = () => iteratorConverter<string>(inboundAudioTrackIdsGenerator());
|
|
73
78
|
|
|
74
|
-
const
|
|
79
|
+
const inboundVideoTrackIdsGenerator = function* () {
|
|
75
80
|
for (const observedCall of observedCalls.values()) {
|
|
76
81
|
for (const observedClient of observedCall.observedClients()) {
|
|
77
82
|
for (const observedPeerConnection of observedClient.observedPeerConnections()) {
|
|
@@ -82,8 +87,9 @@ export class ObservedCallsBuilder {
|
|
|
82
87
|
}
|
|
83
88
|
}
|
|
84
89
|
};
|
|
90
|
+
const inboundVideoTrackIds = () => iteratorConverter<string>(inboundVideoTrackIdsGenerator());
|
|
85
91
|
|
|
86
|
-
const
|
|
92
|
+
const outboundAudioTrackIdsGenerator = function* () {
|
|
87
93
|
for (const observedCall of observedCalls.values()) {
|
|
88
94
|
for (const observedClient of observedCall.observedClients()) {
|
|
89
95
|
for (const observedPeerConnection of observedClient.observedPeerConnections()) {
|
|
@@ -94,8 +100,9 @@ export class ObservedCallsBuilder {
|
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
102
|
};
|
|
103
|
+
const outboundAudioTrackIds = () => iteratorConverter<string>(outboundAudioTrackIdsGenerator());
|
|
97
104
|
|
|
98
|
-
const
|
|
105
|
+
const outboundVideoTrackIdsGenerator = function* () {
|
|
99
106
|
for (const observedCall of observedCalls.values()) {
|
|
100
107
|
for (const observedClient of observedCall.observedClients()) {
|
|
101
108
|
for (const observedPeerConnection of observedClient.observedPeerConnections()) {
|
|
@@ -106,6 +113,7 @@ export class ObservedCallsBuilder {
|
|
|
106
113
|
}
|
|
107
114
|
}
|
|
108
115
|
};
|
|
116
|
+
const outboundVideoTrackIds = () => iteratorConverter<string>(outboundVideoTrackIdsGenerator());
|
|
109
117
|
|
|
110
118
|
const result: ObservedCalls = {
|
|
111
119
|
callIds,
|
|
@@ -122,6 +130,8 @@ export class ObservedCallsBuilder {
|
|
|
122
130
|
const observedCall = builder.build();
|
|
123
131
|
observedCalls.set(observedCall.callId, observedCall);
|
|
124
132
|
}
|
|
133
|
+
this._builders.clear();
|
|
125
134
|
return result;
|
|
126
135
|
}
|
|
136
|
+
|
|
127
137
|
}
|
|
@@ -4,6 +4,8 @@ import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
|
4
4
|
export interface ObservedInboundAudioTrack {
|
|
5
5
|
readonly peerConnection: ObservedPeerConnection;
|
|
6
6
|
readonly trackId: string;
|
|
7
|
+
readonly sfuStreamId?: string,
|
|
8
|
+
readonly sfuSinkId?: string,
|
|
7
9
|
|
|
8
10
|
samples(): IterableIterator<InboundAudioTrack>;
|
|
9
11
|
}
|
|
@@ -4,7 +4,9 @@ import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
|
4
4
|
export interface ObservedInboundVideoTrack {
|
|
5
5
|
readonly peerConnection: ObservedPeerConnection;
|
|
6
6
|
readonly trackId: string;
|
|
7
|
-
|
|
7
|
+
readonly sfuStreamId?: string,
|
|
8
|
+
readonly sfuSinkId?: string,
|
|
9
|
+
|
|
8
10
|
samples(): IterableIterator<InboundVideoTrack>;
|
|
9
11
|
}
|
|
10
12
|
|
|
@@ -4,7 +4,8 @@ import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
|
4
4
|
export interface ObservedOutboundAudioTrack {
|
|
5
5
|
readonly peerConnection: ObservedPeerConnection;
|
|
6
6
|
readonly trackId: string;
|
|
7
|
-
|
|
7
|
+
readonly sfuStreamId?: string,
|
|
8
|
+
|
|
8
9
|
samples(): IterableIterator<OutboundAudioTrack>;
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -4,7 +4,8 @@ import { ObservedPeerConnection } from './ObservedPeerConnection';
|
|
|
4
4
|
export interface ObservedOutboundVideoTrack {
|
|
5
5
|
readonly peerConnection: ObservedPeerConnection;
|
|
6
6
|
readonly trackId: string;
|
|
7
|
-
|
|
7
|
+
readonly sfuStreamId?: string,
|
|
8
|
+
|
|
8
9
|
samples(): IterableIterator<OutboundVideoTrack>;
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -66,7 +66,11 @@ export class ObservedPeerConnectionBuilder {
|
|
|
66
66
|
|
|
67
67
|
public addInboundAudioTrack(inboundAudioTrackSample: InboundAudioTrack) {
|
|
68
68
|
if (inboundAudioTrackSample.trackId) {
|
|
69
|
-
const builder = this._getInboundAudioTrackBuilder(
|
|
69
|
+
const builder = this._getInboundAudioTrackBuilder(
|
|
70
|
+
inboundAudioTrackSample.trackId,
|
|
71
|
+
inboundAudioTrackSample.sfuStreamId,
|
|
72
|
+
inboundAudioTrackSample.sfuSinkId
|
|
73
|
+
);
|
|
70
74
|
builder.addSample(inboundAudioTrackSample);
|
|
71
75
|
}
|
|
72
76
|
}
|
|
@@ -81,28 +85,35 @@ export class ObservedPeerConnectionBuilder {
|
|
|
81
85
|
this._iceLocalCandidates.push(iceLocalCandidate);
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
private _getInboundAudioTrackBuilder(trackId: string): ObservedInboundAudioTrackBuilder {
|
|
88
|
+
private _getInboundAudioTrackBuilder(trackId: string, sfuStreamId?: string, sfuSinkId?: string): ObservedInboundAudioTrackBuilder {
|
|
85
89
|
let result = this._inboundAudioTracks.get(trackId);
|
|
86
90
|
if (!result) {
|
|
87
91
|
result = new ObservedInboundAudioTrackBuilder({
|
|
88
92
|
trackId,
|
|
93
|
+
sfuStreamId,
|
|
94
|
+
sfuSinkId,
|
|
89
95
|
});
|
|
96
|
+
this._inboundAudioTracks.set(trackId, result);
|
|
90
97
|
}
|
|
91
98
|
return result;
|
|
92
99
|
}
|
|
93
100
|
|
|
94
101
|
public addOutboundAudioTrack(outboundAudioTrackSample: OutboundAudioTrack) {
|
|
95
102
|
if (outboundAudioTrackSample.trackId) {
|
|
96
|
-
const builder = this._getOutboundAudioTrackBuilder(
|
|
103
|
+
const builder = this._getOutboundAudioTrackBuilder(
|
|
104
|
+
outboundAudioTrackSample.trackId,
|
|
105
|
+
outboundAudioTrackSample.sfuStreamId,
|
|
106
|
+
);
|
|
97
107
|
builder.addSample(outboundAudioTrackSample);
|
|
98
108
|
}
|
|
99
109
|
}
|
|
100
110
|
|
|
101
|
-
private _getOutboundAudioTrackBuilder(trackId: string): ObservedOutboundAudioTrackBuilder {
|
|
111
|
+
private _getOutboundAudioTrackBuilder(trackId: string, sfuStreamId?: string): ObservedOutboundAudioTrackBuilder {
|
|
102
112
|
let result = this._outboundAudioTracks.get(trackId);
|
|
103
113
|
if (!result) {
|
|
104
114
|
result = new ObservedOutboundAudioTrackBuilder({
|
|
105
115
|
trackId,
|
|
116
|
+
sfuStreamId
|
|
106
117
|
});
|
|
107
118
|
this._outboundAudioTracks.set(trackId, result);
|
|
108
119
|
}
|
|
@@ -111,16 +122,22 @@ export class ObservedPeerConnectionBuilder {
|
|
|
111
122
|
|
|
112
123
|
public addInboundVideoTrack(inboundVideoTrackSample: InboundVideoTrack) {
|
|
113
124
|
if (inboundVideoTrackSample.trackId) {
|
|
114
|
-
const builder = this._getInboundVideoTrackBuilder(
|
|
125
|
+
const builder = this._getInboundVideoTrackBuilder(
|
|
126
|
+
inboundVideoTrackSample.trackId,
|
|
127
|
+
inboundVideoTrackSample.sfuStreamId,
|
|
128
|
+
inboundVideoTrackSample.sfuSinkId,
|
|
129
|
+
);
|
|
115
130
|
builder.addSample(inboundVideoTrackSample);
|
|
116
131
|
}
|
|
117
132
|
}
|
|
118
133
|
|
|
119
|
-
private _getInboundVideoTrackBuilder(trackId: string): ObservedInboundVideoTrackBuilder {
|
|
134
|
+
private _getInboundVideoTrackBuilder(trackId: string, sfuStreamId?: string, sfuSinkId?: string): ObservedInboundVideoTrackBuilder {
|
|
120
135
|
let result = this._inboundVideoTracks.get(trackId);
|
|
121
136
|
if (!result) {
|
|
122
137
|
result = new ObservedInboundVideoTrackBuilder({
|
|
123
138
|
trackId,
|
|
139
|
+
sfuStreamId,
|
|
140
|
+
sfuSinkId,
|
|
124
141
|
});
|
|
125
142
|
this._inboundVideoTracks.set(trackId, result);
|
|
126
143
|
}
|
|
@@ -129,16 +146,20 @@ export class ObservedPeerConnectionBuilder {
|
|
|
129
146
|
|
|
130
147
|
public addOutboundVideoTrack(outboundVideoTrackSample: OutboundVideoTrack) {
|
|
131
148
|
if (outboundVideoTrackSample.trackId) {
|
|
132
|
-
const builder = this._getOutboundVideoTrackBuilder(
|
|
149
|
+
const builder = this._getOutboundVideoTrackBuilder(
|
|
150
|
+
outboundVideoTrackSample.trackId,
|
|
151
|
+
outboundVideoTrackSample.sfuStreamId,
|
|
152
|
+
);
|
|
133
153
|
builder.addSample(outboundVideoTrackSample);
|
|
134
154
|
}
|
|
135
155
|
}
|
|
136
156
|
|
|
137
|
-
private _getOutboundVideoTrackBuilder(trackId: string): ObservedOutboundVideoTrackBuilder {
|
|
157
|
+
private _getOutboundVideoTrackBuilder(trackId: string, sfuStreamId?: string): ObservedOutboundVideoTrackBuilder {
|
|
138
158
|
let result = this._outboundVideoTracks.get(trackId);
|
|
139
159
|
if (!result) {
|
|
140
160
|
result = new ObservedOutboundVideoTrackBuilder({
|
|
141
161
|
trackId,
|
|
162
|
+
sfuStreamId,
|
|
142
163
|
});
|
|
143
164
|
this._outboundVideoTracks.set(trackId, result);
|
|
144
165
|
}
|