livekit-client 2.18.0 → 2.18.1
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/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +8 -7
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +7832 -5799
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/api/SignalClient.d.ts +12 -4
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/e2ee/constants.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +6 -0
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/utils.d.ts +2 -1
- package/dist/src/e2ee/utils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/DataCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +5 -0
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/PCTransportManager.d.ts +1 -1
- package/dist/src/room/PCTransportManager.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +24 -8
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +13 -3
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts.map +1 -1
- package/dist/src/room/data-track/LocalDataTrack.d.ts +28 -5
- package/dist/src/room/data-track/LocalDataTrack.d.ts.map +1 -1
- package/dist/src/room/data-track/RemoteDataTrack.d.ts +5 -5
- package/dist/src/room/data-track/RemoteDataTrack.d.ts.map +1 -1
- package/dist/src/room/data-track/depacketizer.d.ts +4 -4
- package/dist/src/room/data-track/depacketizer.d.ts.map +1 -1
- package/dist/src/room/data-track/frame.d.ts +14 -0
- package/dist/src/room/data-track/frame.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +19 -11
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/pipeline.d.ts +6 -5
- package/dist/src/room/data-track/incoming/pipeline.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +57 -23
- package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/errors.d.ts +16 -6
- package/dist/src/room/data-track/outgoing/errors.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/pipeline.d.ts +7 -6
- package/dist/src/room/data-track/outgoing/pipeline.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/types.d.ts +14 -4
- package/dist/src/room/data-track/outgoing/types.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/extensions.d.ts.map +1 -1
- package/dist/src/room/data-track/packetizer.d.ts +4 -4
- package/dist/src/room/data-track/packetizer.d.ts.map +1 -1
- package/dist/src/room/data-track/track-interfaces.d.ts +1 -1
- package/dist/src/room/data-track/track-interfaces.d.ts.map +1 -1
- package/dist/src/room/data-track/types.d.ts +6 -1
- package/dist/src/room/data-track/types.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +24 -3
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +11 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +13 -0
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +1 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/utils/deferrable-map.d.ts +32 -0
- package/dist/src/utils/deferrable-map.d.ts.map +1 -0
- package/dist/ts4.2/api/SignalClient.d.ts +12 -4
- package/dist/ts4.2/e2ee/types.d.ts +6 -0
- package/dist/ts4.2/e2ee/utils.d.ts +2 -1
- package/dist/ts4.2/index.d.ts +5 -4
- package/dist/ts4.2/room/PCTransport.d.ts +5 -0
- package/dist/ts4.2/room/PCTransportManager.d.ts +1 -1
- package/dist/ts4.2/room/RTCEngine.d.ts +24 -8
- package/dist/ts4.2/room/Room.d.ts +13 -3
- package/dist/ts4.2/room/data-track/LocalDataTrack.d.ts +27 -4
- package/dist/ts4.2/room/data-track/RemoteDataTrack.d.ts +4 -4
- package/dist/ts4.2/room/data-track/depacketizer.d.ts +4 -4
- package/dist/ts4.2/room/data-track/frame.d.ts +14 -0
- package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +21 -10
- package/dist/ts4.2/room/data-track/incoming/pipeline.d.ts +6 -5
- package/dist/ts4.2/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +57 -23
- package/dist/ts4.2/room/data-track/outgoing/errors.d.ts +16 -6
- package/dist/ts4.2/room/data-track/outgoing/pipeline.d.ts +7 -6
- package/dist/ts4.2/room/data-track/outgoing/types.d.ts +14 -4
- package/dist/ts4.2/room/data-track/packetizer.d.ts +4 -4
- package/dist/ts4.2/room/data-track/track-interfaces.d.ts +1 -1
- package/dist/ts4.2/room/data-track/types.d.ts +6 -1
- package/dist/ts4.2/room/events.d.ts +24 -3
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +11 -1
- package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +13 -0
- package/dist/ts4.2/room/utils.d.ts +1 -0
- package/dist/ts4.2/utils/deferrable-map.d.ts +32 -0
- package/package.json +1 -1
- package/src/api/SignalClient.test.ts +9 -4
- package/src/api/SignalClient.ts +116 -9
- package/src/e2ee/constants.ts +1 -0
- package/src/e2ee/types.ts +6 -0
- package/src/e2ee/utils.ts +4 -3
- package/src/e2ee/worker/DataCryptor.ts +1 -4
- package/src/e2ee/worker/FrameCryptor.ts +1 -4
- package/src/e2ee/worker/ParticipantKeyHandler.ts +1 -1
- package/src/index.ts +6 -4
- package/src/room/PCTransport.ts +41 -1
- package/src/room/PCTransportManager.ts +1 -1
- package/src/room/RTCEngine.ts +266 -111
- package/src/room/Room.ts +149 -12
- package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +7 -7
- package/src/room/data-track/LocalDataTrack.ts +83 -10
- package/src/room/data-track/RemoteDataTrack.ts +7 -9
- package/src/room/data-track/depacketizer.ts +21 -12
- package/src/room/data-track/frame.ts +28 -2
- package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +58 -73
- package/src/room/data-track/incoming/IncomingDataTrackManager.ts +132 -80
- package/src/room/data-track/incoming/pipeline.ts +29 -24
- package/src/room/data-track/outgoing/OutgoingDataTrackManager.test.ts +225 -32
- package/src/room/data-track/outgoing/OutgoingDataTrackManager.ts +150 -75
- package/src/room/data-track/outgoing/errors.ts +36 -7
- package/src/room/data-track/outgoing/pipeline.ts +23 -17
- package/src/room/data-track/outgoing/types.ts +12 -3
- package/src/room/data-track/packet/extensions.ts +17 -22
- package/src/room/data-track/packet/index.test.ts +22 -33
- package/src/room/data-track/packetizer.test.ts +2 -2
- package/src/room/data-track/packetizer.ts +4 -4
- package/src/room/data-track/track-interfaces.ts +1 -1
- package/src/room/data-track/types.ts +21 -1
- package/src/room/events.ts +26 -1
- package/src/room/participant/LocalParticipant.ts +57 -6
- package/src/room/participant/RemoteParticipant.ts +25 -0
- package/src/room/utils.ts +4 -0
- package/src/utils/deferrable-map.ts +109 -0
- package/dist/src/room/data-track/e2ee.d.ts +0 -12
- package/dist/src/room/data-track/e2ee.d.ts.map +0 -1
- package/dist/ts4.2/room/data-track/e2ee.d.ts +0 -12
- package/src/room/data-track/e2ee.ts +0 -15
package/src/room/RTCEngine.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
DataChannelReceiveState,
|
|
9
9
|
DataPacket,
|
|
10
10
|
DataPacket_Kind,
|
|
11
|
+
DataTrackSubscriberHandles,
|
|
11
12
|
DisconnectReason,
|
|
12
13
|
EncryptedPacket,
|
|
13
14
|
EncryptedPacketPayload,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
LeaveRequest_Action,
|
|
18
19
|
MediaSectionsRequirement,
|
|
19
20
|
ParticipantInfo,
|
|
21
|
+
PublishDataTrackResponse,
|
|
20
22
|
ReconnectReason,
|
|
21
23
|
type ReconnectResponse,
|
|
22
24
|
RequestResponse,
|
|
@@ -24,6 +26,7 @@ import {
|
|
|
24
26
|
RoomMovedResponse,
|
|
25
27
|
RpcAck,
|
|
26
28
|
RpcResponse,
|
|
29
|
+
SessionDescription,
|
|
27
30
|
SignalTarget,
|
|
28
31
|
SpeakerInfo,
|
|
29
32
|
type StreamStateUpdate,
|
|
@@ -35,6 +38,7 @@ import {
|
|
|
35
38
|
type TrackPublishedResponse,
|
|
36
39
|
TrackUnpublishedResponse,
|
|
37
40
|
Transcription,
|
|
41
|
+
UnpublishDataTrackResponse,
|
|
38
42
|
UpdateSubscription,
|
|
39
43
|
type UserPacket,
|
|
40
44
|
} from '@livekit/protocol';
|
|
@@ -58,6 +62,7 @@ import PCTransport, { PCEvents } from './PCTransport';
|
|
|
58
62
|
import { PCTransportManager, PCTransportState } from './PCTransportManager';
|
|
59
63
|
import type { ReconnectContext, ReconnectPolicy } from './ReconnectPolicy';
|
|
60
64
|
import { DEFAULT_MAX_AGE_MS, type RegionUrlProvider } from './RegionUrlProvider';
|
|
65
|
+
import { DataTrackInfo } from './data-track/types';
|
|
61
66
|
import { roomConnectOptionDefaults } from './defaults';
|
|
62
67
|
import {
|
|
63
68
|
ConnectionError,
|
|
@@ -80,6 +85,7 @@ import type { TrackPublishOptions, VideoCodec } from './track/options';
|
|
|
80
85
|
import { getTrackPublicationInfo } from './track/utils';
|
|
81
86
|
import type { LoggerOptions } from './types';
|
|
82
87
|
import {
|
|
88
|
+
isCompressionStreamSupported,
|
|
83
89
|
isVideoCodec,
|
|
84
90
|
isVideoTrack,
|
|
85
91
|
isWeb,
|
|
@@ -91,11 +97,14 @@ import {
|
|
|
91
97
|
|
|
92
98
|
const lossyDataChannel = '_lossy';
|
|
93
99
|
const reliableDataChannel = '_reliable';
|
|
100
|
+
const dataTrackDataChannel = '_data_track';
|
|
94
101
|
const minReconnectWait = 2 * 1000;
|
|
95
102
|
const leaveReconnect = 'leave-reconnect';
|
|
96
103
|
const reliabeReceiveStateTTL = 30_000;
|
|
97
104
|
const lossyDataChannelBufferThresholdMin = 8 * 1024;
|
|
98
105
|
const lossyDataChannelBufferThresholdMax = 256 * 1024;
|
|
106
|
+
const initialMediaSectionsAudio = 3;
|
|
107
|
+
const initialMediaSectionsVideo = 3;
|
|
99
108
|
|
|
100
109
|
enum PCState {
|
|
101
110
|
New,
|
|
@@ -105,6 +114,12 @@ enum PCState {
|
|
|
105
114
|
Closed,
|
|
106
115
|
}
|
|
107
116
|
|
|
117
|
+
export enum DataChannelKind {
|
|
118
|
+
RELIABLE = DataPacket_Kind.RELIABLE,
|
|
119
|
+
LOSSY = DataPacket_Kind.LOSSY,
|
|
120
|
+
DATA_TRACK_LOSSY,
|
|
121
|
+
}
|
|
122
|
+
|
|
108
123
|
/** @internal */
|
|
109
124
|
export default class RTCEngine extends (EventEmitter as new () => TypedEventEmitter<EngineEventCallbacks>) {
|
|
110
125
|
client: SignalClient;
|
|
@@ -149,11 +164,16 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
149
164
|
|
|
150
165
|
private reliableDC?: RTCDataChannel;
|
|
151
166
|
|
|
152
|
-
private dcBufferStatus: Map<DataPacket_Kind, boolean>;
|
|
153
|
-
|
|
154
167
|
// @ts-ignore noUnusedLocals
|
|
155
168
|
private reliableDCSub?: RTCDataChannel;
|
|
156
169
|
|
|
170
|
+
private dataTrackDC?: RTCDataChannel;
|
|
171
|
+
|
|
172
|
+
// @ts-ignore noUnusedLocals
|
|
173
|
+
private dataTrackDCSub?: RTCDataChannel;
|
|
174
|
+
|
|
175
|
+
private dcBufferStatus: Map<DataChannelKind, boolean>;
|
|
176
|
+
|
|
157
177
|
private subscriberPrimary: boolean = false;
|
|
158
178
|
|
|
159
179
|
private pcState: PCState = PCState.New;
|
|
@@ -239,8 +259,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
239
259
|
this.closingLock = new Mutex();
|
|
240
260
|
this.dataProcessLock = new Mutex();
|
|
241
261
|
this.dcBufferStatus = new Map([
|
|
242
|
-
[
|
|
243
|
-
[
|
|
262
|
+
[DataChannelKind.RELIABLE, true],
|
|
263
|
+
[DataChannelKind.LOSSY, true],
|
|
264
|
+
[DataChannelKind.DATA_TRACK_LOSSY, true],
|
|
244
265
|
]);
|
|
245
266
|
|
|
246
267
|
this.client.onParticipantUpdate = (updates) =>
|
|
@@ -255,6 +276,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
255
276
|
this.client.onStreamStateUpdate = (update) => this.emit(EngineEvent.StreamStateChanged, update);
|
|
256
277
|
this.client.onRequestResponse = (response) =>
|
|
257
278
|
this.emit(EngineEvent.SignalRequestResponse, response);
|
|
279
|
+
this.client.onParticipantUpdate = (updates) =>
|
|
280
|
+
this.emit(EngineEvent.ParticipantUpdate, updates);
|
|
281
|
+
this.client.onJoined = (joinResponse) => this.emit(EngineEvent.Joined, joinResponse);
|
|
258
282
|
}
|
|
259
283
|
|
|
260
284
|
/** @internal */
|
|
@@ -284,20 +308,46 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
284
308
|
this.joinAttempts += 1;
|
|
285
309
|
|
|
286
310
|
this.setupSignalClientCallbacks();
|
|
287
|
-
|
|
311
|
+
let offerProto: SessionDescription | undefined;
|
|
312
|
+
if (!useV0Path && isCompressionStreamSupported()) {
|
|
313
|
+
if (!this.pcManager) {
|
|
314
|
+
await this.configure();
|
|
315
|
+
this.createDataChannels();
|
|
316
|
+
this.addMediaSections(initialMediaSectionsAudio, initialMediaSectionsVideo);
|
|
317
|
+
}
|
|
318
|
+
const offer = await this.pcManager?.publisher.createInitialOffer();
|
|
319
|
+
if (offer) {
|
|
320
|
+
offerProto = toProtoSessionDescription(offer.offer, offer.offerId);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (abortSignal?.aborted) {
|
|
324
|
+
throw ConnectionError.cancelled('Connection aborted');
|
|
325
|
+
}
|
|
326
|
+
const joinResponse = await this.client.join(
|
|
327
|
+
url,
|
|
328
|
+
token,
|
|
329
|
+
opts,
|
|
330
|
+
abortSignal,
|
|
331
|
+
useV0Path,
|
|
332
|
+
offerProto,
|
|
333
|
+
);
|
|
288
334
|
this._isClosed = false;
|
|
289
335
|
this.latestJoinResponse = joinResponse;
|
|
336
|
+
this.participantSid = joinResponse.participant?.sid;
|
|
290
337
|
|
|
291
338
|
this.subscriberPrimary = joinResponse.subscriberPrimary;
|
|
292
|
-
if (!
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
339
|
+
if (!useV0Path && isCompressionStreamSupported()) {
|
|
340
|
+
this.pcManager?.updateConfiguration(this.makeRTCConfiguration(joinResponse));
|
|
341
|
+
} else {
|
|
342
|
+
if (!this.pcManager) {
|
|
343
|
+
await this.configure(joinResponse, !useV0Path);
|
|
344
|
+
}
|
|
345
|
+
// create offer
|
|
346
|
+
if (!this.subscriberPrimary || joinResponse.fastPublish) {
|
|
347
|
+
this.negotiate().catch((err) => {
|
|
348
|
+
log.error(err, this.logContext);
|
|
349
|
+
});
|
|
350
|
+
}
|
|
301
351
|
}
|
|
302
352
|
|
|
303
353
|
this.registerOnLineListener();
|
|
@@ -362,11 +412,15 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
362
412
|
dcCleanup(this.lossyDCSub);
|
|
363
413
|
dcCleanup(this.reliableDC);
|
|
364
414
|
dcCleanup(this.reliableDCSub);
|
|
415
|
+
dcCleanup(this.dataTrackDC);
|
|
416
|
+
dcCleanup(this.dataTrackDCSub);
|
|
365
417
|
|
|
366
418
|
this.lossyDC = undefined;
|
|
367
419
|
this.lossyDCSub = undefined;
|
|
368
420
|
this.reliableDC = undefined;
|
|
369
421
|
this.reliableDCSub = undefined;
|
|
422
|
+
this.dataTrackDC = undefined;
|
|
423
|
+
this.dataTrackDCSub = undefined;
|
|
370
424
|
this.reliableMessageBuffer = new DataPacketBuffer();
|
|
371
425
|
this.reliableDataSequence = 1;
|
|
372
426
|
this.reliableReceivedState.clear();
|
|
@@ -452,25 +506,28 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
452
506
|
this.regionUrlProvider = provider;
|
|
453
507
|
}
|
|
454
508
|
|
|
455
|
-
private async configure(joinResponse
|
|
509
|
+
private async configure(joinResponse?: JoinResponse, useSinglePeerConnection?: boolean) {
|
|
456
510
|
// already configured
|
|
457
511
|
if (this.pcManager && this.pcManager.currentState !== PCTransportState.NEW) {
|
|
458
512
|
return;
|
|
459
513
|
}
|
|
460
514
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
rtcConfig
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
515
|
+
if (!joinResponse) {
|
|
516
|
+
const rtcConfig = this.makeRTCConfiguration();
|
|
517
|
+
this.pcManager = new PCTransportManager('publisher-only', this.loggerOptions, rtcConfig);
|
|
518
|
+
} else {
|
|
519
|
+
this.participantSid = joinResponse.participant?.sid;
|
|
520
|
+
const rtcConfig = this.makeRTCConfiguration(joinResponse);
|
|
521
|
+
this.pcManager = new PCTransportManager(
|
|
522
|
+
useSinglePeerConnection
|
|
523
|
+
? 'publisher-only'
|
|
524
|
+
: joinResponse.subscriberPrimary
|
|
525
|
+
? 'subscriber-primary'
|
|
526
|
+
: 'publisher-primary',
|
|
527
|
+
this.loggerOptions,
|
|
528
|
+
rtcConfig,
|
|
529
|
+
);
|
|
530
|
+
}
|
|
474
531
|
|
|
475
532
|
this.emit(EngineEvent.TransportsCreated, this.pcManager.publisher, this.pcManager.subscriber);
|
|
476
533
|
|
|
@@ -494,7 +551,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
494
551
|
const shouldEmit = this.pcState === PCState.New;
|
|
495
552
|
this.pcState = PCState.Connected;
|
|
496
553
|
if (shouldEmit) {
|
|
497
|
-
this.emit(EngineEvent.Connected,
|
|
554
|
+
this.emit(EngineEvent.Connected, this.latestJoinResponse!);
|
|
498
555
|
}
|
|
499
556
|
} else if (connectionState === PCTransportState.FAILED) {
|
|
500
557
|
// on Safari, PeerConnection will switch to 'disconnected' during renegotiation
|
|
@@ -529,10 +586,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
529
586
|
if (ev.streams.length === 0) return;
|
|
530
587
|
this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
|
|
531
588
|
};
|
|
532
|
-
|
|
533
|
-
if (!supportOptionalDatachannel(joinResponse.serverInfo?.protocol)) {
|
|
534
|
-
this.createDataChannels();
|
|
535
|
-
}
|
|
536
589
|
}
|
|
537
590
|
|
|
538
591
|
private setupSignalClientCallbacks() {
|
|
@@ -621,17 +674,22 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
621
674
|
};
|
|
622
675
|
|
|
623
676
|
this.client.onMediaSectionsRequirement = (requirement: MediaSectionsRequirement) => {
|
|
624
|
-
|
|
625
|
-
for (let i: number = 0; i < requirement.numAudios; i++) {
|
|
626
|
-
this.pcManager?.addPublisherTransceiverOfKind('audio', transceiverInit);
|
|
627
|
-
}
|
|
628
|
-
for (let i: number = 0; i < requirement.numVideos; i++) {
|
|
629
|
-
this.pcManager?.addPublisherTransceiverOfKind('video', transceiverInit);
|
|
630
|
-
}
|
|
631
|
-
|
|
677
|
+
this.addMediaSections(requirement.numAudios, requirement.numVideos);
|
|
632
678
|
this.negotiate();
|
|
633
679
|
};
|
|
634
680
|
|
|
681
|
+
this.client.onPublishDataTrackResponse = (event: PublishDataTrackResponse) => {
|
|
682
|
+
this.emit(EngineEvent.PublishDataTrackResponse, event);
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
this.client.onUnPublishDataTrackResponse = (event: UnpublishDataTrackResponse) => {
|
|
686
|
+
this.emit(EngineEvent.UnPublishDataTrackResponse, event);
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
this.client.onDataTrackSubscriberHandles = (event: DataTrackSubscriberHandles) => {
|
|
690
|
+
this.emit(EngineEvent.DataTrackSubscriberHandles, event);
|
|
691
|
+
};
|
|
692
|
+
|
|
635
693
|
this.client.onClose = () => {
|
|
636
694
|
this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
|
|
637
695
|
};
|
|
@@ -665,7 +723,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
665
723
|
};
|
|
666
724
|
}
|
|
667
725
|
|
|
668
|
-
private makeRTCConfiguration(
|
|
726
|
+
private makeRTCConfiguration(
|
|
727
|
+
serverResponse?: JoinResponse | ReconnectResponse,
|
|
728
|
+
): RTCConfiguration {
|
|
669
729
|
const rtcConfig = { ...this.rtcConfig };
|
|
670
730
|
|
|
671
731
|
if (this.signalOpts?.e2eeEnabled) {
|
|
@@ -675,6 +735,15 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
675
735
|
rtcConfig.encodedInsertableStreams = true;
|
|
676
736
|
}
|
|
677
737
|
|
|
738
|
+
// @ts-ignore
|
|
739
|
+
rtcConfig.sdpSemantics = 'unified-plan';
|
|
740
|
+
// @ts-ignore
|
|
741
|
+
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
|
742
|
+
|
|
743
|
+
if (!serverResponse) {
|
|
744
|
+
return rtcConfig;
|
|
745
|
+
}
|
|
746
|
+
|
|
678
747
|
// update ICE servers before creating PeerConnection
|
|
679
748
|
if (serverResponse.iceServers && !rtcConfig.iceServers) {
|
|
680
749
|
const rtcIceServers: RTCIceServer[] = [];
|
|
@@ -698,14 +767,19 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
698
767
|
rtcConfig.iceTransportPolicy = 'relay';
|
|
699
768
|
}
|
|
700
769
|
|
|
701
|
-
// @ts-ignore
|
|
702
|
-
rtcConfig.sdpSemantics = 'unified-plan';
|
|
703
|
-
// @ts-ignore
|
|
704
|
-
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
|
705
|
-
|
|
706
770
|
return rtcConfig;
|
|
707
771
|
}
|
|
708
772
|
|
|
773
|
+
private addMediaSections(numAudios: number, numVideos: number) {
|
|
774
|
+
const transceiverInit: RTCRtpTransceiverInit = { direction: 'recvonly' };
|
|
775
|
+
for (let i: number = 0; i < numAudios; i++) {
|
|
776
|
+
this.pcManager?.addPublisherTransceiverOfKind('audio', transceiverInit);
|
|
777
|
+
}
|
|
778
|
+
for (let i: number = 0; i < numVideos; i++) {
|
|
779
|
+
this.pcManager?.addPublisherTransceiverOfKind('video', transceiverInit);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
709
783
|
private createDataChannels() {
|
|
710
784
|
if (!this.pcManager) {
|
|
711
785
|
return;
|
|
@@ -720,6 +794,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
720
794
|
this.reliableDC.onmessage = null;
|
|
721
795
|
this.reliableDC.onerror = null;
|
|
722
796
|
}
|
|
797
|
+
if (this.dataTrackDC) {
|
|
798
|
+
this.dataTrackDC.onmessage = null;
|
|
799
|
+
this.dataTrackDC.onerror = null;
|
|
800
|
+
}
|
|
723
801
|
|
|
724
802
|
// create data channels
|
|
725
803
|
this.lossyDC = this.pcManager.createPublisherDataChannel(lossyDataChannel, {
|
|
@@ -729,29 +807,39 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
729
807
|
this.reliableDC = this.pcManager.createPublisherDataChannel(reliableDataChannel, {
|
|
730
808
|
ordered: true,
|
|
731
809
|
});
|
|
810
|
+
this.dataTrackDC = this.pcManager.createPublisherDataChannel(dataTrackDataChannel, {
|
|
811
|
+
ordered: false,
|
|
812
|
+
maxRetransmits: 0,
|
|
813
|
+
});
|
|
732
814
|
|
|
733
815
|
// also handle messages over the pub channel, for backwards compatibility
|
|
734
816
|
this.lossyDC.onmessage = this.handleDataMessage;
|
|
735
817
|
this.reliableDC.onmessage = this.handleDataMessage;
|
|
818
|
+
this.dataTrackDC.onmessage = this.handleDataTrackMessage;
|
|
736
819
|
|
|
737
820
|
// handle datachannel errors
|
|
738
821
|
this.lossyDC.onerror = this.handleDataError;
|
|
739
822
|
this.reliableDC.onerror = this.handleDataError;
|
|
823
|
+
this.dataTrackDC.onerror = this.handleDataError;
|
|
740
824
|
|
|
741
825
|
// set up dc buffer threshold, set to 64kB (otherwise 0 by default)
|
|
742
826
|
this.lossyDC.bufferedAmountLowThreshold = 65535;
|
|
743
827
|
this.reliableDC.bufferedAmountLowThreshold = 65535;
|
|
828
|
+
this.dataTrackDC.bufferedAmountLowThreshold = 65535;
|
|
744
829
|
|
|
745
830
|
// handle buffer amount low events
|
|
746
|
-
this.lossyDC.onbufferedamountlow = this.handleBufferedAmountLow;
|
|
747
|
-
this.reliableDC.onbufferedamountlow =
|
|
831
|
+
this.lossyDC.onbufferedamountlow = () => this.handleBufferedAmountLow(DataChannelKind.LOSSY);
|
|
832
|
+
this.reliableDC.onbufferedamountlow = () =>
|
|
833
|
+
this.handleBufferedAmountLow(DataChannelKind.RELIABLE);
|
|
834
|
+
this.dataTrackDC.onbufferedamountlow = () =>
|
|
835
|
+
this.handleBufferedAmountLow(DataChannelKind.DATA_TRACK_LOSSY);
|
|
748
836
|
|
|
749
837
|
this.cleanupLossyDataStats();
|
|
750
838
|
this.lossyDataStatInterval = setInterval(() => {
|
|
751
839
|
this.lossyDataStatByterate = this.lossyDataStatCurrentBytes;
|
|
752
840
|
this.lossyDataStatCurrentBytes = 0;
|
|
753
841
|
|
|
754
|
-
const dc = this.dataChannelForKind(
|
|
842
|
+
const dc = this.dataChannelForKind(DataChannelKind.LOSSY);
|
|
755
843
|
if (dc) {
|
|
756
844
|
// control buffered latency to ~100ms
|
|
757
845
|
const threshold = this.lossyDataStatByterate / 10;
|
|
@@ -767,15 +855,21 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
767
855
|
if (!channel) {
|
|
768
856
|
return;
|
|
769
857
|
}
|
|
858
|
+
let handler;
|
|
770
859
|
if (channel.label === reliableDataChannel) {
|
|
771
860
|
this.reliableDCSub = channel;
|
|
861
|
+
handler = this.handleDataMessage;
|
|
772
862
|
} else if (channel.label === lossyDataChannel) {
|
|
773
863
|
this.lossyDCSub = channel;
|
|
864
|
+
handler = this.handleDataMessage;
|
|
865
|
+
} else if (channel.label === dataTrackDataChannel) {
|
|
866
|
+
this.dataTrackDCSub = channel;
|
|
867
|
+
handler = this.handleDataTrackMessage;
|
|
774
868
|
} else {
|
|
775
869
|
return;
|
|
776
870
|
}
|
|
777
871
|
this.log.debug(`on data channel ${channel.id}, ${channel.label}`, this.logContext);
|
|
778
|
-
channel.onmessage =
|
|
872
|
+
channel.onmessage = handler;
|
|
779
873
|
};
|
|
780
874
|
|
|
781
875
|
private handleDataMessage = async (message: MessageEvent) => {
|
|
@@ -840,6 +934,21 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
840
934
|
}
|
|
841
935
|
};
|
|
842
936
|
|
|
937
|
+
private handleDataTrackMessage = async (message: MessageEvent) => {
|
|
938
|
+
// Decode / normalize into a common format
|
|
939
|
+
let buffer: ArrayBuffer | undefined;
|
|
940
|
+
if (message.data instanceof ArrayBuffer) {
|
|
941
|
+
buffer = message.data;
|
|
942
|
+
} else if (message.data instanceof Blob) {
|
|
943
|
+
buffer = await message.data.arrayBuffer();
|
|
944
|
+
} else {
|
|
945
|
+
this.log.error('unsupported data type', { ...this.logContext, data: message.data });
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
this.emit('dataTrackPacketReceived', new Uint8Array(buffer));
|
|
950
|
+
};
|
|
951
|
+
|
|
843
952
|
private handleDataError = (event: Event) => {
|
|
844
953
|
const channel = event.currentTarget as RTCDataChannel;
|
|
845
954
|
const channelKind = channel.maxRetransmits === 0 ? 'lossy' : 'reliable';
|
|
@@ -855,11 +964,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
855
964
|
}
|
|
856
965
|
};
|
|
857
966
|
|
|
858
|
-
private handleBufferedAmountLow = (
|
|
859
|
-
const channel = event.currentTarget as RTCDataChannel;
|
|
860
|
-
const channelKind =
|
|
861
|
-
channel.maxRetransmits === 0 ? DataPacket_Kind.LOSSY : DataPacket_Kind.RELIABLE;
|
|
862
|
-
|
|
967
|
+
private handleBufferedAmountLow = (channelKind: DataChannelKind) => {
|
|
863
968
|
this.updateAndEmitDCBufferStatus(channelKind);
|
|
864
969
|
};
|
|
865
970
|
|
|
@@ -1288,7 +1393,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1288
1393
|
},
|
|
1289
1394
|
});
|
|
1290
1395
|
|
|
1291
|
-
await this.sendDataPacket(packet,
|
|
1396
|
+
await this.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
1292
1397
|
}
|
|
1293
1398
|
|
|
1294
1399
|
/** @internal */
|
|
@@ -1303,11 +1408,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1303
1408
|
}),
|
|
1304
1409
|
},
|
|
1305
1410
|
});
|
|
1306
|
-
await this.sendDataPacket(packet,
|
|
1411
|
+
await this.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
1307
1412
|
}
|
|
1308
1413
|
|
|
1309
1414
|
/* @internal */
|
|
1310
|
-
async sendDataPacket(packet: DataPacket, kind:
|
|
1415
|
+
async sendDataPacket(packet: DataPacket, kind: DataChannelKind) {
|
|
1311
1416
|
// make sure we do have a data connection
|
|
1312
1417
|
await this.ensurePublisherConnected(kind);
|
|
1313
1418
|
|
|
@@ -1326,57 +1431,93 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1326
1431
|
}
|
|
1327
1432
|
}
|
|
1328
1433
|
|
|
1329
|
-
if (kind ===
|
|
1434
|
+
if (kind === DataChannelKind.RELIABLE) {
|
|
1330
1435
|
packet.sequence = this.reliableDataSequence;
|
|
1331
1436
|
this.reliableDataSequence += 1;
|
|
1332
1437
|
}
|
|
1333
1438
|
|
|
1334
1439
|
const msg = packet.toBinary();
|
|
1335
1440
|
|
|
1441
|
+
switch (kind) {
|
|
1442
|
+
case DataChannelKind.LOSSY:
|
|
1443
|
+
case DataChannelKind.DATA_TRACK_LOSSY:
|
|
1444
|
+
return this.sendLossyBytes(msg, kind);
|
|
1445
|
+
|
|
1446
|
+
case DataChannelKind.RELIABLE:
|
|
1447
|
+
const dc = this.dataChannelForKind(kind);
|
|
1448
|
+
if (dc) {
|
|
1449
|
+
await this.waitForBufferStatusLow(kind);
|
|
1450
|
+
this.reliableMessageBuffer.push({ data: msg, sequence: packet.sequence });
|
|
1451
|
+
|
|
1452
|
+
if (this.attemptingReconnect) {
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
dc.send(msg);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
this.updateAndEmitDCBufferStatus(kind);
|
|
1460
|
+
break;
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
/* @internal */
|
|
1465
|
+
async sendLossyBytes(
|
|
1466
|
+
bytes: Uint8Array,
|
|
1467
|
+
kind: Exclude<DataChannelKind, DataChannelKind.RELIABLE>,
|
|
1468
|
+
bufferStatusLowBehavior: 'drop' | 'wait' = 'drop',
|
|
1469
|
+
) {
|
|
1470
|
+
// make sure we do have a data connection
|
|
1471
|
+
await this.ensurePublisherConnected(kind);
|
|
1472
|
+
|
|
1336
1473
|
const dc = this.dataChannelForKind(kind);
|
|
1337
1474
|
if (dc) {
|
|
1338
|
-
if (kind
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
this.log.warn(
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
)
|
|
1350
|
-
|
|
1351
|
-
|
|
1475
|
+
if (!this.isBufferStatusLow(kind)) {
|
|
1476
|
+
// Depending on the exact circumstance that data is being sent, either drop or wait for the
|
|
1477
|
+
// buffer status to not be low before continuing.
|
|
1478
|
+
switch (bufferStatusLowBehavior) {
|
|
1479
|
+
case 'wait':
|
|
1480
|
+
await this.waitForBufferStatusLow(kind);
|
|
1481
|
+
break;
|
|
1482
|
+
case 'drop':
|
|
1483
|
+
// this.log.warn(`dropping lossy data channel message`, this.logContext);
|
|
1484
|
+
// Drop messages to reduce latency
|
|
1485
|
+
this.lossyDataDropCount += 1;
|
|
1486
|
+
if (this.lossyDataDropCount % 100 === 0) {
|
|
1487
|
+
this.log.warn(
|
|
1488
|
+
`dropping lossy data channel messages, total dropped: ${this.lossyDataDropCount}`,
|
|
1489
|
+
this.logContext,
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
return;
|
|
1352
1493
|
}
|
|
1353
|
-
this.lossyDataStatCurrentBytes += msg.byteLength;
|
|
1354
1494
|
}
|
|
1495
|
+
this.lossyDataStatCurrentBytes += bytes.byteLength;
|
|
1355
1496
|
|
|
1356
1497
|
if (this.attemptingReconnect) {
|
|
1357
1498
|
return;
|
|
1358
1499
|
}
|
|
1359
1500
|
|
|
1360
|
-
dc.send(
|
|
1501
|
+
dc.send(bytes);
|
|
1361
1502
|
}
|
|
1362
1503
|
|
|
1363
1504
|
this.updateAndEmitDCBufferStatus(kind);
|
|
1364
1505
|
}
|
|
1365
1506
|
|
|
1366
1507
|
private async resendReliableMessagesForResume(lastMessageSeq: number) {
|
|
1367
|
-
await this.ensurePublisherConnected(
|
|
1368
|
-
const dc = this.dataChannelForKind(
|
|
1508
|
+
await this.ensurePublisherConnected(DataChannelKind.RELIABLE);
|
|
1509
|
+
const dc = this.dataChannelForKind(DataChannelKind.RELIABLE);
|
|
1369
1510
|
if (dc) {
|
|
1370
1511
|
this.reliableMessageBuffer.popToSequence(lastMessageSeq);
|
|
1371
1512
|
this.reliableMessageBuffer.getAll().forEach((msg) => {
|
|
1372
1513
|
dc.send(msg.data);
|
|
1373
1514
|
});
|
|
1374
1515
|
}
|
|
1375
|
-
this.updateAndEmitDCBufferStatus(
|
|
1516
|
+
this.updateAndEmitDCBufferStatus(DataChannelKind.RELIABLE);
|
|
1376
1517
|
}
|
|
1377
1518
|
|
|
1378
|
-
private updateAndEmitDCBufferStatus = (kind:
|
|
1379
|
-
if (kind ===
|
|
1519
|
+
private updateAndEmitDCBufferStatus = (kind: DataChannelKind) => {
|
|
1520
|
+
if (kind === DataChannelKind.RELIABLE) {
|
|
1380
1521
|
const dc = this.dataChannelForKind(kind);
|
|
1381
1522
|
if (dc) {
|
|
1382
1523
|
this.reliableMessageBuffer.alignBufferedAmount(dc.bufferedAmount);
|
|
@@ -1390,14 +1531,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1390
1531
|
}
|
|
1391
1532
|
};
|
|
1392
1533
|
|
|
1393
|
-
private isBufferStatusLow = (kind:
|
|
1534
|
+
private isBufferStatusLow = (kind: DataChannelKind): boolean | undefined => {
|
|
1394
1535
|
const dc = this.dataChannelForKind(kind);
|
|
1395
1536
|
if (dc) {
|
|
1396
1537
|
return dc.bufferedAmount <= dc.bufferedAmountLowThreshold;
|
|
1397
1538
|
}
|
|
1398
1539
|
};
|
|
1399
1540
|
|
|
1400
|
-
waitForBufferStatusLow(kind:
|
|
1541
|
+
waitForBufferStatusLow(kind: DataChannelKind): TypedPromise<void, UnexpectedConnectionState> {
|
|
1401
1542
|
return new TypedPromise(async (resolve, reject) => {
|
|
1402
1543
|
if (this.isBufferStatusLow(kind)) {
|
|
1403
1544
|
resolve();
|
|
@@ -1417,7 +1558,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1417
1558
|
* @internal
|
|
1418
1559
|
*/
|
|
1419
1560
|
async ensureDataTransportConnected(
|
|
1420
|
-
kind:
|
|
1561
|
+
kind: DataChannelKind,
|
|
1421
1562
|
subscriber: boolean = this.subscriberPrimary,
|
|
1422
1563
|
) {
|
|
1423
1564
|
if (!this.pcManager) {
|
|
@@ -1472,7 +1613,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1472
1613
|
);
|
|
1473
1614
|
}
|
|
1474
1615
|
|
|
1475
|
-
private async ensurePublisherConnected(kind:
|
|
1616
|
+
private async ensurePublisherConnected(kind: DataChannelKind) {
|
|
1476
1617
|
if (!this.publisherConnectionPromise) {
|
|
1477
1618
|
this.publisherConnectionPromise = this.ensureDataTransportConnected(kind, false);
|
|
1478
1619
|
}
|
|
@@ -1513,7 +1654,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1513
1654
|
if (
|
|
1514
1655
|
this.pcManager.publisher.getTransceivers().length == 0 &&
|
|
1515
1656
|
!this.lossyDC &&
|
|
1516
|
-
!this.reliableDC
|
|
1657
|
+
!this.reliableDC &&
|
|
1658
|
+
!this.dataTrackDC
|
|
1517
1659
|
) {
|
|
1518
1660
|
this.createDataChannels();
|
|
1519
1661
|
}
|
|
@@ -1573,26 +1715,35 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1573
1715
|
});
|
|
1574
1716
|
}
|
|
1575
1717
|
|
|
1576
|
-
dataChannelForKind(kind:
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1718
|
+
dataChannelForKind(kind: DataChannelKind, sub?: boolean): RTCDataChannel | undefined {
|
|
1719
|
+
switch (kind) {
|
|
1720
|
+
case DataChannelKind.RELIABLE:
|
|
1721
|
+
if (!sub) {
|
|
1722
|
+
return this.reliableDC;
|
|
1723
|
+
} else {
|
|
1724
|
+
return this.reliableDCSub;
|
|
1725
|
+
}
|
|
1726
|
+
case DataChannelKind.LOSSY:
|
|
1727
|
+
if (!sub) {
|
|
1728
|
+
return this.lossyDC;
|
|
1729
|
+
} else {
|
|
1730
|
+
return this.lossyDCSub;
|
|
1731
|
+
}
|
|
1732
|
+
case DataChannelKind.DATA_TRACK_LOSSY:
|
|
1733
|
+
if (!sub) {
|
|
1734
|
+
return this.dataTrackDC;
|
|
1735
|
+
} else {
|
|
1736
|
+
return this.dataTrackDCSub;
|
|
1737
|
+
}
|
|
1591
1738
|
}
|
|
1592
1739
|
}
|
|
1593
1740
|
|
|
1594
1741
|
/** @internal */
|
|
1595
|
-
sendSyncState(
|
|
1742
|
+
sendSyncState(
|
|
1743
|
+
remoteTracks: RemoteTrackPublication[],
|
|
1744
|
+
localTracks: LocalTrackPublication[],
|
|
1745
|
+
localDataTrackInfos: Array<DataTrackInfo>,
|
|
1746
|
+
) {
|
|
1596
1747
|
if (!this.pcManager) {
|
|
1597
1748
|
this.log.warn('sync state cannot be sent without peer connection setup', this.logContext);
|
|
1598
1749
|
return;
|
|
@@ -1664,6 +1815,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1664
1815
|
lastSeq: seq,
|
|
1665
1816
|
});
|
|
1666
1817
|
}),
|
|
1818
|
+
publishDataTracks: localDataTrackInfos.map((info) => {
|
|
1819
|
+
return new PublishDataTrackResponse({ info: DataTrackInfo.toProtobuf(info) });
|
|
1820
|
+
}),
|
|
1667
1821
|
}),
|
|
1668
1822
|
);
|
|
1669
1823
|
}
|
|
@@ -1687,10 +1841,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1687
1841
|
);
|
|
1688
1842
|
}
|
|
1689
1843
|
};
|
|
1690
|
-
getInfo(this.dataChannelForKind(
|
|
1691
|
-
getInfo(this.dataChannelForKind(
|
|
1692
|
-
getInfo(this.dataChannelForKind(
|
|
1693
|
-
getInfo(this.dataChannelForKind(
|
|
1844
|
+
getInfo(this.dataChannelForKind(DataChannelKind.LOSSY), SignalTarget.PUBLISHER);
|
|
1845
|
+
getInfo(this.dataChannelForKind(DataChannelKind.RELIABLE), SignalTarget.PUBLISHER);
|
|
1846
|
+
getInfo(this.dataChannelForKind(DataChannelKind.LOSSY, true), SignalTarget.SUBSCRIBER);
|
|
1847
|
+
getInfo(this.dataChannelForKind(DataChannelKind.RELIABLE, true), SignalTarget.SUBSCRIBER);
|
|
1694
1848
|
return infos;
|
|
1695
1849
|
}
|
|
1696
1850
|
|
|
@@ -1797,7 +1951,7 @@ export type EngineEventCallbacks = {
|
|
|
1797
1951
|
/** @internal */
|
|
1798
1952
|
trackSenderAdded: (track: Track, sender: RTCRtpSender) => void;
|
|
1799
1953
|
rtpVideoMapUpdate: (rtpMap: Map<number, VideoCodec>) => void;
|
|
1800
|
-
dcBufferStatusChanged: (isLow: boolean, kind:
|
|
1954
|
+
dcBufferStatusChanged: (isLow: boolean, kind: DataChannelKind) => void;
|
|
1801
1955
|
participantUpdate: (infos: ParticipantInfo[]) => void;
|
|
1802
1956
|
roomUpdate: (room: RoomModel) => void;
|
|
1803
1957
|
roomMoved: (room: RoomMovedResponse) => void;
|
|
@@ -1813,12 +1967,13 @@ export type EngineEventCallbacks = {
|
|
|
1813
1967
|
offline: () => void;
|
|
1814
1968
|
signalRequestResponse: (response: RequestResponse) => void;
|
|
1815
1969
|
signalConnected: (joinResp: JoinResponse) => void;
|
|
1970
|
+
publishDataTrackResponse: (event: PublishDataTrackResponse) => void;
|
|
1971
|
+
unPublishDataTrackResponse: (event: UnpublishDataTrackResponse) => void;
|
|
1972
|
+
dataTrackSubscriberHandles: (event: DataTrackSubscriberHandles) => void;
|
|
1973
|
+
dataTrackPacketReceived: (packet: Uint8Array) => void;
|
|
1974
|
+
joined: (joinResponse: JoinResponse) => void;
|
|
1816
1975
|
};
|
|
1817
1976
|
|
|
1818
|
-
function supportOptionalDatachannel(protocol: number | undefined): boolean {
|
|
1819
|
-
return protocol !== undefined && protocol > 13;
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
1977
|
function applyUserDataCompat(newObj: DataPacket, oldObj: UserPacket) {
|
|
1823
1978
|
const participantIdentity = newObj.participantIdentity
|
|
1824
1979
|
? newObj.participantIdentity
|