livekit-client 2.17.3 → 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 +7823 -5772
- 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 +27 -9
- 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 +48 -0
- package/dist/src/room/data-track/LocalDataTrack.d.ts.map +1 -0
- package/dist/src/room/data-track/RemoteDataTrack.d.ts +46 -0
- package/dist/src/room/data-track/RemoteDataTrack.d.ts.map +1 -0
- package/dist/src/room/data-track/depacketizer.d.ts +6 -6
- 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/handle.d.ts +2 -2
- package/dist/src/room/data-track/handle.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +104 -0
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -0
- package/dist/src/room/data-track/incoming/errors.d.ts +24 -0
- package/dist/src/room/data-track/incoming/errors.d.ts.map +1 -0
- package/dist/src/room/data-track/incoming/pipeline.d.ts +38 -0
- package/dist/src/room/data-track/incoming/pipeline.d.ts.map +1 -0
- package/dist/src/room/data-track/incoming/types.d.ts +20 -0
- package/dist/src/room/data-track/incoming/types.d.ts.map +1 -0
- package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +63 -28
- package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/errors.d.ts +20 -10
- package/dist/src/room/data-track/outgoing/errors.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/pipeline.d.ts +9 -8
- package/dist/src/room/data-track/outgoing/pipeline.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/types.d.ts +16 -7
- package/dist/src/room/data-track/outgoing/types.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/errors.d.ts +2 -4
- package/dist/src/room/data-track/packet/errors.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/extensions.d.ts +4 -4
- package/dist/src/room/data-track/packet/extensions.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/index.d.ts +5 -5
- package/dist/src/room/data-track/packet/index.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/serializable.d.ts +4 -4
- package/dist/src/room/data-track/packet/serializable.d.ts.map +1 -1
- package/dist/src/room/data-track/packetizer.d.ts +6 -6
- package/dist/src/room/data-track/packetizer.d.ts.map +1 -1
- package/dist/src/room/data-track/track-interfaces.d.ts +23 -0
- package/dist/src/room/data-track/track-interfaces.d.ts.map +1 -0
- package/dist/src/room/data-track/types.d.ts +15 -0
- package/dist/src/room/data-track/types.d.ts.map +1 -0
- 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 +14 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/token-source/TokenSource.d.ts +1 -1
- package/dist/src/room/token-source/TokenSource.d.ts.map +1 -1
- package/dist/src/room/token-source/types.d.ts +1 -0
- package/dist/src/room/token-source/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +2 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/utils/abort-signal-polyfill.d.ts +13 -0
- package/dist/src/utils/abort-signal-polyfill.d.ts.map +1 -0
- package/dist/src/utils/deferrable-map.d.ts +32 -0
- package/dist/src/utils/deferrable-map.d.ts.map +1 -0
- package/dist/src/utils/subscribeToEvents.d.ts +3 -0
- package/dist/src/utils/subscribeToEvents.d.ts.map +1 -1
- 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 +27 -9
- package/dist/ts4.2/room/Room.d.ts +13 -3
- package/dist/ts4.2/room/data-track/LocalDataTrack.d.ts +48 -0
- package/dist/ts4.2/room/data-track/RemoteDataTrack.d.ts +46 -0
- package/dist/ts4.2/room/data-track/depacketizer.d.ts +6 -6
- package/dist/ts4.2/room/data-track/frame.d.ts +14 -0
- package/dist/ts4.2/room/data-track/handle.d.ts +2 -2
- package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +110 -0
- package/dist/ts4.2/room/data-track/incoming/errors.d.ts +24 -0
- package/dist/ts4.2/room/data-track/incoming/pipeline.d.ts +38 -0
- package/dist/ts4.2/room/data-track/incoming/types.d.ts +20 -0
- package/dist/ts4.2/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +63 -29
- package/dist/ts4.2/room/data-track/outgoing/errors.d.ts +20 -10
- package/dist/ts4.2/room/data-track/outgoing/pipeline.d.ts +9 -8
- package/dist/ts4.2/room/data-track/outgoing/types.d.ts +16 -7
- package/dist/ts4.2/room/data-track/packet/errors.d.ts +2 -4
- package/dist/ts4.2/room/data-track/packet/extensions.d.ts +4 -4
- package/dist/ts4.2/room/data-track/packet/index.d.ts +5 -6
- package/dist/ts4.2/room/data-track/packet/serializable.d.ts +4 -4
- package/dist/ts4.2/room/data-track/packetizer.d.ts +6 -6
- package/dist/ts4.2/room/data-track/track-interfaces.d.ts +23 -0
- package/dist/ts4.2/room/data-track/types.d.ts +15 -0
- 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 +14 -1
- package/dist/ts4.2/room/token-source/TokenSource.d.ts +1 -1
- package/dist/ts4.2/room/token-source/types.d.ts +1 -0
- package/dist/ts4.2/room/utils.d.ts +2 -1
- package/dist/ts4.2/utils/abort-signal-polyfill.d.ts +13 -0
- package/dist/ts4.2/utils/deferrable-map.d.ts +32 -0
- package/dist/ts4.2/utils/subscribeToEvents.d.ts +3 -0
- package/package.json +4 -2
- 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 +274 -112
- package/src/room/Room.ts +152 -15
- package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +9 -9
- package/src/room/data-track/LocalDataTrack.ts +126 -0
- package/src/room/data-track/RemoteDataTrack.ts +80 -0
- package/src/room/data-track/depacketizer.ts +23 -26
- package/src/room/data-track/frame.ts +28 -2
- package/src/room/data-track/handle.ts +2 -8
- package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +555 -0
- package/src/room/data-track/incoming/IncomingDataTrackManager.ts +589 -0
- package/src/room/data-track/incoming/errors.ts +57 -0
- package/src/room/data-track/incoming/pipeline.ts +121 -0
- package/src/room/data-track/incoming/types.ts +22 -0
- package/src/room/data-track/outgoing/OutgoingDataTrackManager.test.ts +240 -27
- package/src/room/data-track/outgoing/OutgoingDataTrackManager.ts +165 -84
- package/src/room/data-track/outgoing/errors.ts +40 -11
- package/src/room/data-track/outgoing/pipeline.ts +25 -23
- package/src/room/data-track/outgoing/types.ts +14 -6
- package/src/room/data-track/packet/errors.ts +2 -14
- package/src/room/data-track/packet/extensions.ts +21 -26
- package/src/room/data-track/packet/index.test.ts +22 -33
- package/src/room/data-track/packet/index.ts +4 -6
- package/src/room/data-track/packet/serializable.ts +4 -4
- package/src/room/data-track/packetizer.test.ts +2 -2
- package/src/room/data-track/packetizer.ts +7 -10
- package/src/room/data-track/track-interfaces.ts +53 -0
- package/src/room/data-track/types.ts +31 -0
- package/src/room/events.ts +26 -1
- package/src/room/participant/LocalParticipant.ts +57 -6
- package/src/room/participant/RemoteParticipant.ts +26 -1
- package/src/room/token-source/TokenSource.ts +8 -2
- package/src/room/token-source/types.ts +4 -0
- package/src/room/utils.ts +5 -1
- package/src/utils/abort-signal-polyfill.ts +63 -0
- package/src/utils/deferrable-map.ts +109 -0
- package/src/utils/subscribeToEvents.ts +18 -1
- 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/src/room/data-track/track.d.ts +0 -30
- package/dist/src/room/data-track/track.d.ts.map +0 -1
- package/dist/src/utils/throws.d.ts +0 -36
- package/dist/src/utils/throws.d.ts.map +0 -1
- package/dist/ts4.2/room/data-track/e2ee.d.ts +0 -12
- package/dist/ts4.2/room/data-track/track.d.ts +0 -30
- package/dist/ts4.2/utils/throws.d.ts +0 -39
- package/src/room/data-track/e2ee.ts +0 -14
- package/src/room/data-track/track.ts +0 -50
- package/src/utils/throws.ts +0 -42
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;
|
|
@@ -134,6 +149,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
134
149
|
return this._isClosed;
|
|
135
150
|
}
|
|
136
151
|
|
|
152
|
+
get isNewlyCreated() {
|
|
153
|
+
return this._isNewlyCreated;
|
|
154
|
+
}
|
|
155
|
+
|
|
137
156
|
get pendingReconnect() {
|
|
138
157
|
return !!this.reconnectTimeout;
|
|
139
158
|
}
|
|
@@ -145,17 +164,24 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
145
164
|
|
|
146
165
|
private reliableDC?: RTCDataChannel;
|
|
147
166
|
|
|
148
|
-
private dcBufferStatus: Map<DataPacket_Kind, boolean>;
|
|
149
|
-
|
|
150
167
|
// @ts-ignore noUnusedLocals
|
|
151
168
|
private reliableDCSub?: RTCDataChannel;
|
|
152
169
|
|
|
170
|
+
private dataTrackDC?: RTCDataChannel;
|
|
171
|
+
|
|
172
|
+
// @ts-ignore noUnusedLocals
|
|
173
|
+
private dataTrackDCSub?: RTCDataChannel;
|
|
174
|
+
|
|
175
|
+
private dcBufferStatus: Map<DataChannelKind, boolean>;
|
|
176
|
+
|
|
153
177
|
private subscriberPrimary: boolean = false;
|
|
154
178
|
|
|
155
179
|
private pcState: PCState = PCState.New;
|
|
156
180
|
|
|
157
181
|
private _isClosed: boolean = true;
|
|
158
182
|
|
|
183
|
+
private _isNewlyCreated: boolean = true;
|
|
184
|
+
|
|
159
185
|
private pendingTrackResolvers: {
|
|
160
186
|
[key: string]: { resolve: (info: TrackInfo) => void; reject: () => void };
|
|
161
187
|
} = {};
|
|
@@ -233,8 +259,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
233
259
|
this.closingLock = new Mutex();
|
|
234
260
|
this.dataProcessLock = new Mutex();
|
|
235
261
|
this.dcBufferStatus = new Map([
|
|
236
|
-
[
|
|
237
|
-
[
|
|
262
|
+
[DataChannelKind.RELIABLE, true],
|
|
263
|
+
[DataChannelKind.LOSSY, true],
|
|
264
|
+
[DataChannelKind.DATA_TRACK_LOSSY, true],
|
|
238
265
|
]);
|
|
239
266
|
|
|
240
267
|
this.client.onParticipantUpdate = (updates) =>
|
|
@@ -249,6 +276,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
249
276
|
this.client.onStreamStateUpdate = (update) => this.emit(EngineEvent.StreamStateChanged, update);
|
|
250
277
|
this.client.onRequestResponse = (response) =>
|
|
251
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);
|
|
252
282
|
}
|
|
253
283
|
|
|
254
284
|
/** @internal */
|
|
@@ -257,7 +287,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
257
287
|
room: this.latestJoinResponse?.room?.name,
|
|
258
288
|
roomID: this.latestJoinResponse?.room?.sid,
|
|
259
289
|
participant: this.latestJoinResponse?.participant?.identity,
|
|
260
|
-
|
|
290
|
+
participantID: this.participantSid,
|
|
261
291
|
};
|
|
262
292
|
}
|
|
263
293
|
|
|
@@ -269,6 +299,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
269
299
|
/** setting this to true results in dual peer connection mode being used */
|
|
270
300
|
useV0Path: boolean = false,
|
|
271
301
|
): Promise<JoinResponse> {
|
|
302
|
+
this._isNewlyCreated = false;
|
|
272
303
|
this.url = url;
|
|
273
304
|
this.token = token;
|
|
274
305
|
this.signalOpts = opts;
|
|
@@ -277,20 +308,46 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
277
308
|
this.joinAttempts += 1;
|
|
278
309
|
|
|
279
310
|
this.setupSignalClientCallbacks();
|
|
280
|
-
|
|
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
|
+
);
|
|
281
334
|
this._isClosed = false;
|
|
282
335
|
this.latestJoinResponse = joinResponse;
|
|
336
|
+
this.participantSid = joinResponse.participant?.sid;
|
|
283
337
|
|
|
284
338
|
this.subscriberPrimary = joinResponse.subscriberPrimary;
|
|
285
|
-
if (!
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
+
}
|
|
294
351
|
}
|
|
295
352
|
|
|
296
353
|
this.registerOnLineListener();
|
|
@@ -355,11 +412,15 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
355
412
|
dcCleanup(this.lossyDCSub);
|
|
356
413
|
dcCleanup(this.reliableDC);
|
|
357
414
|
dcCleanup(this.reliableDCSub);
|
|
415
|
+
dcCleanup(this.dataTrackDC);
|
|
416
|
+
dcCleanup(this.dataTrackDCSub);
|
|
358
417
|
|
|
359
418
|
this.lossyDC = undefined;
|
|
360
419
|
this.lossyDCSub = undefined;
|
|
361
420
|
this.reliableDC = undefined;
|
|
362
421
|
this.reliableDCSub = undefined;
|
|
422
|
+
this.dataTrackDC = undefined;
|
|
423
|
+
this.dataTrackDCSub = undefined;
|
|
363
424
|
this.reliableMessageBuffer = new DataPacketBuffer();
|
|
364
425
|
this.reliableDataSequence = 1;
|
|
365
426
|
this.reliableReceivedState.clear();
|
|
@@ -445,25 +506,28 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
445
506
|
this.regionUrlProvider = provider;
|
|
446
507
|
}
|
|
447
508
|
|
|
448
|
-
private async configure(joinResponse
|
|
509
|
+
private async configure(joinResponse?: JoinResponse, useSinglePeerConnection?: boolean) {
|
|
449
510
|
// already configured
|
|
450
511
|
if (this.pcManager && this.pcManager.currentState !== PCTransportState.NEW) {
|
|
451
512
|
return;
|
|
452
513
|
}
|
|
453
514
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
rtcConfig
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
+
}
|
|
467
531
|
|
|
468
532
|
this.emit(EngineEvent.TransportsCreated, this.pcManager.publisher, this.pcManager.subscriber);
|
|
469
533
|
|
|
@@ -487,7 +551,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
487
551
|
const shouldEmit = this.pcState === PCState.New;
|
|
488
552
|
this.pcState = PCState.Connected;
|
|
489
553
|
if (shouldEmit) {
|
|
490
|
-
this.emit(EngineEvent.Connected,
|
|
554
|
+
this.emit(EngineEvent.Connected, this.latestJoinResponse!);
|
|
491
555
|
}
|
|
492
556
|
} else if (connectionState === PCTransportState.FAILED) {
|
|
493
557
|
// on Safari, PeerConnection will switch to 'disconnected' during renegotiation
|
|
@@ -522,10 +586,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
522
586
|
if (ev.streams.length === 0) return;
|
|
523
587
|
this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
|
|
524
588
|
};
|
|
525
|
-
|
|
526
|
-
if (!supportOptionalDatachannel(joinResponse.serverInfo?.protocol)) {
|
|
527
|
-
this.createDataChannels();
|
|
528
|
-
}
|
|
529
589
|
}
|
|
530
590
|
|
|
531
591
|
private setupSignalClientCallbacks() {
|
|
@@ -614,17 +674,22 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
614
674
|
};
|
|
615
675
|
|
|
616
676
|
this.client.onMediaSectionsRequirement = (requirement: MediaSectionsRequirement) => {
|
|
617
|
-
|
|
618
|
-
for (let i: number = 0; i < requirement.numAudios; i++) {
|
|
619
|
-
this.pcManager?.addPublisherTransceiverOfKind('audio', transceiverInit);
|
|
620
|
-
}
|
|
621
|
-
for (let i: number = 0; i < requirement.numVideos; i++) {
|
|
622
|
-
this.pcManager?.addPublisherTransceiverOfKind('video', transceiverInit);
|
|
623
|
-
}
|
|
624
|
-
|
|
677
|
+
this.addMediaSections(requirement.numAudios, requirement.numVideos);
|
|
625
678
|
this.negotiate();
|
|
626
679
|
};
|
|
627
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
|
+
|
|
628
693
|
this.client.onClose = () => {
|
|
629
694
|
this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
|
|
630
695
|
};
|
|
@@ -658,7 +723,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
658
723
|
};
|
|
659
724
|
}
|
|
660
725
|
|
|
661
|
-
private makeRTCConfiguration(
|
|
726
|
+
private makeRTCConfiguration(
|
|
727
|
+
serverResponse?: JoinResponse | ReconnectResponse,
|
|
728
|
+
): RTCConfiguration {
|
|
662
729
|
const rtcConfig = { ...this.rtcConfig };
|
|
663
730
|
|
|
664
731
|
if (this.signalOpts?.e2eeEnabled) {
|
|
@@ -668,6 +735,15 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
668
735
|
rtcConfig.encodedInsertableStreams = true;
|
|
669
736
|
}
|
|
670
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
|
+
|
|
671
747
|
// update ICE servers before creating PeerConnection
|
|
672
748
|
if (serverResponse.iceServers && !rtcConfig.iceServers) {
|
|
673
749
|
const rtcIceServers: RTCIceServer[] = [];
|
|
@@ -691,14 +767,19 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
691
767
|
rtcConfig.iceTransportPolicy = 'relay';
|
|
692
768
|
}
|
|
693
769
|
|
|
694
|
-
// @ts-ignore
|
|
695
|
-
rtcConfig.sdpSemantics = 'unified-plan';
|
|
696
|
-
// @ts-ignore
|
|
697
|
-
rtcConfig.continualGatheringPolicy = 'gather_continually';
|
|
698
|
-
|
|
699
770
|
return rtcConfig;
|
|
700
771
|
}
|
|
701
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
|
+
|
|
702
783
|
private createDataChannels() {
|
|
703
784
|
if (!this.pcManager) {
|
|
704
785
|
return;
|
|
@@ -713,6 +794,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
713
794
|
this.reliableDC.onmessage = null;
|
|
714
795
|
this.reliableDC.onerror = null;
|
|
715
796
|
}
|
|
797
|
+
if (this.dataTrackDC) {
|
|
798
|
+
this.dataTrackDC.onmessage = null;
|
|
799
|
+
this.dataTrackDC.onerror = null;
|
|
800
|
+
}
|
|
716
801
|
|
|
717
802
|
// create data channels
|
|
718
803
|
this.lossyDC = this.pcManager.createPublisherDataChannel(lossyDataChannel, {
|
|
@@ -722,29 +807,39 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
722
807
|
this.reliableDC = this.pcManager.createPublisherDataChannel(reliableDataChannel, {
|
|
723
808
|
ordered: true,
|
|
724
809
|
});
|
|
810
|
+
this.dataTrackDC = this.pcManager.createPublisherDataChannel(dataTrackDataChannel, {
|
|
811
|
+
ordered: false,
|
|
812
|
+
maxRetransmits: 0,
|
|
813
|
+
});
|
|
725
814
|
|
|
726
815
|
// also handle messages over the pub channel, for backwards compatibility
|
|
727
816
|
this.lossyDC.onmessage = this.handleDataMessage;
|
|
728
817
|
this.reliableDC.onmessage = this.handleDataMessage;
|
|
818
|
+
this.dataTrackDC.onmessage = this.handleDataTrackMessage;
|
|
729
819
|
|
|
730
820
|
// handle datachannel errors
|
|
731
821
|
this.lossyDC.onerror = this.handleDataError;
|
|
732
822
|
this.reliableDC.onerror = this.handleDataError;
|
|
823
|
+
this.dataTrackDC.onerror = this.handleDataError;
|
|
733
824
|
|
|
734
825
|
// set up dc buffer threshold, set to 64kB (otherwise 0 by default)
|
|
735
826
|
this.lossyDC.bufferedAmountLowThreshold = 65535;
|
|
736
827
|
this.reliableDC.bufferedAmountLowThreshold = 65535;
|
|
828
|
+
this.dataTrackDC.bufferedAmountLowThreshold = 65535;
|
|
737
829
|
|
|
738
830
|
// handle buffer amount low events
|
|
739
|
-
this.lossyDC.onbufferedamountlow = this.handleBufferedAmountLow;
|
|
740
|
-
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);
|
|
741
836
|
|
|
742
837
|
this.cleanupLossyDataStats();
|
|
743
838
|
this.lossyDataStatInterval = setInterval(() => {
|
|
744
839
|
this.lossyDataStatByterate = this.lossyDataStatCurrentBytes;
|
|
745
840
|
this.lossyDataStatCurrentBytes = 0;
|
|
746
841
|
|
|
747
|
-
const dc = this.dataChannelForKind(
|
|
842
|
+
const dc = this.dataChannelForKind(DataChannelKind.LOSSY);
|
|
748
843
|
if (dc) {
|
|
749
844
|
// control buffered latency to ~100ms
|
|
750
845
|
const threshold = this.lossyDataStatByterate / 10;
|
|
@@ -760,15 +855,21 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
760
855
|
if (!channel) {
|
|
761
856
|
return;
|
|
762
857
|
}
|
|
858
|
+
let handler;
|
|
763
859
|
if (channel.label === reliableDataChannel) {
|
|
764
860
|
this.reliableDCSub = channel;
|
|
861
|
+
handler = this.handleDataMessage;
|
|
765
862
|
} else if (channel.label === lossyDataChannel) {
|
|
766
863
|
this.lossyDCSub = channel;
|
|
864
|
+
handler = this.handleDataMessage;
|
|
865
|
+
} else if (channel.label === dataTrackDataChannel) {
|
|
866
|
+
this.dataTrackDCSub = channel;
|
|
867
|
+
handler = this.handleDataTrackMessage;
|
|
767
868
|
} else {
|
|
768
869
|
return;
|
|
769
870
|
}
|
|
770
871
|
this.log.debug(`on data channel ${channel.id}, ${channel.label}`, this.logContext);
|
|
771
|
-
channel.onmessage =
|
|
872
|
+
channel.onmessage = handler;
|
|
772
873
|
};
|
|
773
874
|
|
|
774
875
|
private handleDataMessage = async (message: MessageEvent) => {
|
|
@@ -833,6 +934,21 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
833
934
|
}
|
|
834
935
|
};
|
|
835
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
|
+
|
|
836
952
|
private handleDataError = (event: Event) => {
|
|
837
953
|
const channel = event.currentTarget as RTCDataChannel;
|
|
838
954
|
const channelKind = channel.maxRetransmits === 0 ? 'lossy' : 'reliable';
|
|
@@ -848,11 +964,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
848
964
|
}
|
|
849
965
|
};
|
|
850
966
|
|
|
851
|
-
private handleBufferedAmountLow = (
|
|
852
|
-
const channel = event.currentTarget as RTCDataChannel;
|
|
853
|
-
const channelKind =
|
|
854
|
-
channel.maxRetransmits === 0 ? DataPacket_Kind.LOSSY : DataPacket_Kind.RELIABLE;
|
|
855
|
-
|
|
967
|
+
private handleBufferedAmountLow = (channelKind: DataChannelKind) => {
|
|
856
968
|
this.updateAndEmitDCBufferStatus(channelKind);
|
|
857
969
|
};
|
|
858
970
|
|
|
@@ -1281,7 +1393,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1281
1393
|
},
|
|
1282
1394
|
});
|
|
1283
1395
|
|
|
1284
|
-
await this.sendDataPacket(packet,
|
|
1396
|
+
await this.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
1285
1397
|
}
|
|
1286
1398
|
|
|
1287
1399
|
/** @internal */
|
|
@@ -1296,11 +1408,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1296
1408
|
}),
|
|
1297
1409
|
},
|
|
1298
1410
|
});
|
|
1299
|
-
await this.sendDataPacket(packet,
|
|
1411
|
+
await this.sendDataPacket(packet, DataChannelKind.RELIABLE);
|
|
1300
1412
|
}
|
|
1301
1413
|
|
|
1302
1414
|
/* @internal */
|
|
1303
|
-
async sendDataPacket(packet: DataPacket, kind:
|
|
1415
|
+
async sendDataPacket(packet: DataPacket, kind: DataChannelKind) {
|
|
1304
1416
|
// make sure we do have a data connection
|
|
1305
1417
|
await this.ensurePublisherConnected(kind);
|
|
1306
1418
|
|
|
@@ -1319,57 +1431,93 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1319
1431
|
}
|
|
1320
1432
|
}
|
|
1321
1433
|
|
|
1322
|
-
if (kind ===
|
|
1434
|
+
if (kind === DataChannelKind.RELIABLE) {
|
|
1323
1435
|
packet.sequence = this.reliableDataSequence;
|
|
1324
1436
|
this.reliableDataSequence += 1;
|
|
1325
1437
|
}
|
|
1326
1438
|
|
|
1327
1439
|
const msg = packet.toBinary();
|
|
1328
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
|
+
|
|
1329
1473
|
const dc = this.dataChannelForKind(kind);
|
|
1330
1474
|
if (dc) {
|
|
1331
|
-
if (kind
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
this.log.warn(
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
)
|
|
1343
|
-
|
|
1344
|
-
|
|
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;
|
|
1345
1493
|
}
|
|
1346
|
-
this.lossyDataStatCurrentBytes += msg.byteLength;
|
|
1347
1494
|
}
|
|
1495
|
+
this.lossyDataStatCurrentBytes += bytes.byteLength;
|
|
1348
1496
|
|
|
1349
1497
|
if (this.attemptingReconnect) {
|
|
1350
1498
|
return;
|
|
1351
1499
|
}
|
|
1352
1500
|
|
|
1353
|
-
dc.send(
|
|
1501
|
+
dc.send(bytes);
|
|
1354
1502
|
}
|
|
1355
1503
|
|
|
1356
1504
|
this.updateAndEmitDCBufferStatus(kind);
|
|
1357
1505
|
}
|
|
1358
1506
|
|
|
1359
1507
|
private async resendReliableMessagesForResume(lastMessageSeq: number) {
|
|
1360
|
-
await this.ensurePublisherConnected(
|
|
1361
|
-
const dc = this.dataChannelForKind(
|
|
1508
|
+
await this.ensurePublisherConnected(DataChannelKind.RELIABLE);
|
|
1509
|
+
const dc = this.dataChannelForKind(DataChannelKind.RELIABLE);
|
|
1362
1510
|
if (dc) {
|
|
1363
1511
|
this.reliableMessageBuffer.popToSequence(lastMessageSeq);
|
|
1364
1512
|
this.reliableMessageBuffer.getAll().forEach((msg) => {
|
|
1365
1513
|
dc.send(msg.data);
|
|
1366
1514
|
});
|
|
1367
1515
|
}
|
|
1368
|
-
this.updateAndEmitDCBufferStatus(
|
|
1516
|
+
this.updateAndEmitDCBufferStatus(DataChannelKind.RELIABLE);
|
|
1369
1517
|
}
|
|
1370
1518
|
|
|
1371
|
-
private updateAndEmitDCBufferStatus = (kind:
|
|
1372
|
-
if (kind ===
|
|
1519
|
+
private updateAndEmitDCBufferStatus = (kind: DataChannelKind) => {
|
|
1520
|
+
if (kind === DataChannelKind.RELIABLE) {
|
|
1373
1521
|
const dc = this.dataChannelForKind(kind);
|
|
1374
1522
|
if (dc) {
|
|
1375
1523
|
this.reliableMessageBuffer.alignBufferedAmount(dc.bufferedAmount);
|
|
@@ -1383,14 +1531,14 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1383
1531
|
}
|
|
1384
1532
|
};
|
|
1385
1533
|
|
|
1386
|
-
private isBufferStatusLow = (kind:
|
|
1534
|
+
private isBufferStatusLow = (kind: DataChannelKind): boolean | undefined => {
|
|
1387
1535
|
const dc = this.dataChannelForKind(kind);
|
|
1388
1536
|
if (dc) {
|
|
1389
1537
|
return dc.bufferedAmount <= dc.bufferedAmountLowThreshold;
|
|
1390
1538
|
}
|
|
1391
1539
|
};
|
|
1392
1540
|
|
|
1393
|
-
waitForBufferStatusLow(kind:
|
|
1541
|
+
waitForBufferStatusLow(kind: DataChannelKind): TypedPromise<void, UnexpectedConnectionState> {
|
|
1394
1542
|
return new TypedPromise(async (resolve, reject) => {
|
|
1395
1543
|
if (this.isBufferStatusLow(kind)) {
|
|
1396
1544
|
resolve();
|
|
@@ -1410,7 +1558,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1410
1558
|
* @internal
|
|
1411
1559
|
*/
|
|
1412
1560
|
async ensureDataTransportConnected(
|
|
1413
|
-
kind:
|
|
1561
|
+
kind: DataChannelKind,
|
|
1414
1562
|
subscriber: boolean = this.subscriberPrimary,
|
|
1415
1563
|
) {
|
|
1416
1564
|
if (!this.pcManager) {
|
|
@@ -1465,7 +1613,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1465
1613
|
);
|
|
1466
1614
|
}
|
|
1467
1615
|
|
|
1468
|
-
private async ensurePublisherConnected(kind:
|
|
1616
|
+
private async ensurePublisherConnected(kind: DataChannelKind) {
|
|
1469
1617
|
if (!this.publisherConnectionPromise) {
|
|
1470
1618
|
this.publisherConnectionPromise = this.ensureDataTransportConnected(kind, false);
|
|
1471
1619
|
}
|
|
@@ -1506,7 +1654,8 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1506
1654
|
if (
|
|
1507
1655
|
this.pcManager.publisher.getTransceivers().length == 0 &&
|
|
1508
1656
|
!this.lossyDC &&
|
|
1509
|
-
!this.reliableDC
|
|
1657
|
+
!this.reliableDC &&
|
|
1658
|
+
!this.dataTrackDC
|
|
1510
1659
|
) {
|
|
1511
1660
|
this.createDataChannels();
|
|
1512
1661
|
}
|
|
@@ -1566,26 +1715,35 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1566
1715
|
});
|
|
1567
1716
|
}
|
|
1568
1717
|
|
|
1569
|
-
dataChannelForKind(kind:
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
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
|
+
}
|
|
1584
1738
|
}
|
|
1585
1739
|
}
|
|
1586
1740
|
|
|
1587
1741
|
/** @internal */
|
|
1588
|
-
sendSyncState(
|
|
1742
|
+
sendSyncState(
|
|
1743
|
+
remoteTracks: RemoteTrackPublication[],
|
|
1744
|
+
localTracks: LocalTrackPublication[],
|
|
1745
|
+
localDataTrackInfos: Array<DataTrackInfo>,
|
|
1746
|
+
) {
|
|
1589
1747
|
if (!this.pcManager) {
|
|
1590
1748
|
this.log.warn('sync state cannot be sent without peer connection setup', this.logContext);
|
|
1591
1749
|
return;
|
|
@@ -1657,6 +1815,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1657
1815
|
lastSeq: seq,
|
|
1658
1816
|
});
|
|
1659
1817
|
}),
|
|
1818
|
+
publishDataTracks: localDataTrackInfos.map((info) => {
|
|
1819
|
+
return new PublishDataTrackResponse({ info: DataTrackInfo.toProtobuf(info) });
|
|
1820
|
+
}),
|
|
1660
1821
|
}),
|
|
1661
1822
|
);
|
|
1662
1823
|
}
|
|
@@ -1680,10 +1841,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
|
|
|
1680
1841
|
);
|
|
1681
1842
|
}
|
|
1682
1843
|
};
|
|
1683
|
-
getInfo(this.dataChannelForKind(
|
|
1684
|
-
getInfo(this.dataChannelForKind(
|
|
1685
|
-
getInfo(this.dataChannelForKind(
|
|
1686
|
-
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);
|
|
1687
1848
|
return infos;
|
|
1688
1849
|
}
|
|
1689
1850
|
|
|
@@ -1790,7 +1951,7 @@ export type EngineEventCallbacks = {
|
|
|
1790
1951
|
/** @internal */
|
|
1791
1952
|
trackSenderAdded: (track: Track, sender: RTCRtpSender) => void;
|
|
1792
1953
|
rtpVideoMapUpdate: (rtpMap: Map<number, VideoCodec>) => void;
|
|
1793
|
-
dcBufferStatusChanged: (isLow: boolean, kind:
|
|
1954
|
+
dcBufferStatusChanged: (isLow: boolean, kind: DataChannelKind) => void;
|
|
1794
1955
|
participantUpdate: (infos: ParticipantInfo[]) => void;
|
|
1795
1956
|
roomUpdate: (room: RoomModel) => void;
|
|
1796
1957
|
roomMoved: (room: RoomMovedResponse) => void;
|
|
@@ -1806,12 +1967,13 @@ export type EngineEventCallbacks = {
|
|
|
1806
1967
|
offline: () => void;
|
|
1807
1968
|
signalRequestResponse: (response: RequestResponse) => void;
|
|
1808
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;
|
|
1809
1975
|
};
|
|
1810
1976
|
|
|
1811
|
-
function supportOptionalDatachannel(protocol: number | undefined): boolean {
|
|
1812
|
-
return protocol !== undefined && protocol > 13;
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
1977
|
function applyUserDataCompat(newObj: DataPacket, oldObj: UserPacket) {
|
|
1816
1978
|
const participantIdentity = newObj.participantIdentity
|
|
1817
1979
|
? newObj.participantIdentity
|