livekit-client 2.18.9 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +5609 -644
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +3553 -2813
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.pt.worker.js +2 -0
  8. package/dist/livekit-client.pt.worker.js.map +1 -0
  9. package/dist/livekit-client.pt.worker.mjs +5834 -0
  10. package/dist/livekit-client.pt.worker.mjs.map +1 -0
  11. package/dist/livekit-client.umd.js +1 -1
  12. package/dist/livekit-client.umd.js.map +1 -1
  13. package/dist/src/api/SignalClient.d.ts +2 -1
  14. package/dist/src/api/SignalClient.d.ts.map +1 -1
  15. package/dist/src/e2ee/E2eeManager.d.ts +8 -7
  16. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  17. package/dist/src/e2ee/types.d.ts +35 -8
  18. package/dist/src/e2ee/types.d.ts.map +1 -1
  19. package/dist/src/e2ee/utils.d.ts +5 -5
  20. package/dist/src/e2ee/utils.d.ts.map +1 -1
  21. package/dist/src/e2ee/worker/DataCryptor.d.ts +5 -5
  22. package/dist/src/e2ee/worker/DataCryptor.d.ts.map +1 -1
  23. package/dist/src/e2ee/worker/FrameCryptor.d.ts +21 -4
  24. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  25. package/dist/src/e2ee/worker/naluUtils.d.ts +1 -1
  26. package/dist/src/e2ee/worker/naluUtils.d.ts.map +1 -1
  27. package/dist/src/e2ee/worker/sifPayload.d.ts +7 -7
  28. package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -1
  29. package/dist/src/index.d.ts +4 -1
  30. package/dist/src/index.d.ts.map +1 -1
  31. package/dist/src/options.d.ts +7 -0
  32. package/dist/src/options.d.ts.map +1 -1
  33. package/dist/src/packetTrailer/PacketTrailerManager.d.ts +49 -0
  34. package/dist/src/packetTrailer/PacketTrailerManager.d.ts.map +1 -0
  35. package/dist/src/packetTrailer/packetTrailer.d.ts +32 -0
  36. package/dist/src/packetTrailer/packetTrailer.d.ts.map +1 -0
  37. package/dist/src/packetTrailer/types.d.ts +57 -0
  38. package/dist/src/packetTrailer/types.d.ts.map +1 -0
  39. package/dist/src/packetTrailer/utils.d.ts +9 -0
  40. package/dist/src/packetTrailer/utils.d.ts.map +1 -0
  41. package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts +2 -0
  42. package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts.map +1 -0
  43. package/dist/src/room/RTCEngine.d.ts +2 -4
  44. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  45. package/dist/src/room/Room.d.ts +7 -3
  46. package/dist/src/room/Room.d.ts.map +1 -1
  47. package/dist/src/room/data-track/RemoteDataTrack.d.ts +5 -1
  48. package/dist/src/room/data-track/RemoteDataTrack.d.ts.map +1 -1
  49. package/dist/src/room/data-track/depacketizer.d.ts +12 -4
  50. package/dist/src/room/data-track/depacketizer.d.ts.map +1 -1
  51. package/dist/src/room/data-track/frame.d.ts +3 -3
  52. package/dist/src/room/data-track/frame.d.ts.map +1 -1
  53. package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +3 -1
  54. package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
  55. package/dist/src/room/data-track/incoming/pipeline.d.ts +4 -1
  56. package/dist/src/room/data-track/incoming/pipeline.d.ts.map +1 -1
  57. package/dist/src/room/data-track/outgoing/types.d.ts +2 -2
  58. package/dist/src/room/data-track/outgoing/types.d.ts.map +1 -1
  59. package/dist/src/room/data-track/packet/extensions.d.ts +4 -4
  60. package/dist/src/room/data-track/packet/extensions.d.ts.map +1 -1
  61. package/dist/src/room/data-track/packet/index.d.ts +5 -5
  62. package/dist/src/room/data-track/packet/index.d.ts.map +1 -1
  63. package/dist/src/room/data-track/packet/serializable.d.ts +1 -1
  64. package/dist/src/room/data-track/packet/serializable.d.ts.map +1 -1
  65. package/dist/src/room/data-track/types.d.ts +7 -0
  66. package/dist/src/room/data-track/types.d.ts.map +1 -1
  67. package/dist/src/room/events.d.ts +2 -2
  68. package/dist/src/room/participant/LocalParticipant.d.ts +8 -14
  69. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  70. package/dist/src/room/participant/Participant.d.ts +1 -1
  71. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  72. package/dist/src/room/participant/RemoteParticipant.d.ts +5 -1
  73. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  74. package/dist/src/room/rpc/client/RpcClientManager.d.ts +39 -0
  75. package/dist/src/room/rpc/client/RpcClientManager.d.ts.map +1 -0
  76. package/dist/src/room/rpc/client/events.d.ts +8 -0
  77. package/dist/src/room/rpc/client/events.d.ts.map +1 -0
  78. package/dist/src/room/rpc/index.d.ts +6 -0
  79. package/dist/src/room/rpc/index.d.ts.map +1 -0
  80. package/dist/src/room/rpc/server/RpcServerManager.d.ts +44 -0
  81. package/dist/src/room/rpc/server/RpcServerManager.d.ts.map +1 -0
  82. package/dist/src/room/rpc/server/events.d.ts +8 -0
  83. package/dist/src/room/rpc/server/events.d.ts.map +1 -0
  84. package/dist/src/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
  85. package/dist/src/room/rpc/utils.d.ts.map +1 -0
  86. package/dist/src/room/track/PacketTrailerExtractor.d.ts +19 -0
  87. package/dist/src/room/track/PacketTrailerExtractor.d.ts.map +1 -0
  88. package/dist/src/room/track/RemoteVideoTrack.d.ts +16 -0
  89. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  90. package/dist/src/room/track/Track.d.ts +1 -1
  91. package/dist/src/room/track/Track.d.ts.map +1 -1
  92. package/dist/src/room/track/create.d.ts.map +1 -1
  93. package/dist/src/room/track/options.d.ts +10 -0
  94. package/dist/src/room/track/options.d.ts.map +1 -1
  95. package/dist/src/room/track/utils.d.ts.map +1 -1
  96. package/dist/src/room/utils.d.ts +4 -3
  97. package/dist/src/room/utils.d.ts.map +1 -1
  98. package/dist/src/test/MockMediaStreamTrack.d.ts.map +1 -1
  99. package/dist/src/utils/dataPacketBuffer.d.ts +1 -1
  100. package/dist/src/utils/dataPacketBuffer.d.ts.map +1 -1
  101. package/dist/src/version.d.ts +9 -1
  102. package/dist/src/version.d.ts.map +1 -1
  103. package/dist/ts4.2/api/SignalClient.d.ts +2 -1
  104. package/dist/ts4.2/e2ee/E2eeManager.d.ts +8 -7
  105. package/dist/ts4.2/e2ee/types.d.ts +35 -8
  106. package/dist/ts4.2/e2ee/utils.d.ts +5 -5
  107. package/dist/ts4.2/e2ee/worker/DataCryptor.d.ts +5 -5
  108. package/dist/ts4.2/e2ee/worker/FrameCryptor.d.ts +21 -4
  109. package/dist/ts4.2/e2ee/worker/naluUtils.d.ts +1 -1
  110. package/dist/ts4.2/e2ee/worker/sifPayload.d.ts +7 -7
  111. package/dist/ts4.2/index.d.ts +5 -1
  112. package/dist/ts4.2/options.d.ts +7 -0
  113. package/dist/ts4.2/packetTrailer/PacketTrailerManager.d.ts +49 -0
  114. package/dist/ts4.2/packetTrailer/packetTrailer.d.ts +32 -0
  115. package/dist/ts4.2/packetTrailer/types.d.ts +57 -0
  116. package/dist/ts4.2/packetTrailer/utils.d.ts +9 -0
  117. package/dist/ts4.2/packetTrailer/worker/packetTrailer.worker.d.ts +2 -0
  118. package/dist/ts4.2/room/RTCEngine.d.ts +2 -4
  119. package/dist/ts4.2/room/Room.d.ts +7 -3
  120. package/dist/ts4.2/room/data-track/RemoteDataTrack.d.ts +5 -1
  121. package/dist/ts4.2/room/data-track/depacketizer.d.ts +12 -4
  122. package/dist/ts4.2/room/data-track/frame.d.ts +3 -3
  123. package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +3 -1
  124. package/dist/ts4.2/room/data-track/incoming/pipeline.d.ts +4 -1
  125. package/dist/ts4.2/room/data-track/outgoing/types.d.ts +2 -2
  126. package/dist/ts4.2/room/data-track/packet/extensions.d.ts +4 -4
  127. package/dist/ts4.2/room/data-track/packet/index.d.ts +5 -5
  128. package/dist/ts4.2/room/data-track/packet/serializable.d.ts +1 -1
  129. package/dist/ts4.2/room/data-track/types.d.ts +7 -0
  130. package/dist/ts4.2/room/events.d.ts +2 -2
  131. package/dist/ts4.2/room/participant/LocalParticipant.d.ts +8 -14
  132. package/dist/ts4.2/room/participant/Participant.d.ts +1 -1
  133. package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +5 -1
  134. package/dist/ts4.2/room/rpc/client/RpcClientManager.d.ts +43 -0
  135. package/dist/ts4.2/room/rpc/client/events.d.ts +8 -0
  136. package/dist/ts4.2/room/rpc/index.d.ts +7 -0
  137. package/dist/ts4.2/room/rpc/server/RpcServerManager.d.ts +44 -0
  138. package/dist/ts4.2/room/rpc/server/events.d.ts +8 -0
  139. package/dist/ts4.2/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
  140. package/dist/ts4.2/room/track/PacketTrailerExtractor.d.ts +19 -0
  141. package/dist/ts4.2/room/track/RemoteVideoTrack.d.ts +16 -0
  142. package/dist/ts4.2/room/track/Track.d.ts +1 -1
  143. package/dist/ts4.2/room/track/options.d.ts +10 -0
  144. package/dist/ts4.2/room/utils.d.ts +4 -3
  145. package/dist/ts4.2/utils/dataPacketBuffer.d.ts +1 -1
  146. package/dist/ts4.2/version.d.ts +9 -1
  147. package/package.json +24 -16
  148. package/src/api/SignalClient.test.ts +102 -10
  149. package/src/api/SignalClient.ts +4 -2
  150. package/src/api/WebSocketStream.test.ts +0 -1
  151. package/src/e2ee/E2eeManager.ts +82 -30
  152. package/src/e2ee/types.ts +37 -8
  153. package/src/e2ee/utils.ts +7 -6
  154. package/src/e2ee/worker/DataCryptor.ts +6 -6
  155. package/src/e2ee/worker/FrameCryptor.test.ts +177 -4
  156. package/src/e2ee/worker/FrameCryptor.ts +94 -14
  157. package/src/e2ee/worker/ParticipantKeyHandler.test.ts +4 -4
  158. package/src/e2ee/worker/e2ee.worker.ts +13 -5
  159. package/src/e2ee/worker/naluUtils.ts +4 -4
  160. package/src/e2ee/worker/sifPayload.ts +10 -8
  161. package/src/index.ts +7 -0
  162. package/src/options.ts +8 -0
  163. package/src/packetTrailer/PacketTrailerManager.test.ts +172 -0
  164. package/src/packetTrailer/PacketTrailerManager.ts +250 -0
  165. package/src/packetTrailer/packetTrailer.test.ts +174 -0
  166. package/src/packetTrailer/packetTrailer.ts +276 -0
  167. package/src/packetTrailer/types.ts +75 -0
  168. package/src/packetTrailer/utils.test.ts +105 -0
  169. package/src/packetTrailer/utils.ts +50 -0
  170. package/src/packetTrailer/worker/packetTrailer.worker.ts +155 -0
  171. package/src/packetTrailer/worker/tsconfig.json +14 -0
  172. package/src/room/BackOffStrategy.test.ts +1 -1
  173. package/src/room/RTCEngine.test.ts +219 -0
  174. package/src/room/RTCEngine.ts +86 -46
  175. package/src/room/Room.test.ts +62 -1
  176. package/src/room/Room.ts +111 -86
  177. package/src/room/data-track/RemoteDataTrack.ts +8 -1
  178. package/src/room/data-track/depacketizer.test.ts +433 -1
  179. package/src/room/data-track/depacketizer.ts +79 -61
  180. package/src/room/data-track/frame.ts +2 -2
  181. package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +194 -0
  182. package/src/room/data-track/incoming/IncomingDataTrackManager.ts +21 -1
  183. package/src/room/data-track/incoming/pipeline.ts +13 -2
  184. package/src/room/data-track/outgoing/types.ts +3 -2
  185. package/src/room/data-track/packet/extensions.ts +2 -2
  186. package/src/room/data-track/packet/index.ts +6 -6
  187. package/src/room/data-track/packet/serializable.ts +1 -1
  188. package/src/room/data-track/types.ts +8 -0
  189. package/src/room/events.ts +2 -2
  190. package/src/room/participant/LocalParticipant.test.ts +81 -0
  191. package/src/room/participant/LocalParticipant.ts +64 -187
  192. package/src/room/participant/Participant.ts +1 -1
  193. package/src/room/participant/RemoteParticipant.ts +9 -0
  194. package/src/room/participant/publishUtils.ts +1 -1
  195. package/src/room/rpc/client/RpcClientManager.test.ts +430 -0
  196. package/src/room/rpc/client/RpcClientManager.ts +269 -0
  197. package/src/room/rpc/client/events.ts +9 -0
  198. package/src/room/rpc/index.ts +14 -0
  199. package/src/room/rpc/server/RpcServerManager.test.ts +471 -0
  200. package/src/room/rpc/server/RpcServerManager.ts +293 -0
  201. package/src/room/rpc/server/events.ts +9 -0
  202. package/src/room/{rpc.ts → rpc/utils.ts} +49 -8
  203. package/src/room/track/PacketTrailerExtractor.ts +43 -0
  204. package/src/room/track/RemoteVideoTrack.ts +23 -2
  205. package/src/room/track/Track.ts +1 -1
  206. package/src/room/track/create.ts +0 -4
  207. package/src/room/track/options.ts +11 -0
  208. package/src/room/track/record.ts +1 -1
  209. package/src/room/track/utils.ts +4 -1
  210. package/src/room/utils.test.ts +14 -1
  211. package/src/room/utils.ts +19 -4
  212. package/src/test/MockMediaStreamTrack.ts +0 -1
  213. package/src/type-polyfills/non-shared-typed-arrays.d.ts +6 -0
  214. package/src/utils/dataPacketBuffer.ts +1 -1
  215. package/src/version.ts +11 -1
  216. package/dist/src/room/rpc.d.ts.map +0 -1
  217. package/src/room/rpc.test.ts +0 -301
