@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.
- package/build.rs +4 -0
- package/dist/audio_frame.d.ts +1 -1
- package/dist/audio_frame.d.ts.map +1 -1
- package/dist/audio_frame.js +10 -11
- package/dist/audio_frame.js.map +1 -1
- package/dist/audio_source.d.ts +3 -3
- package/dist/audio_source.d.ts.map +1 -1
- package/dist/audio_source.js +14 -15
- package/dist/audio_source.js.map +1 -1
- package/dist/audio_stream.d.ts +4 -4
- package/dist/audio_stream.d.ts.map +1 -1
- package/dist/audio_stream.js +17 -21
- package/dist/audio_stream.js.map +1 -1
- package/dist/e2ee.d.ts +1 -1
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/e2ee.js +42 -45
- package/dist/e2ee.js.map +1 -1
- package/dist/ffi_client.d.ts +2 -2
- package/dist/ffi_client.d.ts.map +1 -1
- package/dist/ffi_client.js +17 -24
- package/dist/ffi_client.js.map +1 -1
- package/dist/index.d.ts +15 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -70
- package/dist/index.js.map +1 -1
- package/{src/native.js → dist/napi/native.cjs} +12 -0
- package/dist/napi/native.js +15 -0
- package/dist/participant.d.ts +24 -9
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +45 -45
- package/dist/participant.js.map +1 -1
- package/dist/proto/audio_frame_pb.js +148 -176
- package/dist/proto/audio_frame_pb.js.map +1 -1
- package/dist/proto/e2ee_pb.js +134 -162
- package/dist/proto/e2ee_pb.js.map +1 -1
- package/dist/proto/ffi_pb.js +115 -126
- package/dist/proto/ffi_pb.js.map +1 -1
- package/dist/proto/handle_pb.js +7 -11
- package/dist/proto/handle_pb.js.map +1 -1
- package/dist/proto/participant_pb.js +13 -18
- package/dist/proto/participant_pb.js.map +1 -1
- package/dist/proto/room_pb.js +388 -454
- package/dist/proto/room_pb.js.map +1 -1
- package/dist/proto/stats_pb.js +265 -303
- package/dist/proto/stats_pb.js.map +1 -1
- package/dist/proto/track_pb.js +87 -102
- package/dist/proto/track_pb.js.map +1 -1
- package/dist/proto/video_frame_pb.js +184 -215
- package/dist/proto/video_frame_pb.js.map +1 -1
- package/dist/room.d.ts +10 -9
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +74 -77
- package/dist/room.js.map +1 -1
- package/dist/track.d.ts +4 -4
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +15 -20
- package/dist/track.js.map +1 -1
- package/dist/track_publication.d.ts +4 -4
- package/dist/track_publication.d.ts.map +1 -1
- package/dist/track_publication.js +12 -15
- package/dist/track_publication.js.map +1 -1
- package/dist/video_frame.d.ts +1 -1
- package/dist/video_frame.d.ts.map +1 -1
- package/dist/video_frame.js +57 -71
- package/dist/video_frame.js.map +1 -1
- package/dist/video_source.d.ts +3 -3
- package/dist/video_source.d.ts.map +1 -1
- package/dist/video_source.js +12 -13
- package/dist/video_source.js.map +1 -1
- package/dist/video_stream.d.ts +4 -4
- package/dist/video_stream.d.ts.map +1 -1
- package/dist/video_stream.js +18 -22
- package/dist/video_stream.js.map +1 -1
- package/package.json +14 -14
- package/src/audio_frame.ts +6 -2
- package/src/audio_source.ts +8 -4
- package/src/audio_stream.ts +9 -5
- package/src/e2ee.ts +6 -2
- package/src/ffi_client.ts +6 -2
- package/src/index.ts +19 -15
- package/src/lib.rs +4 -0
- package/src/napi/native.cjs +281 -0
- package/src/napi/native.js +15 -0
- package/src/nodejs.rs +4 -0
- package/src/participant.ts +45 -22
- package/src/room.ts +56 -49
- package/src/track.ts +8 -4
- package/src/track_publication.ts +10 -6
- package/src/video_frame.ts +6 -2
- package/src/video_source.ts +7 -3
- package/src/video_stream.ts +9 -5
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -297
- package/dist/native.js.map +0 -1
- /package/dist/{native.d.ts → napi/native.d.ts} +0 -0
- /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
package/src/participant.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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 {
|
|
23
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
88
|
+
kind: options.reliable ? DataPacketKind.KIND_RELIABLE : DataPacketKind.KIND_LOSSY,
|
|
89
|
+
topic: options.topic,
|
|
69
90
|
});
|
|
70
91
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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.
|
|
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.
|
|
182
|
+
let pub = this.trackPublications.get(trackSid);
|
|
160
183
|
pub.track = undefined;
|
|
161
|
-
this.
|
|
184
|
+
this.trackPublications.delete(trackSid);
|
|
162
185
|
}
|
|
163
186
|
}
|
|
164
187
|
|
|
165
188
|
export class RemoteParticipant extends Participant {
|
|
166
|
-
|
|
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
|
-
|
|
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
|
-
|
|
65
|
+
connectionState: ConnectionState = ConnectionState.CONN_DISCONNECTED;
|
|
62
66
|
|
|
63
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
174
|
-
this.
|
|
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.
|
|
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.
|
|
181
|
-
this.localParticipant.
|
|
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.
|
|
185
|
+
let participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
185
186
|
let publication = new RemoteTrackPublication(ev.value.publication);
|
|
186
|
-
participant.
|
|
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.
|
|
190
|
-
let publication = participant.
|
|
191
|
-
participant.
|
|
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.
|
|
196
|
-
let publication = participant.
|
|
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.
|
|
207
|
-
let publication = participant.
|
|
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.
|
|
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.
|
|
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.
|
|
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) =>
|
|
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.
|
|
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.
|
|
267
|
-
this.emit(RoomEvent.ConenctionStateChanged, this.
|
|
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
|
|
287
|
+
if (this.localParticipant.sid === sid) {
|
|
281
288
|
return this.localParticipant;
|
|
282
289
|
} else {
|
|
283
|
-
return this.
|
|
290
|
+
return this.getRemoteParticipantBySid(sid);
|
|
284
291
|
}
|
|
285
292
|
}
|
|
286
293
|
|
|
287
294
|
private createRemoteParticipant(ownedInfo: OwnedParticipant) {
|
|
288
|
-
if (this.
|
|
295
|
+
if (this.remoteParticipants.has(ownedInfo.info.identity)) {
|
|
289
296
|
throw new Error('Participant already exists');
|
|
290
297
|
}
|
|
291
298
|
|
|
292
|
-
|
|
293
|
-
this.
|
|
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
|
-
|
|
2
|
-
|
|
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 */
|