@livekit/rtc-node 0.13.19 → 0.13.21
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 +6 -3
- package/dist/audio_source.cjs +1 -0
- package/dist/audio_source.cjs.map +1 -1
- package/dist/audio_source.d.ts.map +1 -1
- package/dist/audio_source.js +1 -0
- package/dist/audio_source.js.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/participant.cjs +43 -32
- package/dist/participant.cjs.map +1 -1
- package/dist/participant.d.cts +3 -0
- package/dist/participant.d.ts +3 -0
- package/dist/participant.d.ts.map +1 -1
- package/dist/participant.js +43 -32
- package/dist/participant.js.map +1 -1
- package/dist/proto/data_stream_pb.cjs +91 -2
- package/dist/proto/data_stream_pb.cjs.map +1 -1
- package/dist/proto/data_stream_pb.d.cts +92 -1
- package/dist/proto/data_stream_pb.d.ts +92 -1
- package/dist/proto/data_stream_pb.d.ts.map +1 -1
- package/dist/proto/data_stream_pb.js +88 -2
- package/dist/proto/data_stream_pb.js.map +1 -1
- package/dist/proto/ffi_pb.cjs +6 -3
- package/dist/proto/ffi_pb.cjs.map +1 -1
- package/dist/proto/ffi_pb.d.cts +19 -1
- package/dist/proto/ffi_pb.d.ts +19 -1
- package/dist/proto/ffi_pb.d.ts.map +1 -1
- package/dist/proto/ffi_pb.js +7 -4
- package/dist/proto/ffi_pb.js.map +1 -1
- package/dist/proto/room_pb.cjs +32 -2
- package/dist/proto/room_pb.cjs.map +1 -1
- package/dist/proto/room_pb.d.cts +38 -2
- package/dist/proto/room_pb.d.ts +38 -2
- package/dist/proto/room_pb.d.ts.map +1 -1
- package/dist/proto/room_pb.js +31 -2
- package/dist/proto/room_pb.js.map +1 -1
- package/dist/room.cjs +300 -205
- package/dist/room.cjs.map +1 -1
- package/dist/room.d.cts +16 -3
- package/dist/room.d.ts +16 -3
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +301 -206
- 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 +6 -6
- package/src/audio_source.ts +1 -0
- package/src/participant.ts +48 -30
- package/src/proto/data_stream_pb.ts +159 -0
- package/src/proto/ffi_pb.ts +22 -1
- package/src/proto/room_pb.ts +64 -1
- package/src/room.ts +319 -214
- package/src/version.ts +1 -1
package/dist/room.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { Mutex } from "@livekit/mutex";
|
|
1
2
|
import EventEmitter from "events";
|
|
2
3
|
import { ByteStreamReader, TextStreamReader } from "./data_streams/stream_reader.js";
|
|
3
4
|
import { E2EEManager, defaultE2EEOptions } from "./e2ee.js";
|
|
4
5
|
import { FfiClient, FfiClientEvent, FfiHandle } from "./ffi_client.js";
|
|
5
6
|
import { log } from "./log.js";
|
|
6
7
|
import { LocalParticipant, RemoteParticipant } from "./participant.js";
|
|
7
|
-
import { EncryptionState } from "./proto/e2ee_pb.js";
|
|
8
|
+
import { EncryptionState, EncryptionType } from "./proto/e2ee_pb.js";
|
|
8
9
|
import {
|
|
9
10
|
ConnectRequest,
|
|
10
11
|
ConnectionState,
|
|
@@ -25,6 +26,7 @@ const defaultRoomOptions = new FfiRoomOptions({
|
|
|
25
26
|
autoSubscribe: true,
|
|
26
27
|
dynacast: false,
|
|
27
28
|
e2ee: void 0,
|
|
29
|
+
encryption: void 0,
|
|
28
30
|
rtcConfig: void 0,
|
|
29
31
|
adaptiveStream: false,
|
|
30
32
|
joinRetries: 1
|
|
@@ -32,6 +34,12 @@ const defaultRoomOptions = new FfiRoomOptions({
|
|
|
32
34
|
class Room extends EventEmitter {
|
|
33
35
|
constructor() {
|
|
34
36
|
super();
|
|
37
|
+
/**
|
|
38
|
+
* used to ensure events are processed sequentially and allow for
|
|
39
|
+
* the local participant to acquire the lock while doing state updates related to FFI events
|
|
40
|
+
* before processing the next events
|
|
41
|
+
*/
|
|
42
|
+
this.roomEventLock = new Mutex();
|
|
35
43
|
this.byteStreamControllers = /* @__PURE__ */ new Map();
|
|
36
44
|
this.textStreamControllers = /* @__PURE__ */ new Map();
|
|
37
45
|
this.byteStreamHandlers = /* @__PURE__ */ new Map();
|
|
@@ -39,226 +47,305 @@ class Room extends EventEmitter {
|
|
|
39
47
|
this.preConnectEvents = [];
|
|
40
48
|
this.connectionState = ConnectionState.CONN_DISCONNECTED;
|
|
41
49
|
this.remoteParticipants = /* @__PURE__ */ new Map();
|
|
42
|
-
this.onFfiEvent = (ffiEvent) => {
|
|
50
|
+
this.onFfiEvent = async (ffiEvent) => {
|
|
43
51
|
if (!this.localParticipant || !this.ffiHandle || !this.info) {
|
|
44
52
|
this.preConnectEvents.push(ffiEvent);
|
|
45
53
|
return;
|
|
46
54
|
}
|
|
47
55
|
for (const ev of this.preConnectEvents) {
|
|
48
|
-
this.processFfiEvent(ev);
|
|
56
|
+
await this.processFfiEvent(ev);
|
|
49
57
|
}
|
|
50
58
|
this.preConnectEvents = [];
|
|
51
|
-
this.processFfiEvent(ffiEvent);
|
|
59
|
+
await this.processFfiEvent(ffiEvent);
|
|
52
60
|
};
|
|
53
|
-
this.processFfiEvent = (ffiEvent) => {
|
|
61
|
+
this.processFfiEvent = async (ffiEvent) => {
|
|
54
62
|
if (!this.localParticipant || !this.ffiHandle || !this.info) {
|
|
55
63
|
throw new Error("processFfiEvent called before connect");
|
|
56
64
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {
|
|
74
|
-
console.log("Room event:", ev);
|
|
75
|
-
}
|
|
76
|
-
if (ev.case == "participantConnected") {
|
|
77
|
-
const participant = this.createRemoteParticipant(ev.value.info);
|
|
78
|
-
this.remoteParticipants.set(participant.identity, participant);
|
|
79
|
-
this.emit("participantConnected" /* ParticipantConnected */, participant);
|
|
80
|
-
} else if (ev.case == "participantDisconnected") {
|
|
81
|
-
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
82
|
-
this.remoteParticipants.delete(participant.identity);
|
|
83
|
-
participant.info.disconnectReason = ev.value.disconnectReason;
|
|
84
|
-
this.emit("participantDisconnected" /* ParticipantDisconnected */, participant);
|
|
85
|
-
} else if (ev.case == "localTrackPublished") {
|
|
86
|
-
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
87
|
-
this.emit("localTrackPublished" /* LocalTrackPublished */, publication, this.localParticipant);
|
|
88
|
-
} else if (ev.case == "localTrackUnpublished") {
|
|
89
|
-
const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
|
|
90
|
-
this.localParticipant.trackPublications.delete(ev.value.publicationSid);
|
|
91
|
-
this.emit("localTrackUnpublished" /* LocalTrackUnpublished */, publication, this.localParticipant);
|
|
92
|
-
} else if (ev.case == "localTrackSubscribed") {
|
|
93
|
-
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
94
|
-
publication.resolveFirstSubscription();
|
|
95
|
-
this.emit("localTrackSubscribed" /* LocalTrackSubscribed */, publication.track);
|
|
96
|
-
} else if (ev.case == "trackPublished") {
|
|
97
|
-
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
98
|
-
const publication = new RemoteTrackPublication(ev.value.publication);
|
|
99
|
-
participant.trackPublications.set(publication.sid, publication);
|
|
100
|
-
this.emit("trackPublished" /* TrackPublished */, publication, participant);
|
|
101
|
-
} else if (ev.case == "trackUnpublished") {
|
|
102
|
-
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
103
|
-
const publication = participant.trackPublications.get(ev.value.publicationSid);
|
|
104
|
-
participant.trackPublications.delete(ev.value.publicationSid);
|
|
105
|
-
if (publication) {
|
|
106
|
-
this.emit("trackUnpublished" /* TrackUnpublished */, publication, participant);
|
|
107
|
-
}
|
|
108
|
-
} else if (ev.case == "trackSubscribed") {
|
|
109
|
-
const ownedTrack = ev.value.track;
|
|
110
|
-
const trackInfo = ownedTrack.info;
|
|
111
|
-
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
112
|
-
ev.value.participantIdentity,
|
|
113
|
-
trackInfo.sid
|
|
114
|
-
);
|
|
115
|
-
publication.subscribed = true;
|
|
116
|
-
if (trackInfo.kind == TrackKind.KIND_VIDEO) {
|
|
117
|
-
publication.track = new RemoteVideoTrack(ownedTrack);
|
|
118
|
-
} else if (trackInfo.kind == TrackKind.KIND_AUDIO) {
|
|
119
|
-
publication.track = new RemoteAudioTrack(ownedTrack);
|
|
120
|
-
}
|
|
121
|
-
this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
|
|
122
|
-
} else if (ev.case == "trackUnsubscribed") {
|
|
123
|
-
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
124
|
-
ev.value.participantIdentity,
|
|
125
|
-
ev.value.trackSid
|
|
126
|
-
);
|
|
127
|
-
const track = publication.track;
|
|
128
|
-
publication.track = void 0;
|
|
129
|
-
publication.subscribed = false;
|
|
130
|
-
this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
|
|
131
|
-
} else if (ev.case == "trackSubscriptionFailed") {
|
|
132
|
-
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
133
|
-
this.emit("trackSubscriptionFailed" /* TrackSubscriptionFailed */, ev.value.trackSid, participant, ev.value.error);
|
|
134
|
-
} else if (ev.case == "trackMuted") {
|
|
135
|
-
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
136
|
-
ev.value.participantIdentity,
|
|
137
|
-
ev.value.trackSid
|
|
138
|
-
);
|
|
139
|
-
publication.info.muted = true;
|
|
140
|
-
if (publication.track) {
|
|
141
|
-
publication.track.info.muted = true;
|
|
142
|
-
}
|
|
143
|
-
this.emit("trackMuted" /* TrackMuted */, publication, participant);
|
|
144
|
-
} else if (ev.case == "trackUnmuted") {
|
|
145
|
-
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
146
|
-
ev.value.participantIdentity,
|
|
147
|
-
ev.value.trackSid
|
|
148
|
-
);
|
|
149
|
-
publication.info.muted = false;
|
|
150
|
-
if (publication.track) {
|
|
151
|
-
publication.track.info.muted = false;
|
|
65
|
+
const unlock = await this.roomEventLock.lock();
|
|
66
|
+
try {
|
|
67
|
+
if (ffiEvent.message.case == "rpcMethodInvocation") {
|
|
68
|
+
if (ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle) {
|
|
69
|
+
this.localParticipant.handleRpcMethodInvocation(
|
|
70
|
+
ffiEvent.message.value.invocationId,
|
|
71
|
+
ffiEvent.message.value.method,
|
|
72
|
+
ffiEvent.message.value.requestId,
|
|
73
|
+
ffiEvent.message.value.callerIdentity,
|
|
74
|
+
ffiEvent.message.value.payload,
|
|
75
|
+
ffiEvent.message.value.responseTimeoutMs
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
} else if (ffiEvent.message.case != "roomEvent" || ffiEvent.message.value.roomHandle != this.ffiHandle.handle) {
|
|
80
|
+
return;
|
|
152
81
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(identity) => this.requireParticipantByIdentity(identity)
|
|
157
|
-
);
|
|
158
|
-
this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
|
|
159
|
-
} else if (ev.case == "roomMetadataChanged") {
|
|
160
|
-
this.info.metadata = ev.value.metadata;
|
|
161
|
-
this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
|
|
162
|
-
} else if (ev.case == "participantMetadataChanged") {
|
|
163
|
-
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
164
|
-
participant.info.metadata = ev.value.metadata;
|
|
165
|
-
this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
|
|
166
|
-
} else if (ev.case == "participantNameChanged") {
|
|
167
|
-
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
168
|
-
participant.info.name = ev.value.name;
|
|
169
|
-
this.emit("participantNameChanged" /* ParticipantNameChanged */, participant.name, participant);
|
|
170
|
-
} else if (ev.case == "participantAttributesChanged") {
|
|
171
|
-
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
172
|
-
participant.info.attributes = ev.value.attributes.reduce(
|
|
173
|
-
(acc, value) => {
|
|
174
|
-
acc[value.key] = value.value;
|
|
175
|
-
return acc;
|
|
176
|
-
},
|
|
177
|
-
{}
|
|
178
|
-
);
|
|
179
|
-
if (Object.keys(ev.value.changedAttributes).length > 0) {
|
|
180
|
-
const changedAttributes = ev.value.changedAttributes.reduce(
|
|
181
|
-
(acc, value) => {
|
|
182
|
-
acc[value.key] = value.value;
|
|
183
|
-
return acc;
|
|
184
|
-
},
|
|
185
|
-
{}
|
|
186
|
-
);
|
|
187
|
-
this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
|
|
82
|
+
const ev = ffiEvent.message.value.message;
|
|
83
|
+
if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {
|
|
84
|
+
console.log("Room event:", ev);
|
|
188
85
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
86
|
+
if (ev.case == "participantConnected") {
|
|
87
|
+
const participant = this.createRemoteParticipant(ev.value.info);
|
|
88
|
+
this.remoteParticipants.set(participant.identity, participant);
|
|
89
|
+
this.emit("participantConnected" /* ParticipantConnected */, participant);
|
|
90
|
+
} else if (ev.case == "participantDisconnected") {
|
|
91
|
+
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
92
|
+
if (participant) {
|
|
93
|
+
this.remoteParticipants.delete(participant.identity);
|
|
94
|
+
participant.info.disconnectReason = ev.value.disconnectReason;
|
|
95
|
+
this.emit("participantDisconnected" /* ParticipantDisconnected */, participant);
|
|
96
|
+
} else {
|
|
97
|
+
console.log(`RoomEvent.ParticipantDisconnected: Could not find participant`);
|
|
98
|
+
}
|
|
99
|
+
} else if (ev.case == "localTrackPublished") {
|
|
100
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
101
|
+
this.emit("localTrackPublished" /* LocalTrackPublished */, publication, this.localParticipant);
|
|
102
|
+
} else if (ev.case == "localTrackUnpublished") {
|
|
103
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid);
|
|
104
|
+
this.localParticipant.trackPublications.delete(ev.value.publicationSid);
|
|
105
|
+
this.emit("localTrackUnpublished" /* LocalTrackUnpublished */, publication, this.localParticipant);
|
|
106
|
+
} else if (ev.case == "localTrackSubscribed") {
|
|
107
|
+
const publication = this.localParticipant.trackPublications.get(ev.value.trackSid);
|
|
108
|
+
if (publication) {
|
|
109
|
+
publication.resolveFirstSubscription();
|
|
110
|
+
this.emit("localTrackSubscribed" /* LocalTrackSubscribed */, publication.track);
|
|
111
|
+
} else {
|
|
112
|
+
console.warn(
|
|
113
|
+
`RoomEvent.LocalTrackSubscribed: Publication not found: ${ev.value.trackSid}`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
} else if (ev.case == "trackPublished") {
|
|
117
|
+
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
118
|
+
const publication = new RemoteTrackPublication(ev.value.publication);
|
|
119
|
+
if (participant) {
|
|
120
|
+
participant.trackPublications.set(publication.sid, publication);
|
|
121
|
+
} else {
|
|
122
|
+
console.warn(
|
|
123
|
+
`RoomEvent.TrackPublished: Could not find participant: ${ev.value.participantIdentity}`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
this.emit("trackPublished" /* TrackPublished */, publication, participant);
|
|
127
|
+
} else if (ev.case == "trackUnpublished") {
|
|
128
|
+
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
129
|
+
const publication = participant.trackPublications.get(ev.value.publicationSid);
|
|
130
|
+
participant.trackPublications.delete(ev.value.publicationSid);
|
|
131
|
+
if (publication) {
|
|
132
|
+
this.emit("trackUnpublished" /* TrackUnpublished */, publication, participant);
|
|
133
|
+
} else {
|
|
134
|
+
console.warn(`RoomEvent.TrackUnpublished: Could not find publication`);
|
|
135
|
+
}
|
|
136
|
+
} else if (ev.case == "trackSubscribed") {
|
|
137
|
+
const ownedTrack = ev.value.track;
|
|
138
|
+
const trackInfo = ownedTrack.info;
|
|
139
|
+
try {
|
|
140
|
+
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
141
|
+
ev.value.participantIdentity,
|
|
142
|
+
trackInfo.sid
|
|
143
|
+
);
|
|
144
|
+
publication.subscribed = true;
|
|
145
|
+
if (trackInfo.kind == TrackKind.KIND_VIDEO) {
|
|
146
|
+
publication.track = new RemoteVideoTrack(ownedTrack);
|
|
147
|
+
} else if (trackInfo.kind == TrackKind.KIND_AUDIO) {
|
|
148
|
+
publication.track = new RemoteAudioTrack(ownedTrack);
|
|
149
|
+
}
|
|
150
|
+
this.emit("trackSubscribed" /* TrackSubscribed */, publication.track, publication, participant);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.warn(`RoomEvent.TrackSubscribed: ${e.message}`);
|
|
153
|
+
}
|
|
154
|
+
} else if (ev.case == "trackUnsubscribed") {
|
|
155
|
+
try {
|
|
156
|
+
const { participant, publication } = this.requirePublicationOfRemoteParticipant(
|
|
157
|
+
ev.value.participantIdentity,
|
|
158
|
+
ev.value.trackSid
|
|
211
159
|
);
|
|
212
|
-
|
|
160
|
+
const track = publication.track;
|
|
161
|
+
publication.track = void 0;
|
|
162
|
+
publication.subscribed = false;
|
|
163
|
+
this.emit("trackUnsubscribed" /* TrackUnsubscribed */, track, publication, participant);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
console.warn(`RoomEvent.TrackUnsubscribed: ${e.message}`);
|
|
166
|
+
}
|
|
167
|
+
} else if (ev.case == "trackSubscriptionFailed") {
|
|
168
|
+
try {
|
|
169
|
+
const participant = this.requireRemoteParticipant(ev.value.participantIdentity);
|
|
213
170
|
this.emit(
|
|
214
|
-
"
|
|
215
|
-
|
|
171
|
+
"trackSubscriptionFailed" /* TrackSubscriptionFailed */,
|
|
172
|
+
ev.value.trackSid,
|
|
216
173
|
participant,
|
|
217
|
-
ev.value.
|
|
218
|
-
dataPacket.value.topic
|
|
174
|
+
ev.value.error
|
|
219
175
|
);
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
176
|
+
} catch (e) {
|
|
177
|
+
console.warn(`RoomEvent.TrackSubscriptionFailed: ${e.message}`);
|
|
178
|
+
}
|
|
179
|
+
} else if (ev.case == "trackMuted") {
|
|
180
|
+
try {
|
|
181
|
+
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
182
|
+
ev.value.participantIdentity,
|
|
183
|
+
ev.value.trackSid
|
|
184
|
+
);
|
|
185
|
+
publication.info.muted = true;
|
|
186
|
+
if (publication.track) {
|
|
187
|
+
publication.track.info.muted = true;
|
|
188
|
+
}
|
|
189
|
+
this.emit("trackMuted" /* TrackMuted */, publication, participant);
|
|
190
|
+
} catch (e) {
|
|
191
|
+
console.warn(`RoomEvent.TrackMuted: ${e.message}`);
|
|
192
|
+
}
|
|
193
|
+
} else if (ev.case == "trackUnmuted") {
|
|
194
|
+
try {
|
|
195
|
+
const { participant, publication } = this.requirePublicationOfParticipant(
|
|
196
|
+
ev.value.participantIdentity,
|
|
197
|
+
ev.value.trackSid
|
|
198
|
+
);
|
|
199
|
+
publication.info.muted = false;
|
|
200
|
+
if (publication.track) {
|
|
201
|
+
publication.track.info.muted = false;
|
|
202
|
+
}
|
|
203
|
+
this.emit("trackUnmuted" /* TrackUnmuted */, publication, participant);
|
|
204
|
+
} catch (e) {
|
|
205
|
+
console.warn(`RoomEvent.TrackUnmuted: ${e.message}`);
|
|
206
|
+
}
|
|
207
|
+
} else if (ev.case == "activeSpeakersChanged") {
|
|
208
|
+
try {
|
|
209
|
+
const activeSpeakers = ev.value.participantIdentities.map(
|
|
210
|
+
(identity) => this.requireParticipantByIdentity(identity)
|
|
211
|
+
);
|
|
212
|
+
this.emit("activeSpeakersChanged" /* ActiveSpeakersChanged */, activeSpeakers);
|
|
213
|
+
} catch (e) {
|
|
214
|
+
console.warn(`RoomEvent.ActiveSpeakersChanged: ${e.message}`);
|
|
215
|
+
}
|
|
216
|
+
} else if (ev.case == "roomMetadataChanged") {
|
|
217
|
+
this.info.metadata = ev.value.metadata ?? "";
|
|
218
|
+
this.emit("roomMetadataChanged" /* RoomMetadataChanged */, this.info.metadata);
|
|
219
|
+
} else if (ev.case == "participantMetadataChanged") {
|
|
220
|
+
try {
|
|
221
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
222
|
+
participant.info.metadata = ev.value.metadata;
|
|
223
|
+
this.emit("participantMetadataChanged" /* ParticipantMetadataChanged */, participant.metadata, participant);
|
|
224
|
+
} catch (e) {
|
|
225
|
+
console.warn(`RoomEvent.ParticipantMetadataChanged: ${e.message}`);
|
|
226
|
+
}
|
|
227
|
+
} else if (ev.case == "participantNameChanged") {
|
|
228
|
+
try {
|
|
229
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
230
|
+
participant.info.name = ev.value.name;
|
|
231
|
+
this.emit("participantNameChanged" /* ParticipantNameChanged */, participant.name, participant);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
console.warn(`RoomEvent.ParticipantNameChanged: ${e.message}`);
|
|
234
|
+
}
|
|
235
|
+
} else if (ev.case == "participantAttributesChanged") {
|
|
236
|
+
try {
|
|
237
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
238
|
+
participant.info.attributes = ev.value.attributes.reduce(
|
|
239
|
+
(acc, value) => {
|
|
240
|
+
acc[value.key] = value.value;
|
|
241
|
+
return acc;
|
|
242
|
+
},
|
|
243
|
+
{}
|
|
244
|
+
);
|
|
245
|
+
if (Object.keys(ev.value.changedAttributes).length > 0) {
|
|
246
|
+
const changedAttributes = ev.value.changedAttributes.reduce(
|
|
247
|
+
(acc, value) => {
|
|
248
|
+
acc[value.key] = value.value;
|
|
249
|
+
return acc;
|
|
250
|
+
},
|
|
251
|
+
{}
|
|
252
|
+
);
|
|
253
|
+
this.emit("participantAttributesChanged" /* ParticipantAttributesChanged */, changedAttributes, participant);
|
|
254
|
+
}
|
|
255
|
+
} catch (e) {
|
|
256
|
+
console.warn(`RoomEvent.ParticipantAttributesChanged: ${e.message}`);
|
|
257
|
+
}
|
|
258
|
+
} else if (ev.case == "connectionQualityChanged") {
|
|
259
|
+
try {
|
|
260
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
261
|
+
this.emit("connectionQualityChanged" /* ConnectionQualityChanged */, ev.value.quality, participant);
|
|
262
|
+
} catch (e) {
|
|
263
|
+
console.warn(`RoomEvent.ConnectionQualityChanged: ${e.message}`);
|
|
264
|
+
}
|
|
265
|
+
} else if (ev.case == "chatMessage") {
|
|
266
|
+
const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity);
|
|
267
|
+
const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message;
|
|
268
|
+
const message = {
|
|
269
|
+
id,
|
|
270
|
+
message: messageText,
|
|
271
|
+
timestamp: Number(timestamp),
|
|
272
|
+
editTimestamp: Number(editTimestamp),
|
|
273
|
+
generated
|
|
274
|
+
};
|
|
275
|
+
this.emit("chatMessage" /* ChatMessage */, message, participant);
|
|
276
|
+
} else if (ev.case == "dataPacketReceived") {
|
|
277
|
+
const participant = this.remoteParticipants.get(ev.value.participantIdentity);
|
|
278
|
+
const dataPacket = ev.value.value;
|
|
279
|
+
switch (dataPacket.case) {
|
|
280
|
+
case "user":
|
|
281
|
+
const buffer = FfiClient.instance.copyBuffer(
|
|
282
|
+
dataPacket.value.data.data.dataPtr,
|
|
283
|
+
Number(dataPacket.value.data.data.dataLen)
|
|
284
|
+
);
|
|
285
|
+
new FfiHandle(dataPacket.value.data.handle.id).dispose();
|
|
286
|
+
this.emit(
|
|
287
|
+
"dataReceived" /* DataReceived */,
|
|
288
|
+
buffer,
|
|
289
|
+
participant,
|
|
290
|
+
ev.value.kind,
|
|
291
|
+
dataPacket.value.topic
|
|
292
|
+
);
|
|
293
|
+
break;
|
|
294
|
+
case "sipDtmf":
|
|
295
|
+
const { code, digit } = dataPacket.value;
|
|
296
|
+
this.emit("dtmfReceived" /* DtmfReceived */, code, digit, participant);
|
|
297
|
+
break;
|
|
298
|
+
default:
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
} else if (ev.case == "e2eeStateChanged") {
|
|
302
|
+
if (ev.value.state == EncryptionState.INTERNAL_ERROR) {
|
|
303
|
+
this.emit("encryptionError" /* EncryptionError */, new Error("internal server error"));
|
|
304
|
+
}
|
|
305
|
+
} else if (ev.case == "connectionStateChanged") {
|
|
306
|
+
this.connectionState = ev.value.state;
|
|
307
|
+
this.emit("connectionStateChanged" /* ConnectionStateChanged */, this.connectionState);
|
|
308
|
+
} else if (ev.case == "disconnected") {
|
|
309
|
+
this.emit("disconnected" /* Disconnected */, ev.value.reason);
|
|
310
|
+
} else if (ev.case == "reconnecting") {
|
|
311
|
+
this.emit("reconnecting" /* Reconnecting */);
|
|
312
|
+
} else if (ev.case == "reconnected") {
|
|
313
|
+
this.emit("reconnected" /* Reconnected */);
|
|
314
|
+
} else if (ev.case == "roomSidChanged") {
|
|
315
|
+
this.emit("roomSidChanged" /* RoomSidChanged */, ev.value.sid);
|
|
316
|
+
} else if (ev.case === "streamHeaderReceived" && ev.value.header) {
|
|
317
|
+
this.handleStreamHeader(ev.value.header, ev.value.participantIdentity);
|
|
318
|
+
} else if (ev.case === "streamChunkReceived" && ev.value.chunk) {
|
|
319
|
+
this.handleStreamChunk(ev.value.chunk);
|
|
320
|
+
} else if (ev.case === "streamTrailerReceived" && ev.value.trailer) {
|
|
321
|
+
this.handleStreamTrailer(ev.value.trailer);
|
|
322
|
+
} else if (ev.case === "roomUpdated") {
|
|
323
|
+
this.info = ev.value;
|
|
324
|
+
this.emit("roomUpdated" /* RoomUpdated */);
|
|
325
|
+
} else if (ev.case === "moved") {
|
|
326
|
+
this.info = ev.value;
|
|
327
|
+
this.emit("moved" /* Moved */);
|
|
328
|
+
} else if (ev.case === "participantsUpdated") {
|
|
329
|
+
for (const info of ev.value.participants) {
|
|
330
|
+
const participant = this.retrieveParticipantByIdentity(info.identity);
|
|
331
|
+
if (participant) {
|
|
332
|
+
participant.info = info;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
} else if (ev.case === "participantEncryptionStatusChanged") {
|
|
336
|
+
try {
|
|
337
|
+
const participant = this.requireParticipantByIdentity(ev.value.participantIdentity);
|
|
338
|
+
this.emit(
|
|
339
|
+
"participantEncryptionStatusChanged" /* ParticipantEncryptionStatusChanged */,
|
|
340
|
+
!!ev.value.isEncrypted,
|
|
341
|
+
participant
|
|
342
|
+
);
|
|
343
|
+
} catch (e) {
|
|
344
|
+
console.warn(`RoomEvent.ParticipantEncryptionStatusChanged: ${e.message}`);
|
|
260
345
|
}
|
|
261
346
|
}
|
|
347
|
+
} finally {
|
|
348
|
+
unlock();
|
|
262
349
|
}
|
|
263
350
|
};
|
|
264
351
|
}
|
|
@@ -341,7 +428,8 @@ class Room extends EventEmitter {
|
|
|
341
428
|
*/
|
|
342
429
|
async connect(url, token, opts) {
|
|
343
430
|
const options = { ...defaultRoomOptions, ...opts };
|
|
344
|
-
const
|
|
431
|
+
const e2eeEnabled = options.encryption || options.e2ee;
|
|
432
|
+
const e2eeOptions = options.encryption ? { ...defaultE2EEOptions, ...options.encryption } : { ...defaultE2EEOptions, ...options.e2ee };
|
|
345
433
|
const req = new ConnectRequest({
|
|
346
434
|
url,
|
|
347
435
|
token,
|
|
@@ -361,10 +449,13 @@ class Room extends EventEmitter {
|
|
|
361
449
|
switch (cb.message.case) {
|
|
362
450
|
case "result":
|
|
363
451
|
this.ffiHandle = new FfiHandle(cb.message.value.room.handle.id);
|
|
364
|
-
this.e2eeManager =
|
|
452
|
+
this.e2eeManager = e2eeEnabled && new E2EEManager(this.ffiHandle.handle, e2eeOptions);
|
|
365
453
|
this.info = cb.message.value.room.info;
|
|
366
454
|
this.connectionState = ConnectionState.CONN_CONNECTED;
|
|
367
|
-
this.localParticipant = new LocalParticipant(
|
|
455
|
+
this.localParticipant = new LocalParticipant(
|
|
456
|
+
cb.message.value.localParticipant,
|
|
457
|
+
this.roomEventLock
|
|
458
|
+
);
|
|
368
459
|
for (const pt of cb.message.value.participants) {
|
|
369
460
|
const rp = this.createRemoteParticipant(pt.participant);
|
|
370
461
|
for (const pub of pt.publications) {
|
|
@@ -387,7 +478,7 @@ class Room extends EventEmitter {
|
|
|
387
478
|
if (!this.isConnected) {
|
|
388
479
|
return;
|
|
389
480
|
}
|
|
390
|
-
FfiClient.instance.request({
|
|
481
|
+
const res = FfiClient.instance.request({
|
|
391
482
|
message: {
|
|
392
483
|
case: "disconnect",
|
|
393
484
|
value: {
|
|
@@ -395,6 +486,9 @@ class Room extends EventEmitter {
|
|
|
395
486
|
}
|
|
396
487
|
}
|
|
397
488
|
});
|
|
489
|
+
await FfiClient.instance.waitFor((ev) => {
|
|
490
|
+
return ev.message.case == "connect" && ev.message.value.asyncId == res.asyncId;
|
|
491
|
+
});
|
|
398
492
|
FfiClient.instance.removeListener(FfiClientEvent.FfiEvent, this.onFfiEvent);
|
|
399
493
|
this.removeAllListeners();
|
|
400
494
|
}
|
|
@@ -599,6 +693,7 @@ var RoomEvent = /* @__PURE__ */ ((RoomEvent2) => {
|
|
|
599
693
|
RoomEvent2["ParticipantMetadataChanged"] = "participantMetadataChanged";
|
|
600
694
|
RoomEvent2["ParticipantNameChanged"] = "participantNameChanged";
|
|
601
695
|
RoomEvent2["ParticipantAttributesChanged"] = "participantAttributesChanged";
|
|
696
|
+
RoomEvent2["ParticipantEncryptionStatusChanged"] = "participantEncryptionStatusChanged";
|
|
602
697
|
RoomEvent2["ConnectionQualityChanged"] = "connectionQualityChanged";
|
|
603
698
|
RoomEvent2["DataReceived"] = "dataReceived";
|
|
604
699
|
RoomEvent2["ChatMessage"] = "chatMessage";
|