@livekit/rtc-node 0.13.21 → 0.13.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/async_queue.cjs +80 -0
- package/dist/async_queue.cjs.map +1 -0
- package/dist/async_queue.d.cts +30 -0
- package/dist/async_queue.d.ts +30 -0
- package/dist/async_queue.d.ts.map +1 -0
- package/dist/async_queue.js +56 -0
- package/dist/async_queue.js.map +1 -0
- package/dist/audio_frame.cjs +5 -0
- package/dist/audio_frame.cjs.map +1 -1
- package/dist/audio_frame.d.cts +3 -0
- package/dist/audio_frame.d.ts +3 -0
- package/dist/audio_frame.d.ts.map +1 -1
- package/dist/audio_frame.js +5 -0
- package/dist/audio_frame.js.map +1 -1
- package/dist/audio_mixer.cjs +281 -0
- package/dist/audio_mixer.cjs.map +1 -0
- package/dist/audio_mixer.d.cts +121 -0
- package/dist/audio_mixer.d.ts +121 -0
- package/dist/audio_mixer.d.ts.map +1 -0
- package/dist/audio_mixer.js +256 -0
- package/dist/audio_mixer.js.map +1 -0
- package/dist/audio_stream.cjs +18 -5
- package/dist/audio_stream.cjs.map +1 -1
- package/dist/audio_stream.d.cts +4 -3
- package/dist/audio_stream.d.ts +4 -3
- package/dist/audio_stream.d.ts.map +1 -1
- package/dist/audio_stream.js +18 -5
- package/dist/audio_stream.js.map +1 -1
- package/dist/data_streams/stream_reader.cjs.map +1 -1
- package/dist/data_streams/stream_reader.js.map +1 -1
- package/dist/frame_processor.cjs +38 -0
- package/dist/frame_processor.cjs.map +1 -0
- package/dist/frame_processor.d.cts +29 -0
- package/dist/frame_processor.d.ts +29 -0
- package/dist/frame_processor.d.ts.map +1 -0
- package/dist/frame_processor.js +14 -0
- package/dist/frame_processor.js.map +1 -0
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/participant.cjs +4 -4
- package/dist/participant.cjs.map +1 -1
- package/dist/participant.d.cts +2 -2
- package/dist/participant.d.ts +2 -2
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +4 -4
- package/dist/participant.js.map +1 -1
- package/dist/proto/audio_frame_pb.cjs.map +1 -1
- package/dist/proto/audio_frame_pb.js.map +1 -1
- package/dist/proto/e2ee_pb.cjs.map +1 -1
- package/dist/proto/e2ee_pb.js.map +1 -1
- package/dist/proto/ffi_pb.cjs +4 -2
- package/dist/proto/ffi_pb.cjs.map +1 -1
- package/dist/proto/ffi_pb.d.cts +13 -1
- package/dist/proto/ffi_pb.d.ts +13 -1
- package/dist/proto/ffi_pb.d.ts.map +1 -1
- package/dist/proto/ffi_pb.js +5 -3
- package/dist/proto/ffi_pb.js.map +1 -1
- package/dist/proto/handle_pb.cjs.map +1 -1
- package/dist/proto/handle_pb.js.map +1 -1
- package/dist/proto/participant_pb.cjs +26 -4
- package/dist/proto/participant_pb.cjs.map +1 -1
- package/dist/proto/participant_pb.d.cts +31 -2
- package/dist/proto/participant_pb.d.ts +31 -2
- package/dist/proto/participant_pb.d.ts.map +1 -1
- package/dist/proto/participant_pb.js +24 -3
- package/dist/proto/participant_pb.js.map +1 -1
- package/dist/proto/room_pb.cjs +29 -2
- package/dist/proto/room_pb.cjs.map +1 -1
- package/dist/proto/room_pb.d.cts +30 -7
- package/dist/proto/room_pb.d.ts +30 -7
- package/dist/proto/room_pb.d.ts.map +1 -1
- package/dist/proto/room_pb.js +28 -2
- package/dist/proto/room_pb.js.map +1 -1
- package/dist/proto/rpc_pb.cjs.map +1 -1
- package/dist/proto/rpc_pb.js.map +1 -1
- package/dist/proto/stats_pb.cjs.map +1 -1
- package/dist/proto/stats_pb.js.map +1 -1
- package/dist/proto/track_pb.cjs.map +1 -1
- package/dist/proto/track_pb.js.map +1 -1
- package/dist/proto/track_publication_pb.cjs +66 -2
- package/dist/proto/track_publication_pb.cjs.map +1 -1
- package/dist/proto/track_publication_pb.d.cts +56 -1
- package/dist/proto/track_publication_pb.d.ts +56 -1
- package/dist/proto/track_publication_pb.d.ts.map +1 -1
- package/dist/proto/track_publication_pb.js +62 -1
- package/dist/proto/track_publication_pb.js.map +1 -1
- package/dist/proto/video_frame_pb.cjs +3 -1
- package/dist/proto/video_frame_pb.cjs.map +1 -1
- package/dist/proto/video_frame_pb.d.cts +5 -1
- package/dist/proto/video_frame_pb.d.ts +5 -1
- package/dist/proto/video_frame_pb.d.ts.map +1 -1
- package/dist/proto/video_frame_pb.js +3 -1
- package/dist/proto/video_frame_pb.js.map +1 -1
- package/dist/room.cjs +286 -288
- package/dist/room.cjs.map +1 -1
- package/dist/room.d.cts +11 -11
- package/dist/room.d.ts +11 -11
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +287 -289
- package/dist/room.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +9 -8
- package/src/async_queue.test.ts +250 -0
- package/src/async_queue.ts +80 -0
- package/src/audio_frame.ts +7 -0
- package/src/audio_mixer.test.ts +167 -0
- package/src/audio_mixer.ts +407 -0
- package/src/audio_stream.ts +22 -7
- package/src/data_streams/stream_reader.ts +4 -4
- package/src/frame_processor.ts +29 -0
- package/src/index.ts +6 -0
- package/src/participant.ts +5 -5
- package/src/proto/audio_frame_pb.ts +1 -1
- package/src/proto/e2ee_pb.ts +1 -1
- package/src/proto/ffi_pb.ts +16 -2
- package/src/proto/handle_pb.ts +1 -1
- package/src/proto/participant_pb.ts +45 -1
- package/src/proto/room_pb.ts +52 -8
- package/src/proto/rpc_pb.ts +1 -1
- package/src/proto/stats_pb.ts +1 -1
- package/src/proto/track_pb.ts +1 -1
- package/src/proto/track_publication_pb.ts +105 -1
- package/src/proto/video_frame_pb.ts +7 -1
- package/src/room.ts +297 -300
- package/src/version.ts +1 -1
package/dist/room.cjs
CHANGED
|
@@ -70,7 +70,7 @@ class Room extends import_events.default {
|
|
|
70
70
|
* the local participant to acquire the lock while doing state updates related to FFI events
|
|
71
71
|
* before processing the next events
|
|
72
72
|
*/
|
|
73
|
-
this.
|
|
73
|
+
this.ffiEventLock = new import_mutex.Mutex();
|
|
74
74
|
this.byteStreamControllers = /* @__PURE__ */ new Map();
|
|
75
75
|
this.textStreamControllers = /* @__PURE__ */ new Map();
|
|
76
76
|
this.byteStreamHandlers = /* @__PURE__ */ new Map();
|
|
@@ -79,304 +79,302 @@ class Room extends import_events.default {
|
|
|
79
79
|
this.connectionState = import_room_pb.ConnectionState.CONN_DISCONNECTED;
|
|
80
80
|
this.remoteParticipants = /* @__PURE__ */ new Map();
|
|
81
81
|
this.onFfiEvent = async (ffiEvent) => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
const unlock = await this.ffiEventLock.lock();
|
|
83
|
+
try {
|
|
84
|
+
if (!this.localParticipant || !this.ffiHandle || !this.info) {
|
|
85
|
+
this.preConnectEvents.push(ffiEvent);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
for (const ev of this.preConnectEvents) {
|
|
89
|
+
await this.processFfiEvent(ev);
|
|
90
|
+
}
|
|
91
|
+
this.preConnectEvents = [];
|
|
92
|
+
await this.processFfiEvent(ffiEvent);
|
|
93
|
+
} finally {
|
|
94
|
+
unlock();
|
|
88
95
|
}
|
|
89
|
-
this.preConnectEvents = [];
|
|
90
|
-
await this.processFfiEvent(ffiEvent);
|
|
91
96
|
};
|
|
92
97
|
this.processFfiEvent = async (ffiEvent) => {
|
|
93
98
|
if (!this.localParticipant || !this.ffiHandle || !this.info) {
|
|
94
99
|
throw new Error("processFfiEvent called before connect");
|
|
95
100
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
ffiEvent.message.value.responseTimeoutMs
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
return;
|
|
110
|
-
} else if (ffiEvent.message.case != "roomEvent" || ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
|
|
111
|
-
return;
|
|
101
|
+
if (ffiEvent.message.case == "rpcMethodInvocation") {
|
|
102
|
+
if (ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle) {
|
|
103
|
+
this.localParticipant.handleRpcMethodInvocation(
|
|
104
|
+
ffiEvent.message.value.invocationId,
|
|
105
|
+
ffiEvent.message.value.method,
|
|
106
|
+
ffiEvent.message.value.requestId,
|
|
107
|
+
ffiEvent.message.value.callerIdentity,
|
|
108
|
+
ffiEvent.message.value.payload,
|
|
109
|
+
ffiEvent.message.value.responseTimeoutMs
|
|
110
|
+
);
|
|
112
111
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
return;
|
|
113
|
+
} else if (ffiEvent.message.case != "roomEvent" || ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const ev = ffiEvent.message.value.message;
|
|
117
|
+
if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {
|
|
118
|
+
console.log("Room event:", ev);
|
|
119
|
+
}
|
|
120
|
+
if (ev.case == "participantConnected") {
|
|
121
|
+
const participant = this.createRemoteParticipant(ev.value.info);
|
|
122
|
+
this.remoteParticipants.set(participant.identity, participant);
|
|
123
|
+
this.emit("participantConnected" /* ParticipantConnected */, participant);
|
|
124
|
+
} else if (ev.case == "participantDisconnected") {
|
|
125
|
+
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
126
|
+
if (participant) {
|
|
127
|
+
this.remoteParticipants.delete(participant.identity);
|
|
128
|
+
participant.info.disconnectReason = ev.value.disconnectReason;
|
|
129
|
+
this.emit("participantDisconnected" /* ParticipantDisconnected */, participant);
|
|
130
|
+
} else {
|
|
131
|
+
console.log(`RoomEvent.ParticipantDisconnected: Could not find participant`);
|
|
116
132
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
133
|
+
} else if (ev.case == "localTrackPublished") {
|
|
134
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
135
|
+
this.emit("localTrackPublished" /* LocalTrackPublished */, publication, this.localParticipant);
|
|
136
|
+
} else if (ev.case == "localTrackUnpublished") {
|
|
137
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
|
|
138
|
+
this.localParticipant.trackPublications.delete(ev.value.publicationSid);
|
|
139
|
+
this.emit("localTrackUnpublished" /* LocalTrackUnpublished */, publication, this.localParticipant);
|
|
140
|
+
} else if (ev.case == "localTrackSubscribed") {
|
|
141
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
142
|
+
if (publication) {
|
|
143
|
+
publication.resolveFirstSubscription();
|
|
144
|
+
this.emit("localTrackSubscribed" /* LocalTrackSubscribed */, publication.track);
|
|
145
|
+
} else {
|
|
146
|
+
console.warn(`RoomEvent.LocalTrackSubscribed: Publication not found: ${ev.value.trackSid}`);
|
|
147
|
+
}
|
|
148
|
+
} else if (ev.case == "trackPublished") {
|
|
149
|
+
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
150
|
+
const publication = new import_track_publication.RemoteTrackPublication(ev.value.publication);
|
|
151
|
+
if (participant) {
|
|
152
|
+
participant.trackPublications.set(publication.sid, publication);
|
|
153
|
+
} else {
|
|
154
|
+
console.warn(
|
|
155
|
+
`RoomEvent.TrackPublished: Could not find participant: ${ev.value.participantIdentity}`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
this.emit("trackPublished" /* TrackPublished */, publication, participant);
|
|
159
|
+
} else if (ev.case == "trackUnpublished") {
|
|
160
|
+
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
161
|
+
const publication = participant.trackPublications.get(ev.value.publicationSid);
|
|
162
|
+
participant.trackPublications.delete(ev.value.publicationSid);
|
|
163
|
+
if (publication) {
|
|
164
|
+
this.emit("trackUnpublished" /* TrackUnpublished */, publication, participant);
|
|
165
|
+
} else {
|
|
166
|
+
console.warn(`RoomEvent.TrackUnpublished: Could not find publication`);
|
|
167
|
+
}
|
|
168
|
+
} else if (ev.case == "trackSubscribed") {
|
|
169
|
+
const ownedTrack = ev.value.track;
|
|
170
|
+
const trackInfo = ownedTrack.info;
|
|
171
|
+
try {
|
|
172
|
+
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
173
|
+
ev.value.participantIdentity,
|
|
174
|
+
trackInfo.sid
|
|
175
|
+
);
|
|
176
|
+
publication.subscribed = true;
|
|
177
|
+
if (trackInfo.kind == import_track_pb.TrackKind.KIND_VIDEO) {
|
|
178
|
+
publication.track = new import_track.RemoteVideoTrack(ownedTrack);
|
|
179
|
+
} else if (trackInfo.kind == import_track_pb.TrackKind.KIND_AUDIO) {
|
|
180
|
+
publication.track = new import_track.RemoteAudioTrack(ownedTrack);
|
|
156
181
|
}
|
|
157
|
-
this.emit("
|
|
158
|
-
}
|
|
182
|
+
this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
console.warn(`RoomEvent.TrackSubscribed: ${e.message}`);
|
|
185
|
+
}
|
|
186
|
+
} else if (ev.case == "trackUnsubscribed") {
|
|
187
|
+
try {
|
|
188
|
+
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
189
|
+
ev.value.participantIdentity,
|
|
190
|
+
ev.value.trackSid
|
|
191
|
+
);
|
|
192
|
+
const track = publication.track;
|
|
193
|
+
publication.track = void 0;
|
|
194
|
+
publication.subscribed = false;
|
|
195
|
+
this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
|
|
196
|
+
} catch (e) {
|
|
197
|
+
console.warn(`RoomEvent.TrackUnsubscribed: ${e.message}`);
|
|
198
|
+
}
|
|
199
|
+
} else if (ev.case == "trackSubscriptionFailed") {
|
|
200
|
+
try {
|
|
159
201
|
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
} else if (trackInfo.kind == import_track_pb.TrackKind.KIND_AUDIO) {
|
|
179
|
-
publication.track = new import_track.RemoteAudioTrack(ownedTrack);
|
|
180
|
-
}
|
|
181
|
-
this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
|
|
182
|
-
} catch (e) {
|
|
183
|
-
console.warn(`RoomEvent.TrackSubscribed: ${e.message}`);
|
|
184
|
-
}
|
|
185
|
-
} else if (ev.case == "trackUnsubscribed") {
|
|
186
|
-
try {
|
|
187
|
-
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
188
|
-
ev.value.participantIdentity,
|
|
189
|
-
ev.value.trackSid
|
|
190
|
-
);
|
|
191
|
-
const track = publication.track;
|
|
192
|
-
publication.track = void 0;
|
|
193
|
-
publication.subscribed = false;
|
|
194
|
-
this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
|
|
195
|
-
} catch (e) {
|
|
196
|
-
console.warn(`RoomEvent.TrackUnsubscribed: ${e.message}`);
|
|
197
|
-
}
|
|
198
|
-
} else if (ev.case == "trackSubscriptionFailed") {
|
|
199
|
-
try {
|
|
200
|
-
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
201
|
-
this.emit(
|
|
202
|
-
"trackSubscriptionFailed" /* TrackSubscriptionFailed */,
|
|
203
|
-
ev.value.trackSid,
|
|
204
|
-
participant,
|
|
205
|
-
ev.value.error
|
|
206
|
-
);
|
|
207
|
-
} catch (e) {
|
|
208
|
-
console.warn(`RoomEvent.TrackSubscriptionFailed: ${e.message}`);
|
|
209
|
-
}
|
|
210
|
-
} else if (ev.case == "trackMuted") {
|
|
211
|
-
try {
|
|
212
|
-
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
213
|
-
ev.value.participantIdentity,
|
|
214
|
-
ev.value.trackSid
|
|
215
|
-
);
|
|
216
|
-
publication.info.muted = true;
|
|
217
|
-
if (publication.track) {
|
|
218
|
-
publication.track.info.muted = true;
|
|
219
|
-
}
|
|
220
|
-
this.emit("trackMuted" /* TrackMuted */, publication, participant);
|
|
221
|
-
} catch (e) {
|
|
222
|
-
console.warn(`RoomEvent.TrackMuted: ${e.message}`);
|
|
223
|
-
}
|
|
224
|
-
} else if (ev.case == "trackUnmuted") {
|
|
225
|
-
try {
|
|
226
|
-
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
227
|
-
ev.value.participantIdentity,
|
|
228
|
-
ev.value.trackSid
|
|
229
|
-
);
|
|
230
|
-
publication.info.muted = false;
|
|
231
|
-
if (publication.track) {
|
|
232
|
-
publication.track.info.muted = false;
|
|
233
|
-
}
|
|
234
|
-
this.emit("trackUnmuted" /* TrackUnmuted */, publication, participant);
|
|
235
|
-
} catch (e) {
|
|
236
|
-
console.warn(`RoomEvent.TrackUnmuted: ${e.message}`);
|
|
237
|
-
}
|
|
238
|
-
} else if (ev.case == "activeSpeakersChanged") {
|
|
239
|
-
try {
|
|
240
|
-
const activeSpeakers = ev.value.participantIdentities.map(
|
|
241
|
-
(identity) => this.requireParticipantByIdentity(identity)
|
|
242
|
-
);
|
|
243
|
-
this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
|
|
244
|
-
} catch (e) {
|
|
245
|
-
console.warn(`RoomEvent.ActiveSpeakersChanged: ${e.message}`);
|
|
246
|
-
}
|
|
247
|
-
} else if (ev.case == "roomMetadataChanged") {
|
|
248
|
-
this.info.metadata = ev.value.metadata ?? "";
|
|
249
|
-
this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
|
|
250
|
-
} else if (ev.case == "participantMetadataChanged") {
|
|
251
|
-
try {
|
|
252
|
-
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
253
|
-
participant.info.metadata = ev.value.metadata;
|
|
254
|
-
this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
|
|
255
|
-
} catch (e) {
|
|
256
|
-
console.warn(`RoomEvent.ParticipantMetadataChanged: ${e.message}`);
|
|
202
|
+
this.emit(
|
|
203
|
+
"trackSubscriptionFailed" /* TrackSubscriptionFailed */,
|
|
204
|
+
ev.value.trackSid,
|
|
205
|
+
participant,
|
|
206
|
+
ev.value.error
|
|
207
|
+
);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
console.warn(`RoomEvent.TrackSubscriptionFailed: ${e.message}`);
|
|
210
|
+
}
|
|
211
|
+
} else if (ev.case == "trackMuted") {
|
|
212
|
+
try {
|
|
213
|
+
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
214
|
+
ev.value.participantIdentity,
|
|
215
|
+
ev.value.trackSid
|
|
216
|
+
);
|
|
217
|
+
publication.info.muted = true;
|
|
218
|
+
if (publication.track) {
|
|
219
|
+
publication.track.info.muted = true;
|
|
257
220
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
221
|
+
this.emit("trackMuted" /* TrackMuted */, publication, participant);
|
|
222
|
+
} catch (e) {
|
|
223
|
+
console.warn(`RoomEvent.TrackMuted: ${e.message}`);
|
|
224
|
+
}
|
|
225
|
+
} else if (ev.case == "trackUnmuted") {
|
|
226
|
+
try {
|
|
227
|
+
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
228
|
+
ev.value.participantIdentity,
|
|
229
|
+
ev.value.trackSid
|
|
230
|
+
);
|
|
231
|
+
publication.info.muted = false;
|
|
232
|
+
if (publication.track) {
|
|
233
|
+
publication.track.info.muted = false;
|
|
265
234
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
235
|
+
this.emit("trackUnmuted" /* TrackUnmuted */, publication, participant);
|
|
236
|
+
} catch (e) {
|
|
237
|
+
console.warn(`RoomEvent.TrackUnmuted: ${e.message}`);
|
|
238
|
+
}
|
|
239
|
+
} else if (ev.case == "activeSpeakersChanged") {
|
|
240
|
+
try {
|
|
241
|
+
const activeSpeakers = ev.value.participantIdentities.map(
|
|
242
|
+
(identity) => this.requireParticipantByIdentity(identity)
|
|
243
|
+
);
|
|
244
|
+
this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
|
|
245
|
+
} catch (e) {
|
|
246
|
+
console.warn(`RoomEvent.ActiveSpeakersChanged: ${e.message}`);
|
|
247
|
+
}
|
|
248
|
+
} else if (ev.case == "roomMetadataChanged") {
|
|
249
|
+
this.info.metadata = ev.value.metadata ?? "";
|
|
250
|
+
this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
|
|
251
|
+
} else if (ev.case == "participantMetadataChanged") {
|
|
252
|
+
try {
|
|
253
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
254
|
+
participant.info.metadata = ev.value.metadata;
|
|
255
|
+
this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
|
|
256
|
+
} catch (e) {
|
|
257
|
+
console.warn(`RoomEvent.ParticipantMetadataChanged: ${e.message}`);
|
|
258
|
+
}
|
|
259
|
+
} else if (ev.case == "participantNameChanged") {
|
|
260
|
+
try {
|
|
261
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
262
|
+
participant.info.name = ev.value.name;
|
|
263
|
+
this.emit("participantNameChanged" /* ParticipantNameChanged */, participant.name, participant);
|
|
264
|
+
} catch (e) {
|
|
265
|
+
console.warn(`RoomEvent.ParticipantNameChanged: ${e.message}`);
|
|
266
|
+
}
|
|
267
|
+
} else if (ev.case == "participantAttributesChanged") {
|
|
268
|
+
try {
|
|
269
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
270
|
+
participant.info.attributes = ev.value.attributes.reduce(
|
|
271
|
+
(acc, value) => {
|
|
272
|
+
acc[value.key] = value.value;
|
|
273
|
+
return acc;
|
|
274
|
+
},
|
|
275
|
+
{}
|
|
276
|
+
);
|
|
277
|
+
if (Object.keys(ev.value.changedAttributes).length > 0) {
|
|
278
|
+
const changedAttributes = ev.value.changedAttributes.reduce(
|
|
270
279
|
(acc, value) => {
|
|
271
280
|
acc[value.key] = value.value;
|
|
272
281
|
return acc;
|
|
273
282
|
},
|
|
274
283
|
{}
|
|
275
284
|
);
|
|
276
|
-
|
|
277
|
-
const changedAttributes = ev.value.changedAttributes.reduce(
|
|
278
|
-
(acc, value) => {
|
|
279
|
-
acc[value.key] = value.value;
|
|
280
|
-
return acc;
|
|
281
|
-
},
|
|
282
|
-
{}
|
|
283
|
-
);
|
|
284
|
-
this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
|
|
285
|
-
}
|
|
286
|
-
} catch (e) {
|
|
287
|
-
console.warn(`RoomEvent.ParticipantAttributesChanged: ${e.message}`);
|
|
288
|
-
}
|
|
289
|
-
} else if (ev.case == "connectionQualityChanged") {
|
|
290
|
-
try {
|
|
291
|
-
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
292
|
-
this.emit("connectionQualityChanged" /* ConnectionQualityChanged */, ev.value.quality, participant);
|
|
293
|
-
} catch (e) {
|
|
294
|
-
console.warn(`RoomEvent.ConnectionQualityChanged: ${e.message}`);
|
|
295
|
-
}
|
|
296
|
-
} else if (ev.case == "chatMessage") {
|
|
297
|
-
const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
|
|
298
|
-
const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
|
|
299
|
-
const message = {
|
|
300
|
-
id,
|
|
301
|
-
message: messageText,
|
|
302
|
-
timestamp: Number(timestamp),
|
|
303
|
-
editTimestamp: Number(editTimestamp),
|
|
304
|
-
generated
|
|
305
|
-
};
|
|
306
|
-
this.emit("chatMessage" /* ChatMessage */, message, participant);
|
|
307
|
-
} else if (ev.case == "dataPacketReceived") {
|
|
308
|
-
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
309
|
-
const dataPacket = ev.value.value;
|
|
310
|
-
switch (dataPacket.case) {
|
|
311
|
-
case "user":
|
|
312
|
-
const buffer = import_ffi_client.FfiClient.instance.copyBuffer(
|
|
313
|
-
dataPacket.value.data.data.dataPtr,
|
|
314
|
-
Number(dataPacket.value.data.data.dataLen)
|
|
315
|
-
);
|
|
316
|
-
new import_ffi_client.FfiHandle(dataPacket.value.data.handle.id).dispose();
|
|
317
|
-
this.emit(
|
|
318
|
-
"dataReceived" /* DataReceived */,
|
|
319
|
-
buffer,
|
|
320
|
-
participant,
|
|
321
|
-
ev.value.kind,
|
|
322
|
-
dataPacket.value.topic
|
|
323
|
-
);
|
|
324
|
-
break;
|
|
325
|
-
case "sipDtmf":
|
|
326
|
-
const { code, digit } = dataPacket.value;
|
|
327
|
-
this.emit("dtmfReceived" /* DtmfReceived */, code, digit, participant);
|
|
328
|
-
break;
|
|
329
|
-
default:
|
|
330
|
-
break;
|
|
331
|
-
}
|
|
332
|
-
} else if (ev.case == "e2eeStateChanged") {
|
|
333
|
-
if (ev.value.state == import_e2ee_pb.EncryptionState.INTERNAL_ERROR) {
|
|
334
|
-
this.emit("encryptionError" /* EncryptionError */, new Error("internal server error"));
|
|
285
|
+
this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
|
|
335
286
|
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
this.emit("
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
try {
|
|
368
|
-
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
287
|
+
} catch (e) {
|
|
288
|
+
console.warn(`RoomEvent.ParticipantAttributesChanged: ${e.message}`);
|
|
289
|
+
}
|
|
290
|
+
} else if (ev.case == "connectionQualityChanged") {
|
|
291
|
+
try {
|
|
292
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
293
|
+
this.emit("connectionQualityChanged" /* ConnectionQualityChanged */, ev.value.quality, participant);
|
|
294
|
+
} catch (e) {
|
|
295
|
+
console.warn(`RoomEvent.ConnectionQualityChanged: ${e.message}`);
|
|
296
|
+
}
|
|
297
|
+
} else if (ev.case == "chatMessage") {
|
|
298
|
+
const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
|
|
299
|
+
const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
|
|
300
|
+
const message = {
|
|
301
|
+
id,
|
|
302
|
+
message: messageText,
|
|
303
|
+
timestamp: Number(timestamp),
|
|
304
|
+
editTimestamp: Number(editTimestamp),
|
|
305
|
+
generated
|
|
306
|
+
};
|
|
307
|
+
this.emit("chatMessage" /* ChatMessage */, message, participant);
|
|
308
|
+
} else if (ev.case == "dataPacketReceived") {
|
|
309
|
+
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
310
|
+
const dataPacket = ev.value.value;
|
|
311
|
+
switch (dataPacket.case) {
|
|
312
|
+
case "user":
|
|
313
|
+
const buffer = import_ffi_client.FfiClient.instance.copyBuffer(
|
|
314
|
+
dataPacket.value.data.data.dataPtr,
|
|
315
|
+
Number(dataPacket.value.data.data.dataLen)
|
|
316
|
+
);
|
|
317
|
+
new import_ffi_client.FfiHandle(dataPacket.value.data.handle.id).dispose();
|
|
369
318
|
this.emit(
|
|
370
|
-
"
|
|
371
|
-
|
|
372
|
-
participant
|
|
319
|
+
"dataReceived" /* DataReceived */,
|
|
320
|
+
buffer,
|
|
321
|
+
participant,
|
|
322
|
+
ev.value.kind,
|
|
323
|
+
dataPacket.value.topic
|
|
373
324
|
);
|
|
374
|
-
|
|
375
|
-
|
|
325
|
+
break;
|
|
326
|
+
case "sipDtmf":
|
|
327
|
+
const { code, digit } = dataPacket.value;
|
|
328
|
+
this.emit("dtmfReceived" /* DtmfReceived */, code, digit, participant);
|
|
329
|
+
break;
|
|
330
|
+
default:
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
} else if (ev.case == "e2eeStateChanged") {
|
|
334
|
+
if (ev.value.state == import_e2ee_pb.EncryptionState.INTERNAL_ERROR) {
|
|
335
|
+
this.emit("encryptionError" /* EncryptionError */, new Error("internal server error"));
|
|
336
|
+
}
|
|
337
|
+
} else if (ev.case == "connectionStateChanged") {
|
|
338
|
+
this.connectionState = ev.value.state;
|
|
339
|
+
this.emit("connectionStateChanged" /* ConnectionStateChanged */, this.connectionState);
|
|
340
|
+
} else if (ev.case == "disconnected") {
|
|
341
|
+
this.emit("disconnected" /* Disconnected */, ev.value.reason);
|
|
342
|
+
} else if (ev.case == "reconnecting") {
|
|
343
|
+
this.emit("reconnecting" /* Reconnecting */);
|
|
344
|
+
} else if (ev.case == "reconnected") {
|
|
345
|
+
this.emit("reconnected" /* Reconnected */);
|
|
346
|
+
} else if (ev.case == "roomSidChanged") {
|
|
347
|
+
this.emit("roomSidChanged" /* RoomSidChanged */, ev.value.sid);
|
|
348
|
+
} else if (ev.case === "streamHeaderReceived" && ev.value.header) {
|
|
349
|
+
this.handleStreamHeader(ev.value.header, ev.value.participantIdentity);
|
|
350
|
+
} else if (ev.case === "streamChunkReceived" && ev.value.chunk) {
|
|
351
|
+
this.handleStreamChunk(ev.value.chunk);
|
|
352
|
+
} else if (ev.case === "streamTrailerReceived" && ev.value.trailer) {
|
|
353
|
+
this.handleStreamTrailer(ev.value.trailer);
|
|
354
|
+
} else if (ev.case === "roomUpdated") {
|
|
355
|
+
this.info = ev.value;
|
|
356
|
+
this.emit("roomUpdated" /* RoomUpdated */);
|
|
357
|
+
} else if (ev.case === "moved") {
|
|
358
|
+
this.info = ev.value;
|
|
359
|
+
this.emit("moved" /* Moved */);
|
|
360
|
+
} else if (ev.case === "participantsUpdated") {
|
|
361
|
+
for (const info of ev.value.participants) {
|
|
362
|
+
const participant = this.retrieveParticipantByIdentity(info.identity);
|
|
363
|
+
if (participant) {
|
|
364
|
+
participant.info = info;
|
|
376
365
|
}
|
|
377
366
|
}
|
|
378
|
-
}
|
|
379
|
-
|
|
367
|
+
} else if (ev.case === "participantEncryptionStatusChanged") {
|
|
368
|
+
try {
|
|
369
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
370
|
+
this.emit(
|
|
371
|
+
"participantEncryptionStatusChanged" /* ParticipantEncryptionStatusChanged */,
|
|
372
|
+
!!ev.value.isEncrypted,
|
|
373
|
+
participant
|
|
374
|
+
);
|
|
375
|
+
} catch (e) {
|
|
376
|
+
console.warn(`RoomEvent.ParticipantEncryptionStatusChanged: ${e.message}`);
|
|
377
|
+
}
|
|
380
378
|
}
|
|
381
379
|
};
|
|
382
380
|
}
|
|
@@ -452,10 +450,10 @@ class Room extends import_events.default {
|
|
|
452
450
|
}
|
|
453
451
|
/**
|
|
454
452
|
* Connects to a LiveKit room using the provided URL and access token.
|
|
455
|
-
* @param url The WebSocket URL of the LiveKit server
|
|
456
|
-
* @param token A valid LiveKit access token for authentication
|
|
457
|
-
* @param opts Optional room configuration options
|
|
458
|
-
* @throws ConnectError if connection fails
|
|
453
|
+
* @param url - The WebSocket URL of the LiveKit server
|
|
454
|
+
* @param token - A valid LiveKit access token for authentication
|
|
455
|
+
* @param opts - Optional room configuration options
|
|
456
|
+
* @throws ConnectError - if connection fails
|
|
459
457
|
*/
|
|
460
458
|
async connect(url, token, opts) {
|
|
461
459
|
const options = { ...defaultRoomOptions, ...opts };
|
|
@@ -485,7 +483,7 @@ class Room extends import_events.default {
|
|
|
485
483
|
this.connectionState = import_room_pb.ConnectionState.CONN_CONNECTED;
|
|
486
484
|
this.localParticipant = new import_participant.LocalParticipant(
|
|
487
485
|
cb.message.value.localParticipant,
|
|
488
|
-
this.
|
|
486
|
+
this.ffiEventLock
|
|
489
487
|
);
|
|
490
488
|
for (const pt of cb.message.value.participants) {
|
|
491
489
|
const rp = this.createRemoteParticipant(pt.participant);
|
|
@@ -518,7 +516,7 @@ class Room extends import_events.default {
|
|
|
518
516
|
}
|
|
519
517
|
});
|
|
520
518
|
await import_ffi_client.FfiClient.instance.waitFor((ev) => {
|
|
521
|
-
return ev.message.case == "
|
|
519
|
+
return ev.message.case == "disconnect" && ev.message.value.asyncId == res.asyncId;
|
|
522
520
|
});
|
|
523
521
|
import_ffi_client.FfiClient.instance.removeListener(import_ffi_client.FfiClientEvent.FfiEvent, this.onFfiEvent);
|
|
524
522
|
this.removeAllListeners();
|
|
@@ -526,9 +524,9 @@ class Room extends import_events.default {
|
|
|
526
524
|
/**
|
|
527
525
|
* Registers a handler for incoming text data streams on a specific topic.
|
|
528
526
|
* Text streams are used for receiving structured text data from other participants.
|
|
529
|
-
* @param topic The topic to listen for text streams on
|
|
530
|
-
* @param callback Function to handle incoming text stream data
|
|
531
|
-
* @throws Error if a handler for this topic is already registered
|
|
527
|
+
* @param topic - The topic to listen for text streams on
|
|
528
|
+
* @param callback - Function to handle incoming text stream data
|
|
529
|
+
* @throws Error - if a handler for this topic is already registered
|
|
532
530
|
*/
|
|
533
531
|
registerTextStreamHandler(topic, callback) {
|
|
534
532
|
if (this.textStreamHandlers.has(topic)) {
|
|
@@ -542,9 +540,9 @@ class Room extends import_events.default {
|
|
|
542
540
|
/**
|
|
543
541
|
* Registers a handler for incoming byte data streams on a specific topic.
|
|
544
542
|
* Byte streams are used for receiving binary data like files from other participants.
|
|
545
|
-
* @param topic The topic to listen for byte streams on
|
|
546
|
-
* @param callback Function to handle incoming byte stream data
|
|
547
|
-
* @throws Error if a handler for this topic is already registered
|
|
543
|
+
* @param topic - The topic to listen for byte streams on
|
|
544
|
+
* @param callback - Function to handle incoming byte stream data
|
|
545
|
+
* @throws Error - if a handler for this topic is already registered
|
|
548
546
|
*/
|
|
549
547
|
registerByteStreamHandler(topic, callback) {
|
|
550
548
|
if (this.byteStreamHandlers.has(topic)) {
|