@@ -9,12 +9,10 @@ import {
9
9
  DataPacket_Kind,
10
10
  Encryption_Type,
11
11
  JoinResponse,
12
+ PacketTrailerFeature,
12
13
  ParticipantInfo,
13
14
  RequestResponse,
14
15
  RequestResponse_Reason,
15
- RpcAck,
16
- RpcRequest,
17
- RpcResponse,
18
16
  SimulcastCodec,
19
17
  SipDTMF,
20
18
  SubscribedQualityUpdate,
@@ -25,6 +23,12 @@ import {
25
23
  } from '@livekit/protocol';
26
24
  import { SignalConnectionState } from '../../api/SignalClient';
27
25
  import type { InternalRoomOptions } from '../../options';
26
+ import {
27
+ getPacketTrailerFeatures,
28
+ getPacketTrailerPublishOptions,
29
+ hasPacketTrailerPublishOptions,
30
+ isPacketTrailerSupported,
31
+ } from '../../packetTrailer/utils';
28
32
  import TypedPromise from '../../utils/TypedPromise';
29
33
  import { PCTransportState } from '../PCTransportManager';
30
34
  import type RTCEngine from '../RTCEngine';
@@ -47,11 +51,11 @@ import {
47
51
  } from '../errors';
48
52
  import { EngineEvent, ParticipantEvent, TrackEvent } from '../events';
49
53
  import {
50
- MAX_PAYLOAD_BYTES,
51
54
  type PerformRpcParams,
55
+ RpcClientManager,
52
56
  RpcError,
53
57
  type RpcInvocationData,
54
- byteLength,
58
+ RpcServerManager,
55
59
  } from '../rpc';
56
60
  import LocalAudioTrack from '../track/LocalAudioTrack';
57
61
  import LocalTrack from '../track/LocalTrack';
@@ -87,7 +91,6 @@ import {
87
91
  } from '../types';
88
92
  import {
89
93
  Future,
90
- compareVersions,
91
94
  isAudioTrack,
92
95
  isE2EESimulcastSupported,
93
96
  isFireFox,
@@ -155,12 +158,14 @@ export default class LocalParticipant extends Participant {
155
158
 
156
159
  private firstActiveAgent?: RemoteParticipant;
157
160
 
158
- private rpcHandlers: Map<string, (data: RpcInvocationData) => Promise<string>>;
159
-
160
161
  private roomOutgoingDataStreamManager: OutgoingDataStreamManager;
161
162
 
162
163
  private roomOutgoingDataTrackManager: OutgoingDataTrackManager;
163
164
 
165
+ private rpcClientManager: RpcClientManager;
166
+
167
+ private rpcServerManager: RpcServerManager;
168
+
164
169
  private pendingSignalRequests: Map<
165
170
  number,
166
171
  {
@@ -172,25 +177,16 @@ export default class LocalParticipant extends Participant {
172
177
 
173
178
  private enabledPublishVideoCodecs: Codec[] = [];
174
179
 
175
- private pendingAcks = new Map<string, { resolve: () => void; participantIdentity: string }>();
176
-
177
- private pendingResponses = new Map<
178
- string,
179
- {
180
- resolve: (payload: string | null, error: RpcError | null) => void;
181
- participantIdentity: string;
182
- }
183
- >();
184
-
185
180
  /** @internal */
186
181
  constructor(
187
182
  sid: string,
188
183
  identity: string,
189
184
  engine: RTCEngine,
190
185
  options: InternalRoomOptions,
191
- roomRpcHandlers: Map<string, (data: RpcInvocationData) => Promise<string>>,
192
186
  roomOutgoingDataStreamManager: OutgoingDataStreamManager,
193
187
  roomOutgoingDataTrackManager: OutgoingDataTrackManager,
188
+ rpcClientManager: RpcClientManager,
189
+ rpcServerManager: RpcServerManager,
194
190
  ) {
195
191
  super(sid, identity, undefined, undefined, undefined, {
196
192
  loggerName: options.loggerName,
@@ -208,9 +204,10 @@ export default class LocalParticipant extends Participant {
208
204
  ['audiooutput', 'default'],
209
205
  ]);
210
206
  this.pendingSignalRequests = new Map();
211
- this.rpcHandlers = roomRpcHandlers;
212
207
  this.roomOutgoingDataStreamManager = roomOutgoingDataStreamManager;
213
208
  this.roomOutgoingDataTrackManager = roomOutgoingDataTrackManager;
209
+ this.rpcClientManager = rpcClientManager;
210
+ this.rpcServerManager = rpcServerManager;
214
211
  }
215
212
 
216
213
  get lastCameraError(): Error | undefined {
@@ -270,8 +267,7 @@ export default class LocalParticipant extends Participant {
270
267
  .on(EngineEvent.LocalTrackUnpublished, this.handleLocalTrackUnpublished)
271
268
  .on(EngineEvent.SubscribedQualityUpdate, this.handleSubscribedQualityUpdate)
272
269
  .on(EngineEvent.Closing, this.handleClosing)
273
- .on(EngineEvent.SignalRequestResponse, this.handleSignalRequestResponse)
274
- .on(EngineEvent.DataPacketReceived, this.handleDataPacket);
270
+ .on(EngineEvent.SignalRequestResponse, this.handleSignalRequestResponse);
275
271
  }
276
272
 
277
273
  private handleReconnecting = () => {
@@ -343,7 +339,7 @@ export default class LocalParticipant extends Participant {
343
339
  break;
344
340
  default:
345
341
  error = DataTrackPublishError.unknown(response.reason, response.message);
346
- return;
342
+ break;
347
343
  }
348
344
 
349
345
  this.roomOutgoingDataTrackManager.receivedSfuPublishResponse(
@@ -355,27 +351,6 @@ export default class LocalParticipant extends Participant {
355
351
  }
356
352
  };
357
353
 
358
- private handleDataPacket = (packet: DataPacket) => {
359
- switch (packet.value.case) {
360
- case 'rpcResponse':
361
- let rpcResponse = packet.value.value as RpcResponse;
362
- let payload: string | null = null;
363
- let error: RpcError | null = null;
364
-
365
- if (rpcResponse.value.case === 'payload') {
366
- payload = rpcResponse.value.value;
367
- } else if (rpcResponse.value.case === 'error') {
368
- error = RpcError.fromProto(rpcResponse.value.value);
369
- }
370
- this.handleIncomingRpcResponse(rpcResponse.requestId, payload, error);
371
- break;
372
- case 'rpcAck':
373
- let rpcAck = packet.value.value as RpcAck;
374
- this.handleIncomingRpcAck(rpcAck.requestId);
375
- break;
376
- }
377
- };
378
-
379
354
  /**
380
355
  * Sets and updates the metadata of the local participant.
381
356
  * Note: this requires `canUpdateOwnMetadata` permission.
@@ -1109,6 +1084,8 @@ export default class LocalParticipant extends Participant {
1109
1084
  if (isLocalAudioTrack(track) && track.hasPreConnectBuffer) {
1110
1085
  audioFeatures.push(AudioTrackFeature.TF_PRECONNECT_BUFFER);
1111
1086
  }
1087
+ const packetTrailerFeatures: PacketTrailerFeature[] =
1088
+ this.normalizeRequestedPacketTrailerOptions(track, opts);
1112
1089
 
1113
1090
  // create track publication from track
1114
1091
  const req = new AddTrackRequest({
@@ -1125,15 +1102,13 @@ export default class LocalParticipant extends Participant {
1125
1102
  stream: opts?.stream,
1126
1103
  backupCodecPolicy: opts?.backupCodecPolicy as BackupCodecPolicy,
1127
1104
  audioFeatures,
1105
+ packetTrailerFeatures,
1128
1106
  });
1129
1107
 
1130
1108
  // compute encodings and layers for video
1131
1109
  let encodings: RTCRtpEncodingParameters[] | undefined;
1132
1110
  if (track.kind === Track.Kind.Video) {
1133
- let dims: Track.Dimensions = {
1134
- width: 0,
1135
- height: 0,
1136
- };
1111
+ let dims: Track.Dimensions;
1137
1112
  try {
1138
1113
  dims = await track.waitForDimensions();
1139
1114
  } catch (e) {
@@ -1240,6 +1215,9 @@ export default class LocalParticipant extends Participant {
1240
1215
  }
1241
1216
 
1242
1217
  track.sender = await this.engine.createSender(track, opts, encodings);
1218
+ if (isLocalVideoTrack(track)) {
1219
+ track.publishOptions = opts;
1220
+ }
1243
1221
  this.emit(ParticipantEvent.LocalSenderCreated, track.sender, track);
1244
1222
 
1245
1223
  if (isLocalVideoTrack(track)) {
@@ -1307,7 +1285,7 @@ export default class LocalParticipant extends Participant {
1307
1285
  reject(err);
1308
1286
  }
1309
1287
  });
1310
- if (this.enabledPublishVideoCodecs.length > 0) {
1288
+ if (this.enabledPublishVideoCodecs.length > 0 && packetTrailerFeatures.length === 0) {
1311
1289
  const rets = await Promise.all([addTrackPromise, negotiate()]);
1312
1290
  ti = rets[0];
1313
1291
  } else {
@@ -1438,6 +1416,34 @@ export default class LocalParticipant extends Participant {
1438
1416
  return publication;
1439
1417
  }
1440
1418
 
1419
+ private canPublishPacketTrailer() {
1420
+ return !!(
1421
+ this.roomOptions.e2ee ||
1422
+ this.roomOptions.encryption ||
1423
+ isPacketTrailerSupported(this.roomOptions.packetTrailer)
1424
+ );
1425
+ }
1426
+
1427
+ private normalizeRequestedPacketTrailerOptions(track: LocalTrack, opts: TrackPublishOptions) {
1428
+ if (track.kind !== Track.Kind.Video || !hasPacketTrailerPublishOptions(opts.packetTrailer)) {
1429
+ opts.packetTrailer = undefined;
1430
+ return [];
1431
+ }
1432
+
1433
+ if (!this.canPublishPacketTrailer()) {
1434
+ this.log.warn('packet trailer transform not supported; not advertising features', {
1435
+ ...this.logContext,
1436
+ ...getLogContextFromTrack(track),
1437
+ });
1438
+ opts.packetTrailer = undefined;
1439
+ return [];
1440
+ }
1441
+
1442
+ const features = getPacketTrailerFeatures(opts.packetTrailer);
1443
+ opts.packetTrailer = getPacketTrailerPublishOptions(features);
1444
+ return features;
1445
+ }
1446
+
1441
1447
  override get isLocal(): boolean {
1442
1448
  return true;
1443
1449
  }
@@ -1490,12 +1496,15 @@ export default class LocalParticipant extends Participant {
1490
1496
  if (!simulcastTrack) {
1491
1497
  return;
1492
1498
  }
1499
+ const packetTrailerFeatures = this.normalizeRequestedPacketTrailerOptions(track, opts);
1500
+
1493
1501
  const req = new AddTrackRequest({
1494
1502
  cid: simulcastTrack.mediaStreamTrack.id,
1495
1503
  type: Track.kindToProto(track.kind),
1496
1504
  muted: track.isMuted,
1497
1505
  source: Track.sourceToProto(track.source),
1498
1506
  sid: track.sid,
1507
+ packetTrailerFeatures,
1499
1508
  simulcastCodecs: [
1500
1509
  {
1501
1510
  codec: opts.videoCodec,
@@ -1703,7 +1712,7 @@ export default class LocalParticipant extends Participant {
1703
1712
  * @param data Uint8Array of the payload. To send string data, use TextEncoder.encode
1704
1713
  * @param options optionally specify a `reliable`, `topic` and `destination`
1705
1714
  */
1706
- async publishData(data: Uint8Array, options: DataPublishOptions = {}): Promise<void> {
1715
+ async publishData(data: NonSharedUint8Array, options: DataPublishOptions = {}): Promise<void> {
1707
1716
  const kind = options.reliable ? DataChannelKind.RELIABLE : DataChannelKind.LOSSY;
1708
1717
  const dataPacketKind = options.reliable ? DataPacket_Kind.RELIABLE : DataPacket_Kind.LOSSY;
1709
1718
  const destinationIdentities = options.destinationIdentities;
@@ -1842,69 +1851,9 @@ export default class LocalParticipant extends Participant {
1842
1851
  * @returns A promise that resolves with the response payload or rejects with an error.
1843
1852
  * @throws Error on failure. Details in `message`.
1844
1853
  */
1845
- performRpc({
1846
- destinationIdentity,
1847
- method,
1848
- payload,
1849
- responseTimeout = 15000,
1850
- }: PerformRpcParams): TypedPromise<string, RpcError> {
1851
- const maxRoundTripLatency = 7000;
1852
- const minEffectiveTimeout = maxRoundTripLatency + 1000;
1853
-
1854
- return new TypedPromise<string, RpcError>(async (resolve, reject) => {
1855
- if (byteLength(payload) > MAX_PAYLOAD_BYTES) {
1856
- reject(RpcError.builtIn('REQUEST_PAYLOAD_TOO_LARGE'));
1857
- return;
1858
- }
1859
-
1860
- if (
1861
- this.engine.latestJoinResponse?.serverInfo?.version &&
1862
- compareVersions(this.engine.latestJoinResponse?.serverInfo?.version, '1.8.0') < 0
1863
- ) {
1864
- reject(RpcError.builtIn('UNSUPPORTED_SERVER'));
1865
- return;
1866
- }
1867
-
1868
- const effectiveTimeout = Math.max(responseTimeout, minEffectiveTimeout);
1869
- const id = crypto.randomUUID();
1870
- await this.publishRpcRequest(destinationIdentity, id, method, payload, effectiveTimeout);
1871
-
1872
- const ackTimeoutId = setTimeout(() => {
1873
- this.pendingAcks.delete(id);
1874
- reject(RpcError.builtIn('CONNECTION_TIMEOUT'));
1875
- this.pendingResponses.delete(id);
1876
- clearTimeout(responseTimeoutId);
1877
- }, maxRoundTripLatency);
1878
-
1879
- this.pendingAcks.set(id, {
1880
- resolve: () => {
1881
- clearTimeout(ackTimeoutId);
1882
- },
1883
- participantIdentity: destinationIdentity,
1884
- });
1885
-
1886
- const responseTimeoutId = setTimeout(() => {
1887
- this.pendingResponses.delete(id);
1888
- reject(RpcError.builtIn('RESPONSE_TIMEOUT'));
1889
- }, responseTimeout);
1890
-
1891
- this.pendingResponses.set(id, {
1892
- resolve: (responsePayload: string | null, responseError: RpcError | null) => {
1893
- clearTimeout(responseTimeoutId);
1894
- if (this.pendingAcks.has(id)) {
1895
- this.log.warn('RPC response received before ack', id);
1896
- this.pendingAcks.delete(id);
1897
- clearTimeout(ackTimeoutId);
1898
- }
1899
-
1900
- if (responseError) {
1901
- reject(responseError);
1902
- } else {
1903
- resolve(responsePayload ?? '');
1904
- }
1905
- },
1906
- participantIdentity: destinationIdentity,
1907
- });
1854
+ performRpc(params: PerformRpcParams): TypedPromise<string, RpcError> {
1855
+ return this.rpcClientManager.performRpc(params).then(([_id, completionPromise]) => {
1856
+ return completionPromise;
1908
1857
  });
1909
1858
  }
1910
1859
 
@@ -1912,20 +1861,14 @@ export default class LocalParticipant extends Participant {
1912
1861
  * @deprecated use `room.registerRpcMethod` instead
1913
1862
  */
1914
1863
  registerRpcMethod(method: string, handler: (data: RpcInvocationData) => Promise<string>) {
1915
- if (this.rpcHandlers.has(method)) {
1916
- this.log.warn(
1917
- `you're overriding the RPC handler for method ${method}, in the future this will throw an error`,
1918
- );
1919
- }
1920
-
1921
- this.rpcHandlers.set(method, handler);
1864
+ this.rpcServerManager.registerRpcMethod(method, handler);
1922
1865
  }
1923
1866
 
1924
1867
  /**
1925
1868
  * @deprecated use `room.unregisterRpcMethod` instead
1926
1869
  */
1927
1870
  unregisterRpcMethod(method: string) {
1928
- this.rpcHandlers.delete(method);
1871
+ this.rpcServerManager.unregisterRpcMethod(method);
1929
1872
  }
1930
1873
 
1931
1874
  /**
@@ -1956,72 +1899,6 @@ export default class LocalParticipant extends Participant {
1956
1899
  }
1957
1900
  }
1958
1901
 
1959
- private handleIncomingRpcAck(requestId: string) {
1960
- const handler = this.pendingAcks.get(requestId);
1961
- if (handler) {
1962
- handler.resolve();
1963
- this.pendingAcks.delete(requestId);
1964
- } else {
1965
- console.error('Ack received for unexpected RPC request', requestId);
1966
- }
1967
- }
1968
-
1969
- private handleIncomingRpcResponse(
1970
- requestId: string,
1971
- payload: string | null,
1972
- error: RpcError | null,
1973
- ) {
1974
- const handler = this.pendingResponses.get(requestId);
1975
- if (handler) {
1976
- handler.resolve(payload, error);
1977
- this.pendingResponses.delete(requestId);
1978
- } else {
1979
- console.error('Response received for unexpected RPC request', requestId);
1980
- }
1981
- }
1982
-
1983
- /** @internal */
1984
- private async publishRpcRequest(
1985
- destinationIdentity: string,
1986
- requestId: string,
1987
- method: string,
1988
- payload: string,
1989
- responseTimeout: number,
1990
- ) {
1991
- const packet = new DataPacket({
1992
- destinationIdentities: [destinationIdentity],
1993
- kind: DataPacket_Kind.RELIABLE,
1994
- value: {
1995
- case: 'rpcRequest',
1996
- value: new RpcRequest({
1997
- id: requestId,
1998
- method,
1999
- payload,
2000
- responseTimeoutMs: responseTimeout,
2001
- version: 1,
2002
- }),
2003
- },
2004
- });
2005
-
2006
- await this.engine.sendDataPacket(packet, DataChannelKind.RELIABLE);
2007
- }
2008
-
2009
- /** @internal */
2010
- handleParticipantDisconnected(participantIdentity: string) {
2011
- for (const [id, { participantIdentity: pendingIdentity }] of this.pendingAcks) {
2012
- if (pendingIdentity === participantIdentity) {
2013
- this.pendingAcks.delete(id);
2014
- }
2015
- }
2016
-
2017
- for (const [id, { participantIdentity: pendingIdentity, resolve }] of this.pendingResponses) {
2018
- if (pendingIdentity === participantIdentity) {
2019
- resolve(null, RpcError.builtIn('RECIPIENT_DISCONNECTED'));
2020
- this.pendingResponses.delete(id);
2021
- }
2022
- }
2023
- }
2024
-
2025
1902
  /** @internal */
2026
1903
  setEnabledPublishCodecs(codecs: Codec[]) {
2027
1904
  this.enabledPublishVideoCodecs = codecs.filter(
@@ -413,7 +413,7 @@ export type ParticipantEventCallbacks = {
413
413
  participantMetadataChanged: (prevMetadata: string | undefined, participant?: any) => void;
414
414
  participantNameChanged: (name: string) => void;
415
415
  dataReceived: (
416
- payload: Uint8Array,
416
+ payload: NonSharedUint8Array,
417
417
  kind: DataPacket_Kind,
418
418
  encryptionType?: Encryption_Type,
419
419
  ) => void;
@@ -6,6 +6,7 @@ import type {
6
6
  } from '@livekit/protocol';
7
7
  import type { SignalClient } from '../../api/SignalClient';
8
8
  import { DeferrableMap } from '../../utils/deferrable-map';
9
+ import { CLIENT_PROTOCOL_DEFAULT } from '../../version';
9
10
  import RemoteDataTrack from '../data-track/RemoteDataTrack';
10
11
  import type IncomingDataTrackManager from '../data-track/incoming/IncomingDataTrackManager';
11
12
  import { DataTrackInfo } from '../data-track/types';
@@ -41,6 +42,11 @@ export default class RemoteParticipant extends Participant {
41
42
 
42
43
  signalClient: SignalClient;
43
44
 
45
+ /** A version number indicating the set of features that the report participant's client supports.
46
+ * @internal
47
+ **/
48
+ clientProtocol: number;
49
+
44
50
  private volumeMap: Map<Track.Source, number>;
45
51
 
46
52
  private audioOutput?: AudioOutputOptions;
@@ -65,6 +71,7 @@ export default class RemoteParticipant extends Participant {
65
71
  const info = DataTrackInfo.from(dti);
66
72
  return new RemoteDataTrack(info, manager, { publisherIdentity: pi.identity });
67
73
  }),
74
+ pi.clientProtocol,
68
75
  );
69
76
  }
70
77
 
@@ -87,6 +94,7 @@ export default class RemoteParticipant extends Participant {
87
94
  loggerOptions?: LoggerOptions,
88
95
  kind: ParticipantKind = ParticipantKind.STANDARD,
89
96
  remoteDataTracks: Array<RemoteDataTrack> = [],
97
+ clientProtocol: number = CLIENT_PROTOCOL_DEFAULT,
90
98
  ) {
91
99
  super(sid, identity || '', name, metadata, attributes, loggerOptions, kind);
92
100
  this.signalClient = signalClient;
@@ -99,6 +107,7 @@ export default class RemoteParticipant extends Participant {
99
107
  }),
100
108
  );
101
109
  this.volumeMap = new Map();
110
+ this.clientProtocol = clientProtocol;
102
111
  }
103
112
 
104
113
  protected addTrackPublication(publication: RemoteTrackPublication) {
@@ -194,7 +194,7 @@ export function computeVideoEncodings(
194
194
  return [videoEncoding];
195
195
  }
196
196
 
197
- let presets: Array<VideoPreset> = [];
197
+ let presets: Array<VideoPreset>;
198
198
  if (isScreenShare) {
199
199
  presets =
200
200
  sortPresets(options?.screenShareSimulcastLayers) ??