@livekit/rtc-node 0.0.6 → 0.1.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 (96) hide show
  1. package/build.rs +4 -0
  2. package/dist/audio_frame.d.ts +1 -1
  3. package/dist/audio_frame.d.ts.map +1 -1
  4. package/dist/audio_frame.js +10 -11
  5. package/dist/audio_frame.js.map +1 -1
  6. package/dist/audio_source.d.ts +3 -3
  7. package/dist/audio_source.d.ts.map +1 -1
  8. package/dist/audio_source.js +14 -15
  9. package/dist/audio_source.js.map +1 -1
  10. package/dist/audio_stream.d.ts +4 -4
  11. package/dist/audio_stream.d.ts.map +1 -1
  12. package/dist/audio_stream.js +17 -21
  13. package/dist/audio_stream.js.map +1 -1
  14. package/dist/e2ee.d.ts +1 -1
  15. package/dist/e2ee.d.ts.map +1 -1
  16. package/dist/e2ee.js +42 -45
  17. package/dist/e2ee.js.map +1 -1
  18. package/dist/ffi_client.d.ts +2 -2
  19. package/dist/ffi_client.d.ts.map +1 -1
  20. package/dist/ffi_client.js +17 -24
  21. package/dist/ffi_client.js.map +1 -1
  22. package/dist/index.d.ts +15 -15
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +18 -70
  25. package/dist/index.js.map +1 -1
  26. package/{src/native.js → dist/napi/native.cjs} +12 -0
  27. package/dist/napi/native.js +15 -0
  28. package/dist/participant.d.ts +24 -9
  29. package/dist/participant.d.ts.map +1 -1
  30. package/dist/participant.js +45 -45
  31. package/dist/participant.js.map +1 -1
  32. package/dist/proto/audio_frame_pb.js +148 -176
  33. package/dist/proto/audio_frame_pb.js.map +1 -1
  34. package/dist/proto/e2ee_pb.js +134 -162
  35. package/dist/proto/e2ee_pb.js.map +1 -1
  36. package/dist/proto/ffi_pb.js +115 -126
  37. package/dist/proto/ffi_pb.js.map +1 -1
  38. package/dist/proto/handle_pb.js +7 -11
  39. package/dist/proto/handle_pb.js.map +1 -1
  40. package/dist/proto/participant_pb.js +13 -18
  41. package/dist/proto/participant_pb.js.map +1 -1
  42. package/dist/proto/room_pb.js +388 -454
  43. package/dist/proto/room_pb.js.map +1 -1
  44. package/dist/proto/stats_pb.js +265 -303
  45. package/dist/proto/stats_pb.js.map +1 -1
  46. package/dist/proto/track_pb.js +87 -102
  47. package/dist/proto/track_pb.js.map +1 -1
  48. package/dist/proto/video_frame_pb.js +184 -215
  49. package/dist/proto/video_frame_pb.js.map +1 -1
  50. package/dist/room.d.ts +10 -9
  51. package/dist/room.d.ts.map +1 -1
  52. package/dist/room.js +74 -77
  53. package/dist/room.js.map +1 -1
  54. package/dist/track.d.ts +4 -4
  55. package/dist/track.d.ts.map +1 -1
  56. package/dist/track.js +15 -20
  57. package/dist/track.js.map +1 -1
  58. package/dist/track_publication.d.ts +4 -4
  59. package/dist/track_publication.d.ts.map +1 -1
  60. package/dist/track_publication.js +12 -15
  61. package/dist/track_publication.js.map +1 -1
  62. package/dist/video_frame.d.ts +1 -1
  63. package/dist/video_frame.d.ts.map +1 -1
  64. package/dist/video_frame.js +57 -71
  65. package/dist/video_frame.js.map +1 -1
  66. package/dist/video_source.d.ts +3 -3
  67. package/dist/video_source.d.ts.map +1 -1
  68. package/dist/video_source.js +12 -13
  69. package/dist/video_source.js.map +1 -1
  70. package/dist/video_stream.d.ts +4 -4
  71. package/dist/video_stream.d.ts.map +1 -1
  72. package/dist/video_stream.js +18 -22
  73. package/dist/video_stream.js.map +1 -1
  74. package/package.json +14 -14
  75. package/src/audio_frame.ts +6 -2
  76. package/src/audio_source.ts +8 -4
  77. package/src/audio_stream.ts +9 -5
  78. package/src/e2ee.ts +6 -2
  79. package/src/ffi_client.ts +6 -2
  80. package/src/index.ts +19 -15
  81. package/src/lib.rs +4 -0
  82. package/src/napi/native.cjs +281 -0
  83. package/src/napi/native.js +15 -0
  84. package/src/nodejs.rs +4 -0
  85. package/src/participant.ts +45 -22
  86. package/src/room.ts +56 -49
  87. package/src/track.ts +8 -4
  88. package/src/track_publication.ts +10 -6
  89. package/src/video_frame.ts +6 -2
  90. package/src/video_source.ts +7 -3
  91. package/src/video_stream.ts +9 -5
  92. package/dist/native.d.ts.map +0 -1
  93. package/dist/native.js +0 -297
  94. package/dist/native.js.map +0 -1
  95. /package/dist/{native.d.ts → napi/native.d.ts} +0 -0
  96. /package/src/{native.d.ts → napi/native.d.ts} +0 -0
