@livekit/rtc-node 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +2 -1
- package/README.md +81 -0
- package/dist/audio_frame.d.ts +2 -1
- package/dist/audio_frame.d.ts.map +1 -1
- package/dist/audio_frame.js +3 -3
- package/dist/audio_frame.js.map +1 -1
- package/dist/audio_source.d.ts +2 -2
- package/dist/audio_source.d.ts.map +1 -1
- package/dist/audio_source.js +6 -9
- package/dist/audio_source.js.map +1 -1
- package/dist/audio_stream.d.ts +3 -3
- package/dist/audio_stream.d.ts.map +1 -1
- package/dist/audio_stream.js +6 -6
- package/dist/audio_stream.js.map +1 -1
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/e2ee.js +16 -16
- package/dist/e2ee.js.map +1 -1
- package/dist/ffi_client.d.ts +3 -3
- package/dist/ffi_client.d.ts.map +1 -1
- package/dist/ffi_client.js +8 -11
- package/dist/ffi_client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/napi/native.js +1 -2
- package/dist/participant.d.ts +5 -4
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +15 -15
- package/dist/participant.js.map +1 -1
- package/dist/room.d.ts +25 -22
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +57 -55
- package/dist/room.js.map +1 -1
- package/dist/track.d.ts +3 -3
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +5 -8
- package/dist/track.js.map +1 -1
- package/dist/track_publication.d.ts +3 -3
- package/dist/track_publication.d.ts.map +1 -1
- package/dist/track_publication.js +1 -1
- package/dist/track_publication.js.map +1 -1
- package/dist/video_frame.d.ts +2 -1
- package/dist/video_frame.d.ts.map +1 -1
- package/dist/video_frame.js +1 -1
- package/dist/video_frame.js.map +1 -1
- package/dist/video_source.d.ts +3 -2
- package/dist/video_source.d.ts.map +1 -1
- package/dist/video_source.js +3 -3
- package/dist/video_source.js.map +1 -1
- package/dist/video_stream.d.ts +3 -3
- package/dist/video_stream.d.ts.map +1 -1
- package/dist/video_stream.js +8 -8
- package/dist/video_stream.js.map +1 -1
- package/package.json +9 -9
- package/src/audio_frame.ts +5 -5
- package/src/audio_source.ts +13 -14
- package/src/audio_stream.ts +13 -17
- package/src/e2ee.ts +25 -24
- package/src/ffi_client.ts +10 -11
- package/src/index.ts +1 -3
- package/src/napi/native.js +1 -2
- package/src/nodejs.rs +4 -2
- package/src/participant.ts +27 -29
- package/src/room.ts +93 -91
- package/src/track.ts +9 -11
- package/src/track_publication.ts +7 -7
- package/src/video_frame.ts +9 -16
- package/src/video_source.ts +10 -9
- package/src/video_stream.ts +17 -18
package/src/nodejs.rs
CHANGED
|
@@ -16,8 +16,8 @@ use prost::Message;
|
|
|
16
16
|
use std::sync::Arc;
|
|
17
17
|
|
|
18
18
|
#[napi(ts_args_type = "callback: (data: Uint8Array) => void, captureLogs: boolean")]
|
|
19
|
-
fn livekit_initialize(cb: JsFunction, capture_logs: bool) {
|
|
20
|
-
let tsfn: ThreadsafeFunction<proto::FfiEvent, ErrorStrategy::Fatal> = cb
|
|
19
|
+
fn livekit_initialize(env: Env, cb: JsFunction, capture_logs: bool) {
|
|
20
|
+
let mut tsfn: ThreadsafeFunction<proto::FfiEvent, ErrorStrategy::Fatal> = cb
|
|
21
21
|
.create_threadsafe_function(0, |ctx: ThreadSafeCallContext<proto::FfiEvent>| {
|
|
22
22
|
let data = ctx.value.encode_to_vec();
|
|
23
23
|
let buf = Uint8Array::new(data);
|
|
@@ -25,6 +25,8 @@ fn livekit_initialize(cb: JsFunction, capture_logs: bool) {
|
|
|
25
25
|
})
|
|
26
26
|
.unwrap();
|
|
27
27
|
|
|
28
|
+
let _ = tsfn.unref(&env);
|
|
29
|
+
|
|
28
30
|
FFI_SERVER.setup(server::FfiConfig {
|
|
29
31
|
callback_fn: Arc::new(move |event| {
|
|
30
32
|
let status = tsfn.call(event, ThreadsafeFunctionCallMode::NonBlocking);
|
package/src/participant.ts
CHANGED
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
DataPacketKind,
|
|
4
|
+
import { FfiClient, FfiHandle } from './ffi_client.js';
|
|
5
|
+
import type { OwnedParticipant, ParticipantInfo } from './proto/participant_pb.js';
|
|
6
|
+
import type {
|
|
9
7
|
PublishDataCallback,
|
|
10
|
-
PublishDataRequest,
|
|
11
8
|
PublishDataResponse,
|
|
12
9
|
PublishTrackCallback,
|
|
13
|
-
PublishTrackRequest,
|
|
14
10
|
PublishTrackResponse,
|
|
15
11
|
TrackPublishOptions,
|
|
16
12
|
UnpublishTrackCallback,
|
|
17
|
-
UnpublishTrackRequest,
|
|
18
13
|
UnpublishTrackResponse,
|
|
19
14
|
UpdateLocalMetadataCallback,
|
|
20
|
-
UpdateLocalMetadataRequest,
|
|
21
15
|
UpdateLocalMetadataResponse,
|
|
22
16
|
UpdateLocalNameCallback,
|
|
23
|
-
UpdateLocalNameRequest,
|
|
24
17
|
UpdateLocalNameResponse,
|
|
25
18
|
} from './proto/room_pb.js';
|
|
26
19
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
DataPacketKind,
|
|
21
|
+
PublishDataRequest,
|
|
22
|
+
PublishTrackRequest,
|
|
23
|
+
UnpublishTrackRequest,
|
|
24
|
+
UpdateLocalMetadataRequest,
|
|
25
|
+
UpdateLocalNameRequest,
|
|
26
|
+
} from './proto/room_pb.js';
|
|
27
|
+
import type { LocalTrack } from './track.js';
|
|
28
|
+
import type { RemoteTrackPublication, TrackPublication } from './track_publication.js';
|
|
29
|
+
import { LocalTrackPublication } from './track_publication.js';
|
|
32
30
|
|
|
33
31
|
export abstract class Participant {
|
|
34
32
|
/** @internal */
|
|
@@ -81,7 +79,7 @@ export class LocalParticipant extends Participant {
|
|
|
81
79
|
trackPublications: Map<string, LocalTrackPublication> = new Map();
|
|
82
80
|
|
|
83
81
|
async publishData(data: Uint8Array, options: DataPublishOptions) {
|
|
84
|
-
|
|
82
|
+
const req = new PublishDataRequest({
|
|
85
83
|
localParticipantHandle: this.ffi_handle.handle,
|
|
86
84
|
dataPtr: FfiClient.instance.retrievePtr(data),
|
|
87
85
|
dataLen: BigInt(data.byteLength),
|
|
@@ -97,11 +95,11 @@ export class LocalParticipant extends Participant {
|
|
|
97
95
|
req.destinationSids = sids;
|
|
98
96
|
}
|
|
99
97
|
|
|
100
|
-
|
|
98
|
+
const res = FfiClient.instance.request<PublishDataResponse>({
|
|
101
99
|
message: { case: 'publishData', value: req },
|
|
102
100
|
});
|
|
103
101
|
|
|
104
|
-
|
|
102
|
+
const cb = await FfiClient.instance.waitFor<PublishDataCallback>((ev) => {
|
|
105
103
|
return ev.message.case == 'publishData' && ev.message.value.asyncId == res.asyncId;
|
|
106
104
|
});
|
|
107
105
|
|
|
@@ -111,12 +109,12 @@ export class LocalParticipant extends Participant {
|
|
|
111
109
|
}
|
|
112
110
|
|
|
113
111
|
async updateMetadata(metadata: string) {
|
|
114
|
-
|
|
112
|
+
const req = new UpdateLocalMetadataRequest({
|
|
115
113
|
localParticipantHandle: this.ffi_handle.handle,
|
|
116
114
|
metadata: metadata,
|
|
117
115
|
});
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
const res = FfiClient.instance.request<UpdateLocalMetadataResponse>({
|
|
120
118
|
message: { case: 'updateLocalMetadata', value: req },
|
|
121
119
|
});
|
|
122
120
|
|
|
@@ -126,12 +124,12 @@ export class LocalParticipant extends Participant {
|
|
|
126
124
|
}
|
|
127
125
|
|
|
128
126
|
async updateName(name: string) {
|
|
129
|
-
|
|
127
|
+
const req = new UpdateLocalNameRequest({
|
|
130
128
|
localParticipantHandle: this.ffi_handle.handle,
|
|
131
129
|
name: name,
|
|
132
130
|
});
|
|
133
131
|
|
|
134
|
-
|
|
132
|
+
const res = FfiClient.instance.request<UpdateLocalNameResponse>({
|
|
135
133
|
message: { case: 'updateLocalName', value: req },
|
|
136
134
|
});
|
|
137
135
|
|
|
@@ -144,21 +142,21 @@ export class LocalParticipant extends Participant {
|
|
|
144
142
|
track: LocalTrack,
|
|
145
143
|
options: TrackPublishOptions,
|
|
146
144
|
): Promise<LocalTrackPublication> {
|
|
147
|
-
|
|
145
|
+
const req = new PublishTrackRequest({
|
|
148
146
|
localParticipantHandle: this.ffi_handle.handle,
|
|
149
147
|
trackHandle: track.ffi_handle.handle,
|
|
150
148
|
options: options,
|
|
151
149
|
});
|
|
152
150
|
|
|
153
|
-
|
|
151
|
+
const res = FfiClient.instance.request<PublishTrackResponse>({
|
|
154
152
|
message: { case: 'publishTrack', value: req },
|
|
155
153
|
});
|
|
156
154
|
|
|
157
|
-
|
|
155
|
+
const cb = await FfiClient.instance.waitFor<PublishTrackCallback>((ev) => {
|
|
158
156
|
return ev.message.case == 'publishTrack' && ev.message.value.asyncId == res.asyncId;
|
|
159
157
|
});
|
|
160
158
|
|
|
161
|
-
|
|
159
|
+
const track_publication = new LocalTrackPublication(cb.publication);
|
|
162
160
|
track_publication.track = track;
|
|
163
161
|
this.trackPublications.set(track_publication.sid, track_publication);
|
|
164
162
|
|
|
@@ -166,12 +164,12 @@ export class LocalParticipant extends Participant {
|
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
async unpublishTrack(trackSid: string) {
|
|
169
|
-
|
|
167
|
+
const req = new UnpublishTrackRequest({
|
|
170
168
|
localParticipantHandle: this.ffi_handle.handle,
|
|
171
169
|
trackSid: trackSid,
|
|
172
170
|
});
|
|
173
171
|
|
|
174
|
-
|
|
172
|
+
const res = FfiClient.instance.request<UnpublishTrackResponse>({
|
|
175
173
|
message: { case: 'unpublishTrack', value: req },
|
|
176
174
|
});
|
|
177
175
|
|
|
@@ -179,7 +177,7 @@ export class LocalParticipant extends Participant {
|
|
|
179
177
|
return ev.message.case == 'unpublishTrack' && ev.message.value.asyncId == res.asyncId;
|
|
180
178
|
});
|
|
181
179
|
|
|
182
|
-
|
|
180
|
+
const pub = this.trackPublications.get(trackSid);
|
|
183
181
|
pub.track = undefined;
|
|
184
182
|
this.trackPublications.delete(trackSid);
|
|
185
183
|
}
|
package/src/room.ts
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
|
-
import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
|
|
6
4
|
import EventEmitter from 'events';
|
|
7
|
-
import TypedEmitter from 'typed-emitter';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
5
|
+
import type TypedEmitter from 'typed-emitter';
|
|
6
|
+
import type { E2EEOptions } from './e2ee.js';
|
|
7
|
+
import { E2EEManager } from './e2ee.js';
|
|
8
|
+
import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
|
|
9
|
+
import type { Participant } from './participant.js';
|
|
10
|
+
import { LocalParticipant, RemoteParticipant } from './participant.js';
|
|
11
|
+
import { EncryptionState } from './proto/e2ee_pb.js';
|
|
12
|
+
import type { FfiEvent } from './proto/ffi_pb.js';
|
|
13
|
+
import type { OwnedParticipant } from './proto/participant_pb.js';
|
|
14
|
+
import type {
|
|
11
15
|
ConnectCallback,
|
|
12
|
-
ConnectRequest,
|
|
13
16
|
ConnectResponse,
|
|
14
17
|
ConnectionQuality,
|
|
15
|
-
ConnectionState,
|
|
16
|
-
ContinualGatheringPolicy,
|
|
17
18
|
DataPacketKind,
|
|
18
19
|
DisconnectResponse,
|
|
19
20
|
IceServer,
|
|
20
|
-
IceTransportType,
|
|
21
21
|
RoomInfo,
|
|
22
22
|
} from './proto/room_pb.js';
|
|
23
|
-
import { E2EEManager, E2EEOptions, defaultE2EEOptions } from './e2ee.js';
|
|
24
|
-
import { OwnedParticipant } from './proto/participant_pb.js';
|
|
25
23
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
ConnectRequest,
|
|
25
|
+
ConnectionState,
|
|
26
|
+
ContinualGatheringPolicy,
|
|
27
|
+
IceTransportType,
|
|
28
|
+
} from './proto/room_pb.js';
|
|
31
29
|
import { TrackKind } from './proto/track_pb.js';
|
|
32
|
-
import {
|
|
30
|
+
import type { RemoteTrack } from './track.js';
|
|
31
|
+
import { RemoteAudioTrack, RemoteVideoTrack } from './track.js';
|
|
32
|
+
import type { LocalTrackPublication, TrackPublication } from './track_publication.js';
|
|
33
|
+
import { RemoteTrackPublication } from './track_publication.js';
|
|
33
34
|
|
|
34
35
|
export interface RtcConfiguration {
|
|
35
36
|
iceTransportType: IceTransportType;
|
|
@@ -90,7 +91,7 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
|
|
|
90
91
|
async connect(url: string, token: string, opts?: RoomOptions) {
|
|
91
92
|
const options = { ...defaultRoomOptions, ...opts };
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
const req = new ConnectRequest({
|
|
94
95
|
url: url,
|
|
95
96
|
token: token,
|
|
96
97
|
options: {
|
|
@@ -108,14 +109,14 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
|
|
|
108
109
|
},
|
|
109
110
|
});
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
const res = FfiClient.instance.request<ConnectResponse>({
|
|
112
113
|
message: {
|
|
113
114
|
case: 'connect',
|
|
114
115
|
value: req,
|
|
115
116
|
},
|
|
116
117
|
});
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
const cb = await FfiClient.instance.waitFor<ConnectCallback>((ev: FfiEvent) => {
|
|
119
120
|
return ev.message.case == 'connect' && ev.message.value.asyncId == res.asyncId;
|
|
120
121
|
});
|
|
121
122
|
|
|
@@ -130,11 +131,11 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
|
|
|
130
131
|
this.connectionState = ConnectionState.CONN_CONNECTED;
|
|
131
132
|
this.localParticipant = new LocalParticipant(cb.localParticipant);
|
|
132
133
|
|
|
133
|
-
for (
|
|
134
|
-
|
|
134
|
+
for (const pt of cb.participants) {
|
|
135
|
+
const rp = this.createRemoteParticipant(pt.participant);
|
|
135
136
|
|
|
136
|
-
for (
|
|
137
|
-
|
|
137
|
+
for (const pub of pt.publications) {
|
|
138
|
+
const publication = new RemoteTrackPublication(pub);
|
|
138
139
|
rp.trackPublications.set(publication.sid, publication);
|
|
139
140
|
}
|
|
140
141
|
}
|
|
@@ -155,6 +156,9 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
|
|
|
155
156
|
},
|
|
156
157
|
},
|
|
157
158
|
});
|
|
159
|
+
|
|
160
|
+
FfiClient.instance.removeAllListeners();
|
|
161
|
+
this.removeAllListeners();
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
private onFfiEvent = (ffiEvent: FfiEvent) => {
|
|
@@ -165,36 +169,36 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
|
|
|
165
169
|
return;
|
|
166
170
|
}
|
|
167
171
|
|
|
168
|
-
|
|
172
|
+
const ev = ffiEvent.message.value.message;
|
|
169
173
|
if (ev.case == 'participantConnected') {
|
|
170
|
-
|
|
174
|
+
const participant = this.createRemoteParticipant(ev.value.info);
|
|
171
175
|
this.remoteParticipants.set(participant.identity, participant);
|
|
172
176
|
this.emit(RoomEvent.ParticipantConnected, participant);
|
|
173
177
|
} else if (ev.case == 'participantDisconnected') {
|
|
174
|
-
|
|
178
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
175
179
|
this.remoteParticipants.delete(participant.identity);
|
|
176
180
|
this.emit(RoomEvent.ParticipantDisconnected, participant);
|
|
177
181
|
} else if (ev.case == 'localTrackPublished') {
|
|
178
|
-
|
|
179
|
-
this.emit(RoomEvent.LocalTrackPublished, publication,
|
|
182
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
183
|
+
this.emit(RoomEvent.LocalTrackPublished, publication, this.localParticipant);
|
|
180
184
|
} else if (ev.case == 'localTrackUnpublished') {
|
|
181
|
-
|
|
185
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
|
|
182
186
|
this.localParticipant.trackPublications.delete(ev.value.publicationSid);
|
|
183
|
-
this.emit(RoomEvent.LocalTrackUnpublished, publication);
|
|
187
|
+
this.emit(RoomEvent.LocalTrackUnpublished, publication, this.localParticipant);
|
|
184
188
|
} else if (ev.case == 'trackPublished') {
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
190
|
+
const publication = new RemoteTrackPublication(ev.value.publication);
|
|
187
191
|
participant.trackPublications.set(publication.sid, publication);
|
|
188
192
|
this.emit(RoomEvent.TrackPublished, publication, participant);
|
|
189
193
|
} else if (ev.case == 'trackUnpublished') {
|
|
190
|
-
|
|
191
|
-
|
|
194
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
195
|
+
const publication = participant.trackPublications.get(ev.value.publicationSid);
|
|
192
196
|
participant.trackPublications.delete(ev.value.publicationSid);
|
|
193
197
|
this.emit(RoomEvent.TrackUnpublished, publication, participant);
|
|
194
198
|
} else if (ev.case == 'trackSubscribed') {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
199
|
+
const ownedTrack = ev.value.track;
|
|
200
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
201
|
+
const publication = participant.trackPublications.get(ownedTrack.info.sid);
|
|
198
202
|
publication.subscribed = true;
|
|
199
203
|
if (ownedTrack.info.kind == TrackKind.KIND_VIDEO) {
|
|
200
204
|
publication.track = new RemoteVideoTrack(ownedTrack);
|
|
@@ -204,70 +208,64 @@ export class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>
|
|
|
204
208
|
|
|
205
209
|
this.emit(RoomEvent.TrackSubscribed, publication.track, publication, participant);
|
|
206
210
|
} else if (ev.case == 'trackUnsubscribed') {
|
|
207
|
-
|
|
208
|
-
|
|
211
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
212
|
+
const publication = participant.trackPublications.get(ev.value.trackSid);
|
|
209
213
|
publication.track = undefined;
|
|
210
214
|
publication.subscribed = false;
|
|
211
215
|
this.emit(RoomEvent.TrackUnsubscribed, publication.track, publication, participant);
|
|
212
216
|
} else if (ev.case == 'trackSubscriptionFailed') {
|
|
213
|
-
|
|
214
|
-
this.emit(RoomEvent.TrackSubscriptionFailed,
|
|
217
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
218
|
+
this.emit(RoomEvent.TrackSubscriptionFailed, ev.value.trackSid, participant, ev.value.error);
|
|
215
219
|
} else if (ev.case == 'trackMuted') {
|
|
216
|
-
|
|
217
|
-
|
|
220
|
+
const participant = this.retrieveParticipant(ev.value.participantSid);
|
|
221
|
+
const publication = participant.trackPublications.get(ev.value.trackSid);
|
|
218
222
|
publication.info.muted = true;
|
|
219
223
|
if (publication.track) {
|
|
220
224
|
publication.track.info.muted = true;
|
|
221
225
|
}
|
|
222
|
-
this.emit(RoomEvent.TrackMuted,
|
|
226
|
+
this.emit(RoomEvent.TrackMuted, publication, participant);
|
|
223
227
|
} else if (ev.case == 'trackUnmuted') {
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
const participant = this.retrieveParticipant(ev.value.participantSid);
|
|
229
|
+
const publication = participant.trackPublications.get(ev.value.trackSid);
|
|
226
230
|
publication.info.muted = false;
|
|
227
231
|
if (publication.track) {
|
|
228
232
|
publication.track.info.muted = false;
|
|
229
233
|
}
|
|
230
|
-
this.emit(RoomEvent.TrackUnmuted,
|
|
234
|
+
this.emit(RoomEvent.TrackUnmuted, publication, participant);
|
|
231
235
|
} else if (ev.case == 'activeSpeakersChanged') {
|
|
232
|
-
|
|
236
|
+
const activeSpeakers = ev.value.participantSids.map((sid) =>
|
|
233
237
|
this.getRemoteParticipantBySid(sid),
|
|
234
238
|
);
|
|
235
239
|
this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);
|
|
236
240
|
} else if (ev.case == 'roomMetadataChanged') {
|
|
237
|
-
let oldMetadata = this.info.metadata;
|
|
238
241
|
this.info.metadata = ev.value.metadata;
|
|
239
|
-
this.emit(RoomEvent.RoomMetadataChanged,
|
|
242
|
+
this.emit(RoomEvent.RoomMetadataChanged, this.info.metadata);
|
|
240
243
|
} else if (ev.case == 'participantMetadataChanged') {
|
|
241
|
-
|
|
242
|
-
let oldMetadata = participant.metadata;
|
|
244
|
+
const participant = this.retrieveParticipant(ev.value.participantSid);
|
|
243
245
|
participant.info.metadata = ev.value.metadata;
|
|
244
|
-
this.emit(
|
|
245
|
-
RoomEvent.ParticipantMetadataChanged,
|
|
246
|
-
participant,
|
|
247
|
-
oldMetadata,
|
|
248
|
-
participant.metadata,
|
|
249
|
-
);
|
|
246
|
+
this.emit(RoomEvent.ParticipantMetadataChanged, participant.metadata, participant);
|
|
250
247
|
} else if (ev.case == 'participantNameChanged') {
|
|
251
|
-
|
|
252
|
-
let oldName = participant.name;
|
|
248
|
+
const participant = this.retrieveParticipant(ev.value.participantSid);
|
|
253
249
|
participant.info.name = ev.value.name;
|
|
254
|
-
this.emit(RoomEvent.ParticipantNameChanged, participant,
|
|
250
|
+
this.emit(RoomEvent.ParticipantNameChanged, participant.name, participant);
|
|
255
251
|
} else if (ev.case == 'connectionQualityChanged') {
|
|
256
|
-
|
|
257
|
-
this.emit(RoomEvent.ConnectionQualityChanged,
|
|
252
|
+
const participant = this.retrieveParticipant(ev.value.participantSid);
|
|
253
|
+
this.emit(RoomEvent.ConnectionQualityChanged, ev.value.quality, participant);
|
|
258
254
|
} else if (ev.case == 'dataReceived') {
|
|
259
255
|
// Can be undefined if the data is sent from a Server SDK
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
256
|
+
const participant = this.getRemoteParticipantBySid(ev.value.participantSid);
|
|
257
|
+
const info = ev.value.data;
|
|
258
|
+
const buffer = FfiClient.instance.copyBuffer(info.data.dataPtr, Number(info.data.dataLen));
|
|
263
259
|
new FfiHandle(info.handle.id).dispose();
|
|
264
|
-
this.emit(RoomEvent.DataReceived, buffer, ev.value.kind,
|
|
260
|
+
this.emit(RoomEvent.DataReceived, buffer, participant, ev.value.kind, ev.value.topic);
|
|
265
261
|
} else if (ev.case == 'e2eeStateChanged') {
|
|
266
|
-
|
|
267
|
-
|
|
262
|
+
if (ev.value.state == EncryptionState.INTERNAL_ERROR) {
|
|
263
|
+
// throw generic error until Rust SDK is updated to supply the error alongside INTERNAL_ERROR
|
|
264
|
+
this.emit(RoomEvent.EncryptionError, new Error('internal server error'));
|
|
265
|
+
}
|
|
268
266
|
} else if (ev.case == 'connectionStateChanged') {
|
|
269
267
|
this.connectionState = ev.value.state;
|
|
270
|
-
this.emit(RoomEvent.
|
|
268
|
+
this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);
|
|
271
269
|
/*} else if (ev.case == 'connected') {
|
|
272
270
|
this.emit(RoomEvent.Connected);*/
|
|
273
271
|
} else if (ev.case == 'disconnected') {
|
|
@@ -311,8 +309,11 @@ export class ConnectError extends Error {
|
|
|
311
309
|
export type RoomCallbacks = {
|
|
312
310
|
participantConnected: (participant: RemoteParticipant) => void;
|
|
313
311
|
participantDisconnected: (participant: RemoteParticipant) => void;
|
|
314
|
-
localTrackPublished: (publication: LocalTrackPublication,
|
|
315
|
-
localTrackUnpublished: (
|
|
312
|
+
localTrackPublished: (publication: LocalTrackPublication, participant: LocalParticipant) => void;
|
|
313
|
+
localTrackUnpublished: (
|
|
314
|
+
publication: LocalTrackPublication,
|
|
315
|
+
participant: LocalParticipant,
|
|
316
|
+
) => void;
|
|
316
317
|
trackPublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;
|
|
317
318
|
trackUnpublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;
|
|
318
319
|
trackSubscribed: (
|
|
@@ -326,26 +327,27 @@ export type RoomCallbacks = {
|
|
|
326
327
|
participant: RemoteParticipant,
|
|
327
328
|
) => void;
|
|
328
329
|
trackSubscriptionFailed: (
|
|
330
|
+
trackSid: string,
|
|
329
331
|
participant: RemoteParticipant,
|
|
330
|
-
|
|
331
|
-
error: string,
|
|
332
|
+
reason?: string,
|
|
332
333
|
) => void;
|
|
333
|
-
trackMuted: (
|
|
334
|
-
trackUnmuted: (
|
|
335
|
-
activeSpeakersChanged: (speakers:
|
|
336
|
-
roomMetadataChanged: (
|
|
337
|
-
participantMetadataChanged: (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
334
|
+
trackMuted: (publication: TrackPublication, participant: Participant) => void;
|
|
335
|
+
trackUnmuted: (publication: TrackPublication, participant: Participant) => void;
|
|
336
|
+
activeSpeakersChanged: (speakers: Participant[]) => void;
|
|
337
|
+
roomMetadataChanged: (metadata: string) => void;
|
|
338
|
+
participantMetadataChanged: (metadata: string | undefined, participant: Participant) => void;
|
|
339
|
+
participantNameChanged: (name: string, participant: Participant) => void;
|
|
340
|
+
connectionQualityChanged: (quality: ConnectionQuality, participant: Participant) => void;
|
|
341
|
+
dataReceived: (
|
|
342
|
+
payload: Uint8Array,
|
|
343
|
+
participant?: RemoteParticipant,
|
|
344
|
+
kind?: DataPacketKind,
|
|
345
|
+
topic?: string,
|
|
341
346
|
) => void;
|
|
342
|
-
|
|
343
|
-
connectionQualityChanged: (participant: Participant, quality: ConnectionQuality) => void;
|
|
344
|
-
dataReceived: (data: Uint8Array, kind: DataPacketKind, participant?: RemoteParticipant) => void;
|
|
345
|
-
e2eeStateChanged: (participant: Participant, state: EncryptionState) => void;
|
|
347
|
+
encryptionError: (error: Error) => void;
|
|
346
348
|
connectionStateChanged: (state: ConnectionState) => void;
|
|
347
349
|
connected: () => void;
|
|
348
|
-
disconnected: () => void;
|
|
350
|
+
disconnected: (reason?: string) => void;
|
|
349
351
|
reconnecting: () => void;
|
|
350
352
|
reconnected: () => void;
|
|
351
353
|
};
|
|
@@ -368,8 +370,8 @@ export enum RoomEvent {
|
|
|
368
370
|
ParticipantNameChanged = 'participantNameChanged',
|
|
369
371
|
ConnectionQualityChanged = 'connectionQualityChanged',
|
|
370
372
|
DataReceived = 'dataReceived',
|
|
371
|
-
|
|
372
|
-
|
|
373
|
+
EncryptionError = 'encryptionError',
|
|
374
|
+
ConnectionStateChanged = 'connectionStateChanged',
|
|
373
375
|
Connected = 'connected',
|
|
374
376
|
Disconnected = 'disconnected',
|
|
375
377
|
Reconnecting = 'reconnecting',
|
package/src/track.ts
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
CreateAudioTrackRequest,
|
|
4
|
+
import type { AudioSource } from './audio_source.js';
|
|
5
|
+
import { FfiClient, FfiHandle } from './ffi_client.js';
|
|
6
|
+
import type {
|
|
9
7
|
CreateAudioTrackResponse,
|
|
10
|
-
CreateVideoTrackRequest,
|
|
11
8
|
CreateVideoTrackResponse,
|
|
12
9
|
OwnedTrack,
|
|
13
10
|
StreamState,
|
|
14
11
|
TrackInfo,
|
|
15
12
|
TrackKind,
|
|
16
13
|
} from './proto/track_pb.js';
|
|
17
|
-
import {
|
|
14
|
+
import { CreateAudioTrackRequest, CreateVideoTrackRequest } from './proto/track_pb.js';
|
|
15
|
+
import type { VideoSource } from './video_source.js';
|
|
18
16
|
|
|
19
17
|
export abstract class Track {
|
|
20
18
|
/** @internal */
|
|
@@ -55,12 +53,12 @@ export class LocalAudioTrack extends Track {
|
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
static createAudioTrack(name: string, source: AudioSource): LocalAudioTrack {
|
|
58
|
-
|
|
56
|
+
const req = new CreateAudioTrackRequest({
|
|
59
57
|
name: name,
|
|
60
58
|
sourceHandle: source.ffiHandle.handle,
|
|
61
59
|
});
|
|
62
60
|
|
|
63
|
-
|
|
61
|
+
const res = FfiClient.instance.request<CreateAudioTrackResponse>({
|
|
64
62
|
message: { case: 'createAudioTrack', value: req },
|
|
65
63
|
});
|
|
66
64
|
|
|
@@ -74,12 +72,12 @@ export class LocalVideoTrack extends Track {
|
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
static createVideoTrack(name: string, source: VideoSource): LocalVideoTrack {
|
|
77
|
-
|
|
75
|
+
const req = new CreateVideoTrackRequest({
|
|
78
76
|
name: name,
|
|
79
77
|
sourceHandle: source.ffiHandle.handle,
|
|
80
78
|
});
|
|
81
79
|
|
|
82
|
-
|
|
80
|
+
const res = FfiClient.instance.request<CreateVideoTrackResponse>({
|
|
83
81
|
message: { case: 'createVideoTrack', value: req },
|
|
84
82
|
});
|
|
85
83
|
|
package/src/track_publication.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
|
-
import { FfiClient, FfiRequest } from './ffi_client.js';
|
|
4
|
+
import { FfiClient } from './ffi_client.js';
|
|
6
5
|
import { FfiHandle } from './napi/native.js';
|
|
7
|
-
import { EncryptionType } from './proto/e2ee_pb.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import type { EncryptionType } from './proto/e2ee_pb.js';
|
|
7
|
+
import type { SetSubscribedResponse } from './proto/room_pb.js';
|
|
8
|
+
import { SetSubscribedRequest } from './proto/room_pb.js';
|
|
9
|
+
import type {
|
|
10
10
|
OwnedTrackPublication,
|
|
11
11
|
TrackKind,
|
|
12
12
|
TrackPublicationInfo,
|
|
13
13
|
TrackSource,
|
|
14
14
|
} from './proto/track_pb.js';
|
|
15
|
-
import { Track } from './track.js';
|
|
15
|
+
import type { Track } from './track.js';
|
|
16
16
|
|
|
17
17
|
export abstract class TrackPublication {
|
|
18
18
|
/** @internal */
|
|
@@ -82,7 +82,7 @@ export class RemoteTrackPublication extends TrackPublication {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
setSubscribed(subscribed: boolean) {
|
|
85
|
-
|
|
85
|
+
const req = new SetSubscribedRequest({
|
|
86
86
|
subscribe: subscribed,
|
|
87
87
|
publicationHandle: this.ffiHandle.handle,
|
|
88
88
|
});
|
package/src/video_frame.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
|
|
5
|
-
import {
|
|
4
|
+
import { FfiClient, FfiRequest } from './ffi_client.js';
|
|
5
|
+
import type { OwnedVideoBuffer, VideoConvertResponse } from './proto/video_frame_pb.js';
|
|
6
6
|
import {
|
|
7
|
-
OwnedVideoBuffer,
|
|
8
7
|
VideoBufferInfo,
|
|
9
8
|
VideoBufferInfo_ComponentInfo,
|
|
10
9
|
VideoBufferType,
|
|
11
|
-
VideoConvertResponse,
|
|
12
10
|
} from './proto/video_frame_pb.js';
|
|
13
11
|
|
|
14
12
|
export class VideoFrame {
|
|
@@ -17,12 +15,7 @@ export class VideoFrame {
|
|
|
17
15
|
height: number;
|
|
18
16
|
type: VideoBufferType;
|
|
19
17
|
|
|
20
|
-
constructor(
|
|
21
|
-
data: Uint8Array,
|
|
22
|
-
width: number,
|
|
23
|
-
height: number,
|
|
24
|
-
type: VideoBufferType,
|
|
25
|
-
) {
|
|
18
|
+
constructor(data: Uint8Array, width: number, height: number, type: VideoBufferType) {
|
|
26
19
|
this.data = data;
|
|
27
20
|
this.width = width;
|
|
28
21
|
this.height = height;
|
|
@@ -31,7 +24,7 @@ export class VideoFrame {
|
|
|
31
24
|
|
|
32
25
|
/** @internal */
|
|
33
26
|
get dataPtr(): bigint {
|
|
34
|
-
return FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer))
|
|
27
|
+
return FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer));
|
|
35
28
|
}
|
|
36
29
|
|
|
37
30
|
/** @internal */
|
|
@@ -60,7 +53,7 @@ export class VideoFrame {
|
|
|
60
53
|
|
|
61
54
|
/** @internal */
|
|
62
55
|
static fromOwnedInfo(owned: OwnedVideoBuffer): VideoFrame {
|
|
63
|
-
|
|
56
|
+
const info = owned.info;
|
|
64
57
|
return new VideoFrame(
|
|
65
58
|
FfiClient.instance.copyBuffer(
|
|
66
59
|
info.dataPtr,
|
|
@@ -73,7 +66,7 @@ export class VideoFrame {
|
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
getPlane(planeNth: number): Uint8Array | void {
|
|
76
|
-
const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height)
|
|
69
|
+
const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height);
|
|
77
70
|
if (planeNth >= planeInfos.length) return;
|
|
78
71
|
|
|
79
72
|
const planeInfo = planeInfos[planeNth];
|
|
@@ -91,12 +84,12 @@ export class VideoFrame {
|
|
|
91
84
|
},
|
|
92
85
|
},
|
|
93
86
|
});
|
|
94
|
-
const resp = FfiClient.instance.request<VideoConvertResponse>(req)
|
|
87
|
+
const resp = FfiClient.instance.request<VideoConvertResponse>(req);
|
|
95
88
|
if (resp.error) {
|
|
96
|
-
throw resp.error
|
|
89
|
+
throw resp.error;
|
|
97
90
|
}
|
|
98
91
|
|
|
99
|
-
return VideoFrame.fromOwnedInfo(resp.buffer)
|
|
92
|
+
return VideoFrame.fromOwnedInfo(resp.buffer);
|
|
100
93
|
}
|
|
101
94
|
}
|
|
102
95
|
|