@@ -0,0 +1,281 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path');
9
+
10
+ const { platform, arch } = process;
11
+
12
+ let nativeBinding = null;
13
+ let localFileExisted = false;
14
+ let loadError = null;
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim();
21
+ return readFileSync(lddPath, 'utf8').includes('musl');
22
+ } catch (e) {
23
+ return true;
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header;
27
+ return !glibcVersionRuntime;
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.android-arm64.node'));
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./rtc-node.android-arm64.node');
39
+ } else {
40
+ nativeBinding = require('@livekit/rtc-node-android-arm64');
41
+ }
42
+ } catch (e) {
43
+ loadError = e;
44
+ }
45
+ break;
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.android-arm-eabi.node'));
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./rtc-node.android-arm-eabi.node');
51
+ } else {
52
+ nativeBinding = require('@livekit/rtc-node-android-arm-eabi');
53
+ }
54
+ } catch (e) {
55
+ loadError = e;
56
+ }
57
+ break;
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`);
60
+ }
61
+ break;
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.win32-x64-msvc.node'));
66
+ try {
67
+ if (localFileExisted) {
68
+ nativeBinding = require('./rtc-node.win32-x64-msvc.node');
69
+ } else {
70
+ nativeBinding = require('@livekit/rtc-node-win32-x64-msvc');
71
+ }
72
+ } catch (e) {
73
+ loadError = e;
74
+ }
75
+ break;
76
+ case 'ia32':
77
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.win32-ia32-msvc.node'));
78
+ try {
79
+ if (localFileExisted) {
80
+ nativeBinding = require('./rtc-node.win32-ia32-msvc.node');
81
+ } else {
82
+ nativeBinding = require('@livekit/rtc-node-win32-ia32-msvc');
83
+ }
84
+ } catch (e) {
85
+ loadError = e;
86
+ }
87
+ break;
88
+ case 'arm64':
89
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.win32-arm64-msvc.node'));
90
+ try {
91
+ if (localFileExisted) {
92
+ nativeBinding = require('./rtc-node.win32-arm64-msvc.node');
93
+ } else {
94
+ nativeBinding = require('@livekit/rtc-node-win32-arm64-msvc');
95
+ }
96
+ } catch (e) {
97
+ loadError = e;
98
+ }
99
+ break;
100
+ default:
101
+ throw new Error(`Unsupported architecture on Windows: ${arch}`);
102
+ }
103
+ break;
104
+ case 'darwin':
105
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.darwin-universal.node'));
106
+ try {
107
+ if (localFileExisted) {
108
+ nativeBinding = require('./rtc-node.darwin-universal.node');
109
+ } else {
110
+ nativeBinding = require('@livekit/rtc-node-darwin-universal');
111
+ }
112
+ break;
113
+ } catch {}
114
+ switch (arch) {
115
+ case 'x64':
116
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.darwin-x64.node'));
117
+ try {
118
+ if (localFileExisted) {
119
+ nativeBinding = require('./rtc-node.darwin-x64.node');
120
+ } else {
121
+ nativeBinding = require('@livekit/rtc-node-darwin-x64');
122
+ }
123
+ } catch (e) {
124
+ loadError = e;
125
+ }
126
+ break;
127
+ case 'arm64':
128
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.darwin-arm64.node'));
129
+ try {
130
+ if (localFileExisted) {
131
+ nativeBinding = require('./rtc-node.darwin-arm64.node');
132
+ } else {
133
+ nativeBinding = require('@livekit/rtc-node-darwin-arm64');
134
+ }
135
+ } catch (e) {
136
+ loadError = e;
137
+ }
138
+ break;
139
+ default:
140
+ throw new Error(`Unsupported architecture on macOS: ${arch}`);
141
+ }
142
+ break;
143
+ case 'freebsd':
144
+ if (arch !== 'x64') {
145
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`);
146
+ }
147
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.freebsd-x64.node'));
148
+ try {
149
+ if (localFileExisted) {
150
+ nativeBinding = require('./rtc-node.freebsd-x64.node');
151
+ } else {
152
+ nativeBinding = require('@livekit/rtc-node-freebsd-x64');
153
+ }
154
+ } catch (e) {
155
+ loadError = e;
156
+ }
157
+ break;
158
+ case 'linux':
159
+ switch (arch) {
160
+ case 'x64':
161
+ if (isMusl()) {
162
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-x64-musl.node'));
163
+ try {
164
+ if (localFileExisted) {
165
+ nativeBinding = require('./rtc-node.linux-x64-musl.node');
166
+ } else {
167
+ nativeBinding = require('@livekit/rtc-node-linux-x64-musl');
168
+ }
169
+ } catch (e) {
170
+ loadError = e;
171
+ }
172
+ } else {
173
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-x64-gnu.node'));
174
+ try {
175
+ if (localFileExisted) {
176
+ nativeBinding = require('./rtc-node.linux-x64-gnu.node');
177
+ } else {
178
+ nativeBinding = require('@livekit/rtc-node-linux-x64-gnu');
179
+ }
180
+ } catch (e) {
181
+ loadError = e;
182
+ }
183
+ }
184
+ break;
185
+ case 'arm64':
186
+ if (isMusl()) {
187
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-arm64-musl.node'));
188
+ try {
189
+ if (localFileExisted) {
190
+ nativeBinding = require('./rtc-node.linux-arm64-musl.node');
191
+ } else {
192
+ nativeBinding = require('@livekit/rtc-node-linux-arm64-musl');
193
+ }
194
+ } catch (e) {
195
+ loadError = e;
196
+ }
197
+ } else {
198
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-arm64-gnu.node'));
199
+ try {
200
+ if (localFileExisted) {
201
+ nativeBinding = require('./rtc-node.linux-arm64-gnu.node');
202
+ } else {
203
+ nativeBinding = require('@livekit/rtc-node-linux-arm64-gnu');
204
+ }
205
+ } catch (e) {
206
+ loadError = e;
207
+ }
208
+ }
209
+ break;
210
+ case 'arm':
211
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-arm-gnueabihf.node'));
212
+ try {
213
+ if (localFileExisted) {
214
+ nativeBinding = require('./rtc-node.linux-arm-gnueabihf.node');
215
+ } else {
216
+ nativeBinding = require('@livekit/rtc-node-linux-arm-gnueabihf');
217
+ }
218
+ } catch (e) {
219
+ loadError = e;
220
+ }
221
+ break;
222
+ case 'riscv64':
223
+ if (isMusl()) {
224
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-riscv64-musl.node'));
225
+ try {
226
+ if (localFileExisted) {
227
+ nativeBinding = require('./rtc-node.linux-riscv64-musl.node');
228
+ } else {
229
+ nativeBinding = require('@livekit/rtc-node-linux-riscv64-musl');
230
+ }
231
+ } catch (e) {
232
+ loadError = e;
233
+ }
234
+ } else {
235
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-riscv64-gnu.node'));
236
+ try {
237
+ if (localFileExisted) {
238
+ nativeBinding = require('./rtc-node.linux-riscv64-gnu.node');
239
+ } else {
240
+ nativeBinding = require('@livekit/rtc-node-linux-riscv64-gnu');
241
+ }
242
+ } catch (e) {
243
+ loadError = e;
244
+ }
245
+ }
246
+ break;
247
+ case 's390x':
248
+ localFileExisted = existsSync(join(__dirname, 'rtc-node.linux-s390x-gnu.node'));
249
+ try {
250
+ if (localFileExisted) {
251
+ nativeBinding = require('./rtc-node.linux-s390x-gnu.node');
252
+ } else {
253
+ nativeBinding = require('@livekit/rtc-node-linux-s390x-gnu');
254
+ }
255
+ } catch (e) {
256
+ loadError = e;
257
+ }
258
+ break;
259
+ default:
260
+ throw new Error(`Unsupported architecture on Linux: ${arch}`);
261
+ }
262
+ break;
263
+ default:
264
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`);
265
+ }
266
+
267
+ if (!nativeBinding) {
268
+ if (loadError) {
269
+ throw loadError;
270
+ }
271
+ throw new Error(`Failed to load native binding`);
272
+ }
273
+
274
+ const { livekitInitialize, livekitFfiRequest, livekitRetrievePtr, livekitCopyBuffer, FfiHandle } =
275
+ nativeBinding;
276
+
277
+ module.exports.livekitInitialize = livekitInitialize;
278
+ module.exports.livekitFfiRequest = livekitFfiRequest;
279
+ module.exports.livekitRetrievePtr = livekitRetrievePtr;
280
+ module.exports.livekitCopyBuffer = livekitCopyBuffer;
281
+ module.exports.FfiHandle = FfiHandle;
@@ -0,0 +1,15 @@
1
+ // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ // this file exists to smoothly translate the autogenerated CommonJS code
6
+ // to an ES module that plays better with TypeScript.
7
+
8
+ import native from './native.cjs';
9
+ export const {
10
+ livekitInitialize,
11
+ livekitCopyBuffer,
12
+ livekitRetrievePtr,
13
+ livekitFfiRequest,
14
+ FfiHandle,
15
+ } = native;
package/src/nodejs.rs CHANGED
@@ -1,3 +1,7 @@
1
+ // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
1
5
  use livekit_ffi::FfiHandleId;
2
6
  use livekit_ffi::{proto, server, FFI_SERVER};
3
7
  use napi::{
@@ -1,5 +1,9 @@
1
- import { FfiClient, FfiClientEvent, FfiHandle, FfiRequest } from './ffi_client';
2
- import { ParticipantInfo, OwnedParticipant } from './proto/participant_pb';
1
+ // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ import { FfiClient, FfiClientEvent, FfiHandle, FfiRequest } from './ffi_client.js';
6
+ import { ParticipantInfo, OwnedParticipant } from './proto/participant_pb.js';
3
7
  import {
4
8
  DataPacketKind,
5
9
  PublishDataCallback,
@@ -18,9 +22,13 @@ import {
18
22
  UpdateLocalNameCallback,
19
23
  UpdateLocalNameRequest,
20
24
  UpdateLocalNameResponse,
21
- } from './proto/room_pb';
22
- import { LocalTrackPublication, RemoteTrackPublication, TrackPublication } from './track_publication';
23
- import { LocalTrack } from './track';
25
+ } from './proto/room_pb.js';
26
+ import {
27
+ LocalTrackPublication,
28
+ RemoteTrackPublication,
29
+ TrackPublication,
30
+ } from './track_publication.js';
31
+ import { LocalTrack } from './track.js';
24
32
 
25
33
  export abstract class Participant {
26
34
  /** @internal */
@@ -29,7 +37,7 @@ export abstract class Participant {
29
37
  /** @internal */
30
38
  ffi_handle: FfiHandle;
31
39
 
32
- tracks = new Map<string, TrackPublication>();
40
+ trackPublications = new Map<string, TrackPublication>();
33
41
 
34
42
  constructor(owned_info: OwnedParticipant) {
35
43
  this.info = owned_info.info;
@@ -53,26 +61,41 @@ export abstract class Participant {
53
61
  }
54
62
  }
55
63
 
64
+ export type DataPublishOptions = {
65
+ /**
66
+ * whether to send this as reliable or lossy.
67
+ * For data that you need delivery guarantee (such as chat messages), use Reliable.
68
+ * For data that should arrive as quickly as possible, but you are ok with dropped
69
+ * packets, use Lossy.
70
+ */
71
+ reliable?: boolean;
72
+ /**
73
+ * the sids of participants who will receive the message, will be sent to every one if empty
74
+ */
75
+ destination?: string[] | RemoteParticipant[];
76
+ /** the topic under which the message gets published */
77
+ topic?: string;
78
+ };
79
+
56
80
  export class LocalParticipant extends Participant {
57
- tracks: Map<string, LocalTrackPublication> = new Map();
81
+ trackPublications: Map<string, LocalTrackPublication> = new Map();
58
82
 
59
- async publishData(
60
- data: Uint8Array,
61
- kind: DataPacketKind,
62
- destination_sids: Array<string | RemoteParticipant> = [], // empty = broadcast
63
- ) {
83
+ async publishData(data: Uint8Array, options: DataPublishOptions) {
64
84
  let req = new PublishDataRequest({
65
85
  localParticipantHandle: this.ffi_handle.handle,
66
86
  dataPtr: FfiClient.instance.retrievePtr(data),
67
87
  dataLen: BigInt(data.byteLength),
68
- kind: kind,
88
+ kind: options.reliable ? DataPacketKind.KIND_RELIABLE : DataPacketKind.KIND_LOSSY,
89
+ topic: options.topic,
69
90
  });
70
91
 
71
- let sids = destination_sids.map((sid) => {
72
- if (typeof sid == 'string') return sid;
73
- return sid.sid;
74
- });
75
- req.destinationSids = sids;
92
+ if (options.destination) {
93
+ const sids = options.destination.map((sid: string | RemoteParticipant) => {
94
+ if (typeof sid == 'string') return sid;
95
+ return sid.sid;
96
+ });
97
+ req.destinationSids = sids;
98
+ }
76
99
 
77
100
  let res = FfiClient.instance.request<PublishDataResponse>({
78
101
  message: { case: 'publishData', value: req },
@@ -137,7 +160,7 @@ export class LocalParticipant extends Participant {
137
160
 
138
161
  let track_publication = new LocalTrackPublication(cb.publication);
139
162
  track_publication.track = track;
140
- this.tracks.set(track_publication.sid, track_publication);
163
+ this.trackPublications.set(track_publication.sid, track_publication);
141
164
 
142
165
  return track_publication;
143
166
  }
@@ -156,14 +179,14 @@ export class LocalParticipant extends Participant {
156
179
  return ev.message.case == 'unpublishTrack' && ev.message.value.asyncId == res.asyncId;
157
180
  });
158
181
 
159
- let pub = this.tracks.get(trackSid);
182
+ let pub = this.trackPublications.get(trackSid);
160
183
  pub.track = undefined;
161
- this.tracks.delete(trackSid);
184
+ this.trackPublications.delete(trackSid);
162
185
  }
163
186
  }
164
187
 
165
188
  export class RemoteParticipant extends Participant {
166
- tracks: Map<string, RemoteTrackPublication> = new Map();
189
+ trackPublications: Map<string, RemoteTrackPublication> = new Map();
167
190
 
168
191
  constructor(owned_info: OwnedParticipant) {
169
192
  super(owned_info);
package/src/room.ts CHANGED
@@ -1,8 +1,12 @@
1
- import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client';
1
+ // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
2
6
  import EventEmitter from 'events';
3
7
  import TypedEmitter from 'typed-emitter';
4
- import { FfiEvent } from './proto/ffi_pb';
5
- import { LocalParticipant, Participant, RemoteParticipant } from './participant';
8
+ import { FfiEvent } from './proto/ffi_pb.js';
9
+ import { LocalParticipant, Participant, RemoteParticipant } from './participant.js';
6
10
  import {
7
11
  ConnectCallback,
8
12
  ConnectRequest,
@@ -15,17 +19,17 @@ import {
15
19
  IceServer,
16
20
  IceTransportType,
17
21
  RoomInfo,
18
- } from './proto/room_pb';
19
- import { E2EEManager, E2EEOptions, defaultE2EEOptions } from './e2ee';
20
- import { OwnedParticipant } from './proto/participant_pb';
22
+ } from './proto/room_pb.js';
23
+ import { E2EEManager, E2EEOptions, defaultE2EEOptions } from './e2ee.js';
24
+ import { OwnedParticipant } from './proto/participant_pb.js';
21
25
  import {
22
26
  LocalTrackPublication,
23
27
  RemoteTrackPublication,
24
28
  TrackPublication,
25
- } from './track_publication';
26
- import { LocalTrack, RemoteAudioTrack, RemoteTrack, RemoteVideoTrack } from './track';
27
- import { TrackKind } from './proto/track_pb';
28
- import { EncryptionState } from './proto/e2ee_pb';
29
+ } from './track_publication.js';
30
+ import { LocalTrack, RemoteAudioTrack, RemoteTrack, RemoteVideoTrack } from './track.js';
31
+ import { TrackKind } from './proto/track_pb.js';
32
+ import { EncryptionState } from './proto/e2ee_pb.js';
29
33
 
30
34
  export interface RtcConfiguration {
31
35
  iceTransportType: IceTransportType;
@@ -58,18 +62,13 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
58
62
  private ffiHandle?: FfiHandle;
59
63
 
60
64
  e2eeManager: E2EEManager;
61
- connection_state: ConnectionState = ConnectionState.CONN_DISCONNECTED;
65
+ connectionState: ConnectionState = ConnectionState.CONN_DISCONNECTED;
62
66
 
63
- participants: Map<string, RemoteParticipant> = new Map();
67
+ remoteParticipants: Map<string, RemoteParticipant> = new Map();
64
68
  localParticipant?: LocalParticipant;
65
69
 
66
70
  constructor() {
67
71
  super();
68
- FfiClient.instance.addListener(FfiClientEvent.FfiEvent, this.onFfiEvent);
69
- }
70
-
71
- get sid(): string {
72
- return this.info.sid;
73
72
  }
74
73
 
75
74
  get name(): string {
@@ -81,9 +80,11 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
81
80
  }
82
81
 
83
82
  get isConnected(): boolean {
84
- return (
85
- this.ffiHandle != undefined && this.connection_state != ConnectionState.CONN_DISCONNECTED
86
- );
83
+ return this.ffiHandle != undefined && this.connectionState != ConnectionState.CONN_DISCONNECTED;
84
+ }
85
+
86
+ async getSid(): Promise<string> {
87
+ return this.info.sid; // TODO update this to handle async room updates once rust protocol has been updated
87
88
  }
88
89
 
89
90
  async connect(url: string, token: string, opts?: RoomOptions) {
@@ -126,7 +127,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
126
127
  this.e2eeManager = new E2EEManager(this.ffiHandle.handle, options.e2ee);
127
128
 
128
129
  this.info = cb.room.info;
129
- this.connection_state = ConnectionState.CONN_CONNECTED;
130
+ this.connectionState = ConnectionState.CONN_CONNECTED;
130
131
  this.localParticipant = new LocalParticipant(cb.localParticipant);
131
132
 
132
133
  for (let pt of cb.participants) {
@@ -134,7 +135,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
134
135
 
135
136
  for (let pub of pt.publications) {
136
137
  let publication = new RemoteTrackPublication(pub);
137
- rp.tracks.set(publication.sid, publication);
138
+ rp.trackPublications.set(publication.sid, publication);
138
139
  }
139
140
  }
140
141
 
@@ -167,33 +168,33 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
167
168
  let ev = ffiEvent.message.value.message;
168
169
  if (ev.case == 'participantConnected') {
169
170
  let participant = this.createRemoteParticipant(ev.value.info);
170
- this.participants.set(participant.sid, participant);
171
+ this.remoteParticipants.set(participant.identity, participant);
171
172
  this.emit(RoomEvent.ParticipantConnected, participant);
172
173
  } else if (ev.case == 'participantDisconnected') {
173
- let participant = this.participants.get(ev.value.participantSid);
174
- this.participants.delete(ev.value.participantSid);
174
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
175
+ this.remoteParticipants.delete(participant.identity);
175
176
  this.emit(RoomEvent.ParticipantDisconnected, participant);
176
177
  } else if (ev.case == 'localTrackPublished') {
177
- let publication = this.localParticipant.tracks.get(ev.value.trackSid);
178
+ let publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
178
179
  this.emit(RoomEvent.LocalTrackPublished, publication, publication.track);
179
180
  } else if (ev.case == 'localTrackUnpublished') {
180
- let publication = this.localParticipant.tracks.get(ev.value.publicationSid);
181
- this.localParticipant.tracks.delete(ev.value.publicationSid);
181
+ let publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
182
+ this.localParticipant.trackPublications.delete(ev.value.publicationSid);
182
183
  this.emit(RoomEvent.LocalTrackUnpublished, publication);
183
184
  } else if (ev.case == 'trackPublished') {
184
- let participant = this.participants.get(ev.value.participantSid);
185
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
185
186
  let publication = new RemoteTrackPublication(ev.value.publication);
186
- participant.tracks.set(publication.sid, publication);
187
+ participant.trackPublications.set(publication.sid, publication);
187
188
  this.emit(RoomEvent.TrackPublished, publication, participant);
188
189
  } else if (ev.case == 'trackUnpublished') {
189
- let participant = this.participants.get(ev.value.participantSid);
190
- let publication = participant.tracks.get(ev.value.publicationSid);
191
- participant.tracks.delete(ev.value.publicationSid);
190
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
191
+ let publication = participant.trackPublications.get(ev.value.publicationSid);
192
+ participant.trackPublications.delete(ev.value.publicationSid);
192
193
  this.emit(RoomEvent.TrackUnpublished, publication, participant);
193
194
  } else if (ev.case == 'trackSubscribed') {
194
195
  let ownedTrack = ev.value.track;
195
- let participant = this.participants.get(ev.value.participantSid);
196
- let publication = participant.tracks.get(ownedTrack.info.sid);
196
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
197
+ let publication = participant.trackPublications.get(ownedTrack.info.sid);
197
198
  publication.subscribed = true;
198
199
  if (ownedTrack.info.kind == TrackKind.KIND_VIDEO) {
199
200
  publication.track = new RemoteVideoTrack(ownedTrack);
@@ -203,17 +204,17 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
203
204
 
204
205
  this.emit(RoomEvent.TrackSubscribed, publication.track, publication, participant);
205
206
  } else if (ev.case == 'trackUnsubscribed') {
206
- let participant = this.participants.get(ev.value.participantSid);
207
- let publication = participant.tracks.get(ev.value.trackSid);
207
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
208
+ let publication = participant.trackPublications.get(ev.value.trackSid);
208
209
  publication.track = undefined;
209
210
  publication.subscribed = false;
210
211
  this.emit(RoomEvent.TrackUnsubscribed, publication.track, publication, participant);
211
212
  } else if (ev.case == 'trackSubscriptionFailed') {
212
- let participant = this.participants.get(ev.value.participantSid);
213
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
213
214
  this.emit(RoomEvent.TrackSubscriptionFailed, participant, ev.value.trackSid, ev.value.error);
214
215
  } else if (ev.case == 'trackMuted') {
215
216
  let participant = this.retrieveParticipant(ev.value.participantSid);
216
- let publication = participant.tracks.get(ev.value.trackSid);
217
+ let publication = participant.trackPublications.get(ev.value.trackSid);
217
218
  publication.info.muted = true;
218
219
  if (publication.track) {
219
220
  publication.track.info.muted = true;
@@ -221,14 +222,16 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
221
222
  this.emit(RoomEvent.TrackMuted, participant, publication);
222
223
  } else if (ev.case == 'trackUnmuted') {
223
224
  let participant = this.retrieveParticipant(ev.value.participantSid);
224
- let publication = participant.tracks.get(ev.value.trackSid);
225
+ let publication = participant.trackPublications.get(ev.value.trackSid);
225
226
  publication.info.muted = false;
226
227
  if (publication.track) {
227
228
  publication.track.info.muted = false;
228
229
  }
229
230
  this.emit(RoomEvent.TrackUnmuted, participant, publication);
230
231
  } else if (ev.case == 'activeSpeakersChanged') {
231
- let activeSpeakers = ev.value.participantSids.map((sid) => this.participants.get(sid));
232
+ let activeSpeakers = ev.value.participantSids.map((sid) =>
233
+ this.getRemoteParticipantBySid(sid),
234
+ );
232
235
  this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
233
236
  } else if (ev.case == 'roomMetadataChanged') {
234
237
  let oldMetadata = this.info.metadata;
@@ -254,7 +257,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
254
257
  this.emit(RoomEvent.ConnectionQualityChanged, participant, ev.value.quality);
255
258
  } else if (ev.case == 'dataReceived') {
256
259
  // Can be undefined if the data is sent from a Server SDK
257
- let participant = this.participants.get(ev.value.participantSid);
260
+ let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
258
261
  let info = ev.value.data;
259
262
  let buffer = FfiClient.instance.copyBuffer(info.data.dataPtr, Number(info.data.dataLen));
260
263
  new FfiHandle(info.handle.id).dispose();
@@ -263,8 +266,8 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
263
266
  let participant = this.retrieveParticipant(ev.value.participantSid);
264
267
  this.emit(RoomEvent.E2EEStateChanged, participant, ev.value.state);
265
268
  } else if (ev.case == 'connectionStateChanged') {
266
- this.connection_state = ev.value.state;
267
- this.emit(RoomEvent.ConenctionStateChanged, this.connection_state);
269
+ this.connectionState = ev.value.state;
270
+ this.emit(RoomEvent.ConenctionStateChanged, this.connectionState);
268
271
  /*} else if (ev.case == 'connected') {
269
272
  this.emit(RoomEvent.Connected);*/
270
273
  } else if (ev.case == 'disconnected') {
@@ -274,23 +277,27 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
274
277
  } else if (ev.case == 'reconnected') {
275
278
  this.emit(RoomEvent.Reconnected);
276
279
  }
280
+ };
281
+
282
+ getRemoteParticipantBySid(sid: string) {
283
+ return Array.from(this.remoteParticipants.values()).find((p) => p.sid === sid);
277
284
  }
278
285
 
279
286
  private retrieveParticipant(sid: string): Participant {
280
- if (this.localParticipant.sid == sid) {
287
+ if (this.localParticipant.sid === sid) {
281
288
  return this.localParticipant;
282
289
  } else {
283
- return this.participants.get(sid);
290
+ return this.getRemoteParticipantBySid(sid);
284
291
  }
285
292
  }
286
293
 
287
294
  private createRemoteParticipant(ownedInfo: OwnedParticipant) {
288
- if (this.participants.has(ownedInfo.info.sid)) {
295
+ if (this.remoteParticipants.has(ownedInfo.info.identity)) {
289
296
  throw new Error('Participant already exists');
290
297
  }
291
298
 
292
- let participant = new RemoteParticipant(ownedInfo);
293
- this.participants.set(ownedInfo.info.sid, participant);
299
+ const participant = new RemoteParticipant(ownedInfo);
300
+ this.remoteParticipants.set(ownedInfo.info.identity, participant);
294
301
  return participant;
295
302
  }
296
303
  }
package/src/track.ts CHANGED
@@ -1,5 +1,9 @@
1
- import { AudioSource } from './audio_source';
2
- import { FfiClient, FfiHandle, FfiRequest } from './ffi_client';
1
+ // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ import { AudioSource } from './audio_source.js';
6
+ import { FfiClient, FfiHandle, FfiRequest } from './ffi_client.js';
3
7
  import {
4
8
  CreateAudioTrackRequest,
5
9
  CreateAudioTrackResponse,
@@ -9,8 +13,8 @@ import {
9
13
  StreamState,
10
14
  TrackInfo,
11
15
  TrackKind,
12
- } from './proto/track_pb';
13
- import { VideoSource } from './video_source';
16
+ } from './proto/track_pb.js';
17
+ import { VideoSource } from './video_source.js';
14
18
 
15
19
  export abstract class Track {
16
20
  /** @internal */