@livekit/rtc-node 0.13.22 → 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/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_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 +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.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 +10 -10
- package/dist/room.cjs.map +1 -1
- package/dist/room.d.cts +10 -10
- package/dist/room.d.ts +10 -10
- package/dist/room.d.ts.map +1 -1
- package/dist/room.js +11 -11
- 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_frame.ts +7 -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 +5 -0
- 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 +33 -33
- package/src/version.ts +1 -1
package/dist/room.d.cts
CHANGED
|
@@ -92,10 +92,10 @@ declare class Room extends Room_base {
|
|
|
92
92
|
get emptyTimeout(): number;
|
|
93
93
|
/**
|
|
94
94
|
* Connects to a LiveKit room using the provided URL and access token.
|
|
95
|
-
* @param url The WebSocket URL of the LiveKit server
|
|
96
|
-
* @param token A valid LiveKit access token for authentication
|
|
97
|
-
* @param opts Optional room configuration options
|
|
98
|
-
* @throws ConnectError if connection fails
|
|
95
|
+
* @param url - The WebSocket URL of the LiveKit server
|
|
96
|
+
* @param token - A valid LiveKit access token for authentication
|
|
97
|
+
* @param opts - Optional room configuration options
|
|
98
|
+
* @throws ConnectError - if connection fails
|
|
99
99
|
*/
|
|
100
100
|
connect(url: string, token: string, opts?: RoomOptions): Promise<void>;
|
|
101
101
|
/**
|
|
@@ -106,18 +106,18 @@ declare class Room extends Room_base {
|
|
|
106
106
|
/**
|
|
107
107
|
* Registers a handler for incoming text data streams on a specific topic.
|
|
108
108
|
* Text streams are used for receiving structured text data from other participants.
|
|
109
|
-
* @param topic The topic to listen for text streams on
|
|
110
|
-
* @param callback Function to handle incoming text stream data
|
|
111
|
-
* @throws Error if a handler for this topic is already registered
|
|
109
|
+
* @param topic - The topic to listen for text streams on
|
|
110
|
+
* @param callback - Function to handle incoming text stream data
|
|
111
|
+
* @throws Error - if a handler for this topic is already registered
|
|
112
112
|
*/
|
|
113
113
|
registerTextStreamHandler(topic: string, callback: TextStreamHandler): void;
|
|
114
114
|
unregisterTextStreamHandler(topic: string): void;
|
|
115
115
|
/**
|
|
116
116
|
* Registers a handler for incoming byte data streams on a specific topic.
|
|
117
117
|
* Byte streams are used for receiving binary data like files from other participants.
|
|
118
|
-
* @param topic The topic to listen for byte streams on
|
|
119
|
-
* @param callback Function to handle incoming byte stream data
|
|
120
|
-
* @throws Error if a handler for this topic is already registered
|
|
118
|
+
* @param topic - The topic to listen for byte streams on
|
|
119
|
+
* @param callback - Function to handle incoming byte stream data
|
|
120
|
+
* @throws Error - if a handler for this topic is already registered
|
|
121
121
|
*/
|
|
122
122
|
registerByteStreamHandler(topic: string, callback: ByteStreamHandler): void;
|
|
123
123
|
unregisterByteStreamHandler(topic: string): void;
|
package/dist/room.d.ts
CHANGED
|
@@ -92,10 +92,10 @@ declare class Room extends Room_base {
|
|
|
92
92
|
get emptyTimeout(): number;
|
|
93
93
|
/**
|
|
94
94
|
* Connects to a LiveKit room using the provided URL and access token.
|
|
95
|
-
* @param url The WebSocket URL of the LiveKit server
|
|
96
|
-
* @param token A valid LiveKit access token for authentication
|
|
97
|
-
* @param opts Optional room configuration options
|
|
98
|
-
* @throws ConnectError if connection fails
|
|
95
|
+
* @param url - The WebSocket URL of the LiveKit server
|
|
96
|
+
* @param token - A valid LiveKit access token for authentication
|
|
97
|
+
* @param opts - Optional room configuration options
|
|
98
|
+
* @throws ConnectError - if connection fails
|
|
99
99
|
*/
|
|
100
100
|
connect(url: string, token: string, opts?: RoomOptions): Promise<void>;
|
|
101
101
|
/**
|
|
@@ -106,18 +106,18 @@ declare class Room extends Room_base {
|
|
|
106
106
|
/**
|
|
107
107
|
* Registers a handler for incoming text data streams on a specific topic.
|
|
108
108
|
* Text streams are used for receiving structured text data from other participants.
|
|
109
|
-
* @param topic The topic to listen for text streams on
|
|
110
|
-
* @param callback Function to handle incoming text stream data
|
|
111
|
-
* @throws Error if a handler for this topic is already registered
|
|
109
|
+
* @param topic - The topic to listen for text streams on
|
|
110
|
+
* @param callback - Function to handle incoming text stream data
|
|
111
|
+
* @throws Error - if a handler for this topic is already registered
|
|
112
112
|
*/
|
|
113
113
|
registerTextStreamHandler(topic: string, callback: TextStreamHandler): void;
|
|
114
114
|
unregisterTextStreamHandler(topic: string): void;
|
|
115
115
|
/**
|
|
116
116
|
* Registers a handler for incoming byte data streams on a specific topic.
|
|
117
117
|
* Byte streams are used for receiving binary data like files from other participants.
|
|
118
|
-
* @param topic The topic to listen for byte streams on
|
|
119
|
-
* @param callback Function to handle incoming byte stream data
|
|
120
|
-
* @throws Error if a handler for this topic is already registered
|
|
118
|
+
* @param topic - The topic to listen for byte streams on
|
|
119
|
+
* @param callback - Function to handle incoming byte stream data
|
|
120
|
+
* @throws Error - if a handler for this topic is already registered
|
|
121
121
|
*/
|
|
122
122
|
registerByteStreamHandler(topic: string, callback: ByteStreamHandler): void;
|
|
123
123
|
unregisterByteStreamHandler(topic: string): void;
|
package/dist/room.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,IAAI,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGhF,OAAO,KAAK,EACV,iBAAiB,EAGjB,iBAAiB,EAElB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAsB,MAAM,WAAW,CAAC;AAG5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAmB,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"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"}
|
package/dist/room.js
CHANGED
|
@@ -5,7 +5,7 @@ import { E2EEManager, defaultE2EEOptions } from "./e2ee.js";
|
|
|
5
5
|
import { FfiClient, FfiClientEvent, FfiHandle } from "./ffi_client.js";
|
|
6
6
|
import { log } from "./log.js";
|
|
7
7
|
import { LocalParticipant, RemoteParticipant } from "./participant.js";
|
|
8
|
-
import { EncryptionState
|
|
8
|
+
import { EncryptionState } from "./proto/e2ee_pb.js";
|
|
9
9
|
import {
|
|
10
10
|
ConnectRequest,
|
|
11
11
|
ConnectionState,
|
|
@@ -419,10 +419,10 @@ class Room extends EventEmitter {
|
|
|
419
419
|
}
|
|
420
420
|
/**
|
|
421
421
|
* Connects to a LiveKit room using the provided URL and access token.
|
|
422
|
-
* @param url The WebSocket URL of the LiveKit server
|
|
423
|
-
* @param token A valid LiveKit access token for authentication
|
|
424
|
-
* @param opts Optional room configuration options
|
|
425
|
-
* @throws ConnectError if connection fails
|
|
422
|
+
* @param url - The WebSocket URL of the LiveKit server
|
|
423
|
+
* @param token - A valid LiveKit access token for authentication
|
|
424
|
+
* @param opts - Optional room configuration options
|
|
425
|
+
* @throws ConnectError - if connection fails
|
|
426
426
|
*/
|
|
427
427
|
async connect(url, token, opts) {
|
|
428
428
|
const options = { ...defaultRoomOptions, ...opts };
|
|
@@ -493,9 +493,9 @@ class Room extends EventEmitter {
|
|
|
493
493
|
/**
|
|
494
494
|
* Registers a handler for incoming text data streams on a specific topic.
|
|
495
495
|
* Text streams are used for receiving structured text data from other participants.
|
|
496
|
-
* @param topic The topic to listen for text streams on
|
|
497
|
-
* @param callback Function to handle incoming text stream data
|
|
498
|
-
* @throws Error if a handler for this topic is already registered
|
|
496
|
+
* @param topic - The topic to listen for text streams on
|
|
497
|
+
* @param callback - Function to handle incoming text stream data
|
|
498
|
+
* @throws Error - if a handler for this topic is already registered
|
|
499
499
|
*/
|
|
500
500
|
registerTextStreamHandler(topic, callback) {
|
|
501
501
|
if (this.textStreamHandlers.has(topic)) {
|
|
@@ -509,9 +509,9 @@ class Room extends EventEmitter {
|
|
|
509
509
|
/**
|
|
510
510
|
* Registers a handler for incoming byte data streams on a specific topic.
|
|
511
511
|
* Byte streams are used for receiving binary data like files from other participants.
|
|
512
|
-
* @param topic The topic to listen for byte streams on
|
|
513
|
-
* @param callback Function to handle incoming byte stream data
|
|
514
|
-
* @throws Error if a handler for this topic is already registered
|
|
512
|
+
* @param topic - The topic to listen for byte streams on
|
|
513
|
+
* @param callback - Function to handle incoming byte stream data
|
|
514
|
+
* @throws Error - if a handler for this topic is already registered
|
|
515
515
|
*/
|
|
516
516
|
registerByteStreamHandler(topic, callback) {
|
|
517
517
|
if (this.byteStreamHandlers.has(topic)) {
|
package/dist/room.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/room.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Mutex } from '@livekit/mutex';\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport EventEmitter from 'events';\nimport { ByteStreamReader, TextStreamReader } from './data_streams/stream_reader.js';\nimport type {\n ByteStreamHandler,\n ByteStreamInfo,\n StreamController,\n TextStreamHandler,\n TextStreamInfo,\n} from './data_streams/types.js';\nimport type { E2EEOptions } from './e2ee.js';\nimport { E2EEManager, defaultE2EEOptions } from './e2ee.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport { log } from './log.js';\nimport type { Participant } from './participant.js';\nimport { LocalParticipant, RemoteParticipant } from './participant.js';\nimport { EncryptionState, EncryptionType } from './proto/e2ee_pb.js';\nimport type { FfiEvent } from './proto/ffi_pb.js';\nimport type { DisconnectReason, OwnedParticipant } from './proto/participant_pb.js';\nimport type { DataStream_Trailer, DisconnectCallback } from './proto/room_pb.js';\nimport {\n type ConnectCallback,\n ConnectRequest,\n type ConnectResponse,\n type ConnectionQuality,\n ConnectionState,\n ContinualGatheringPolicy,\n type DataPacketKind,\n type DataStream_Chunk,\n type DataStream_Header,\n type DisconnectResponse,\n RoomOptions as FfiRoomOptions,\n type IceServer,\n IceTransportType,\n type RoomInfo,\n} from './proto/room_pb.js';\nimport { TrackKind } from './proto/track_pb.js';\nimport type { LocalTrack, RemoteTrack } from './track.js';\nimport { RemoteAudioTrack, RemoteVideoTrack } from './track.js';\nimport type { LocalTrackPublication, TrackPublication } from './track_publication.js';\nimport { RemoteTrackPublication } from './track_publication.js';\nimport type { ChatMessage } from './types.js';\nimport { bigIntToNumber } from './utils.js';\n\nexport interface RtcConfiguration {\n iceTransportType: IceTransportType;\n continualGatheringPolicy: ContinualGatheringPolicy;\n iceServers: IceServer[];\n}\n\nexport const defaultRtcConfiguration: RtcConfiguration = {\n iceTransportType: IceTransportType.TRANSPORT_ALL,\n continualGatheringPolicy: ContinualGatheringPolicy.GATHER_CONTINUALLY,\n iceServers: [],\n};\n\nexport interface RoomOptions {\n autoSubscribe: boolean;\n dynacast: boolean;\n /**\n * @deprecated Use `encryption` instead. See x for details\n */\n e2ee?: E2EEOptions;\n encryption?: E2EEOptions;\n rtcConfig?: RtcConfiguration;\n}\n\nexport const defaultRoomOptions = new FfiRoomOptions({\n autoSubscribe: true,\n dynacast: false,\n e2ee: undefined,\n encryption: undefined,\n rtcConfig: undefined,\n adaptiveStream: false,\n joinRetries: 1,\n});\n\nexport class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>) {\n private info?: RoomInfo;\n private ffiHandle?: FfiHandle;\n /**\n * used to ensure events are processed sequentially and allow for\n * the local participant to acquire the lock while doing state updates related to FFI events\n * before processing the next events\n */\n private ffiEventLock = new Mutex();\n\n private byteStreamControllers = new Map<string, StreamController<DataStream_Chunk>>();\n private textStreamControllers = new Map<string, StreamController<DataStream_Chunk>>();\n private byteStreamHandlers = new Map<string, ByteStreamHandler>();\n private textStreamHandlers = new Map<string, TextStreamHandler>();\n\n private preConnectEvents: FfiEvent[] = [];\n\n e2eeManager?: E2EEManager;\n connectionState: ConnectionState = ConnectionState.CONN_DISCONNECTED;\n\n remoteParticipants: Map<string, RemoteParticipant> = new Map();\n localParticipant?: LocalParticipant;\n\n constructor() {\n super();\n }\n\n get name(): string | undefined {\n return this.info?.name;\n }\n\n get metadata(): string | undefined {\n return this.info?.metadata;\n }\n\n get isConnected(): boolean {\n return this.ffiHandle != undefined && this.connectionState != ConnectionState.CONN_DISCONNECTED;\n }\n\n /**\n * Gets the room's server ID. This ID is assigned by the LiveKit server\n * and is unique for each room session.\n * SID is assigned asynchronously after connection.\n * @returns Promise that resolves to the room's server ID, or empty string if not connected\n */\n async getSid(): Promise<string> {\n if (!this.isConnected) {\n return '';\n }\n if (this.info?.sid && this.info.sid !== '') {\n return this.info.sid;\n }\n return new Promise((resolve, reject) => {\n const handleRoomUpdate = (sid: string) => {\n if (sid !== '') {\n this.off(RoomEvent.RoomSidChanged, handleRoomUpdate);\n resolve(sid);\n }\n };\n this.on(RoomEvent.RoomSidChanged, handleRoomUpdate);\n this.once(RoomEvent.Disconnected, () => {\n this.off(RoomEvent.RoomSidChanged, handleRoomUpdate);\n reject('Room disconnected before room server id was available');\n });\n });\n }\n\n get numParticipants(): number {\n return this.info?.numParticipants ?? 0;\n }\n\n get numPublishers(): number {\n return this.info?.numPublishers ?? 0;\n }\n\n get creationTime(): Date {\n return new Date(Number(this.info?.creationTime ?? 0));\n }\n\n get isRecording(): boolean {\n return this.info?.activeRecording ?? false;\n }\n\n /**\n * The time in seconds after which a room will be closed after the last\n * participant has disconnected.\n */\n get departureTimeout(): number {\n return this.info?.departureTimeout ?? 0;\n }\n\n /**\n * The time in seconds after which an empty room will be automatically closed.\n */\n get emptyTimeout(): number {\n return this.info?.emptyTimeout ?? 0;\n }\n\n /**\n * Connects to a LiveKit room using the provided URL and access token.\n * @param url The WebSocket URL of the LiveKit server\n * @param token A valid LiveKit access token for authentication\n * @param opts Optional room configuration options\n * @throws ConnectError if connection fails\n */\n async connect(url: string, token: string, opts?: RoomOptions) {\n const options = { ...defaultRoomOptions, ...opts };\n const e2eeEnabled = options.encryption || options.e2ee;\n const e2eeOptions = options.encryption\n ? { ...defaultE2EEOptions, ...options.encryption }\n : { ...defaultE2EEOptions, ...options.e2ee };\n\n const req = new ConnectRequest({\n url: url,\n token: token,\n options,\n });\n\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onFfiEvent);\n\n const res = FfiClient.instance.request<ConnectResponse>({\n message: {\n case: 'connect',\n value: req,\n },\n });\n\n const cb = await FfiClient.instance.waitFor<ConnectCallback>((ev: FfiEvent) => {\n return ev.message.case == 'connect' && ev.message.value.asyncId == res.asyncId;\n });\n\n log.debug('Connect callback received');\n\n switch (cb.message.case) {\n case 'result':\n this.ffiHandle = new FfiHandle(cb.message.value.room!.handle!.id!);\n this.e2eeManager = e2eeEnabled && new E2EEManager(this.ffiHandle.handle, e2eeOptions);\n\n this.info = cb.message.value.room!.info;\n this.connectionState = ConnectionState.CONN_CONNECTED;\n this.localParticipant = new LocalParticipant(\n cb.message.value.localParticipant!,\n this.ffiEventLock,\n );\n\n for (const pt of cb.message.value.participants) {\n const rp = this.createRemoteParticipant(pt.participant!);\n\n for (const pub of pt.publications) {\n const publication = new RemoteTrackPublication(pub);\n rp.trackPublications.set(publication.sid!, publication);\n }\n }\n break;\n case 'error':\n default:\n throw new ConnectError(cb.message.value || '');\n }\n }\n\n /**\n * Disconnects from the room and cleans up all resources.\n * This will stop all tracks and close the connection.\n */\n async disconnect() {\n if (!this.isConnected) {\n return;\n }\n\n const res = FfiClient.instance.request<DisconnectResponse>({\n message: {\n case: 'disconnect',\n value: {\n roomHandle: this.ffiHandle?.handle,\n },\n },\n });\n\n await FfiClient.instance.waitFor<DisconnectCallback>((ev: FfiEvent) => {\n return ev.message.case == 'disconnect' && ev.message.value.asyncId == res.asyncId;\n });\n\n FfiClient.instance.removeListener(FfiClientEvent.FfiEvent, this.onFfiEvent);\n this.removeAllListeners();\n }\n\n /**\n * Registers a handler for incoming text data streams on a specific topic.\n * Text streams are used for receiving structured text data from other participants.\n * @param topic The topic to listen for text streams on\n * @param callback Function to handle incoming text stream data\n * @throws Error if a handler for this topic is already registered\n */\n registerTextStreamHandler(topic: string, callback: TextStreamHandler) {\n if (this.textStreamHandlers.has(topic)) {\n throw new Error(`A text stream handler for topic \"${topic}\" has already been set.`);\n }\n this.textStreamHandlers.set(topic, callback);\n }\n\n unregisterTextStreamHandler(topic: string) {\n this.textStreamHandlers.delete(topic);\n }\n\n /**\n * Registers a handler for incoming byte data streams on a specific topic.\n * Byte streams are used for receiving binary data like files from other participants.\n * @param topic The topic to listen for byte streams on\n * @param callback Function to handle incoming byte stream data\n * @throws Error if a handler for this topic is already registered\n */\n registerByteStreamHandler(topic: string, callback: ByteStreamHandler) {\n if (this.byteStreamHandlers.has(topic)) {\n throw new Error(`A byte stream handler for topic \"${topic}\" has already been set.`);\n }\n this.byteStreamHandlers.set(topic, callback);\n }\n\n unregisterByteStreamHandler(topic: string) {\n this.byteStreamHandlers.delete(topic);\n }\n\n private onFfiEvent = async (ffiEvent: FfiEvent) => {\n const unlock = await this.ffiEventLock.lock();\n try {\n if (!this.localParticipant || !this.ffiHandle || !this.info) {\n this.preConnectEvents.push(ffiEvent);\n return;\n }\n\n // process preConnectEvents if we received the connectCallback after the events were queued\n for (const ev of this.preConnectEvents) {\n await this.processFfiEvent(ev);\n }\n this.preConnectEvents = [];\n\n await this.processFfiEvent(ffiEvent);\n } finally {\n unlock();\n }\n };\n\n private processFfiEvent = async (ffiEvent: FfiEvent) => {\n if (!this.localParticipant || !this.ffiHandle || !this.info) {\n throw new Error('processFfiEvent called before connect');\n }\n\n if (ffiEvent.message.case == 'rpcMethodInvocation') {\n if (\n ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle\n ) {\n this.localParticipant.handleRpcMethodInvocation(\n ffiEvent.message.value.invocationId!,\n ffiEvent.message.value.method!,\n ffiEvent.message.value.requestId!,\n ffiEvent.message.value.callerIdentity!,\n ffiEvent.message.value.payload!,\n ffiEvent.message.value.responseTimeoutMs!,\n );\n }\n return;\n } else if (\n ffiEvent.message.case != 'roomEvent' ||\n ffiEvent.message.value.roomHandle != this.ffiHandle.handle\n ) {\n return;\n }\n\n const ev = ffiEvent.message.value.message;\n if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {\n console.log('Room event:', ev);\n }\n if (ev.case == 'participantConnected') {\n const participant = this.createRemoteParticipant(ev.value.info!);\n this.remoteParticipants.set(participant.identity!, participant);\n this.emit(RoomEvent.ParticipantConnected, participant);\n } else if (ev.case == 'participantDisconnected') {\n const participant = this.remoteParticipants.get(ev.value.participantIdentity!);\n if (participant) {\n this.remoteParticipants.delete(participant.identity);\n participant.info.disconnectReason = ev.value.disconnectReason;\n this.emit(RoomEvent.ParticipantDisconnected, participant);\n } else {\n console.log(`RoomEvent.ParticipantDisconnected: Could not find participant`);\n }\n } else if (ev.case == 'localTrackPublished') {\n const publication = this.localParticipant.trackPublications.get(ev.value.trackSid!);\n this.emit(RoomEvent.LocalTrackPublished, publication!, this.localParticipant);\n } else if (ev.case == 'localTrackUnpublished') {\n const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid!);\n this.localParticipant.trackPublications.delete(ev.value.publicationSid!);\n this.emit(RoomEvent.LocalTrackUnpublished, publication!, this.localParticipant!);\n } else if (ev.case == 'localTrackSubscribed') {\n const publication = this.localParticipant.trackPublications.get(ev.value.trackSid!);\n if (publication) {\n publication.resolveFirstSubscription();\n this.emit(RoomEvent.LocalTrackSubscribed, publication!.track!);\n } else {\n console.warn(`RoomEvent.LocalTrackSubscribed: Publication not found: ${ev.value.trackSid}`);\n }\n } else if (ev.case == 'trackPublished') {\n const participant = this.remoteParticipants.get(ev.value.participantIdentity!);\n const publication = new RemoteTrackPublication(ev.value.publication!);\n if (participant) {\n participant.trackPublications.set(publication.sid!, publication);\n } else {\n console.warn(\n `RoomEvent.TrackPublished: Could not find participant: ${ev.value.participantIdentity}`,\n );\n }\n this.emit(RoomEvent.TrackPublished, publication, participant!);\n } else if (ev.case == 'trackUnpublished') {\n const participant = this.requireRemoteParticipant(ev.value.participantIdentity!);\n const publication = participant.trackPublications.get(ev.value.publicationSid!);\n participant.trackPublications.delete(ev.value.publicationSid!);\n if (publication) {\n this.emit(RoomEvent.TrackUnpublished, publication, participant);\n } else {\n console.warn(`RoomEvent.TrackUnpublished: Could not find publication`);\n }\n } else if (ev.case == 'trackSubscribed') {\n const ownedTrack = ev.value.track!;\n const trackInfo = ownedTrack.info!;\n try {\n const { participant, publication } = this.requirePublicationOfRemoteParticipant(\n ev.value.participantIdentity!,\n trackInfo.sid!,\n );\n publication.subscribed = true;\n if (trackInfo.kind == TrackKind.KIND_VIDEO) {\n publication.track = new RemoteVideoTrack(ownedTrack);\n } else if (trackInfo.kind == TrackKind.KIND_AUDIO) {\n publication.track = new RemoteAudioTrack(ownedTrack);\n }\n\n this.emit(RoomEvent.TrackSubscribed, publication.track!, publication, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.TrackSubscribed: ${e.message}`);\n }\n } else if (ev.case == 'trackUnsubscribed') {\n try {\n const { participant, publication } = this.requirePublicationOfRemoteParticipant(\n ev.value.participantIdentity!,\n ev.value.trackSid!,\n );\n const track = publication.track!;\n publication.track = undefined;\n publication.subscribed = false;\n this.emit(RoomEvent.TrackUnsubscribed, track, publication, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.TrackUnsubscribed: ${e.message}`);\n }\n } else if (ev.case == 'trackSubscriptionFailed') {\n try {\n const participant = this.requireRemoteParticipant(ev.value.participantIdentity!);\n this.emit(\n RoomEvent.TrackSubscriptionFailed,\n ev.value.trackSid!,\n participant,\n ev.value.error,\n );\n } catch (e: any) {\n console.warn(`RoomEvent.TrackSubscriptionFailed: ${e.message}`);\n }\n } else if (ev.case == 'trackMuted') {\n try {\n const { participant, publication } = this.requirePublicationOfParticipant(\n ev.value.participantIdentity!,\n ev.value.trackSid!,\n );\n publication.info!.muted = true;\n if (publication.track) {\n publication.track.info!.muted = true;\n }\n this.emit(RoomEvent.TrackMuted, publication, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.TrackMuted: ${e.message}`);\n }\n } else if (ev.case == 'trackUnmuted') {\n try {\n const { participant, publication } = this.requirePublicationOfParticipant(\n ev.value.participantIdentity!,\n ev.value.trackSid!,\n );\n publication.info!.muted = false;\n if (publication.track) {\n publication.track.info!.muted = false;\n }\n this.emit(RoomEvent.TrackUnmuted, publication, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.TrackUnmuted: ${e.message}`);\n }\n } else if (ev.case == 'activeSpeakersChanged') {\n try {\n const activeSpeakers = ev.value.participantIdentities.map((identity) =>\n this.requireParticipantByIdentity(identity),\n );\n this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);\n } catch (e: any) {\n console.warn(`RoomEvent.ActiveSpeakersChanged: ${e.message}`);\n }\n } else if (ev.case == 'roomMetadataChanged') {\n this.info.metadata = ev.value.metadata ?? '';\n this.emit(RoomEvent.RoomMetadataChanged, this.info.metadata);\n } else if (ev.case == 'participantMetadataChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n participant.info.metadata = ev.value.metadata;\n this.emit(RoomEvent.ParticipantMetadataChanged, participant.metadata, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.ParticipantMetadataChanged: ${e.message}`);\n }\n } else if (ev.case == 'participantNameChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n participant.info.name = ev.value.name;\n this.emit(RoomEvent.ParticipantNameChanged, participant.name!, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.ParticipantNameChanged: ${e.message}`);\n }\n } else if (ev.case == 'participantAttributesChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n participant.info.attributes = ev.value.attributes.reduce(\n (acc, value) => {\n acc[value.key!] = value.value!;\n return acc;\n },\n {} as Record<string, string>,\n );\n if (Object.keys(ev.value.changedAttributes).length > 0) {\n const changedAttributes = ev.value.changedAttributes.reduce(\n (acc, value) => {\n acc[value.key!] = value.value!;\n return acc;\n },\n {} as Record<string, string>,\n );\n this.emit(RoomEvent.ParticipantAttributesChanged, changedAttributes, participant);\n }\n } catch (e: any) {\n console.warn(`RoomEvent.ParticipantAttributesChanged: ${e.message}`);\n }\n } else if (ev.case == 'connectionQualityChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n this.emit(RoomEvent.ConnectionQualityChanged, ev.value.quality!, participant);\n } catch (e: any) {\n console.warn(`RoomEvent.ConnectionQualityChanged: ${e.message}`);\n }\n } else if (ev.case == 'chatMessage') {\n const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity!);\n const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message!;\n const message: ChatMessage = {\n id: id!,\n message: messageText!,\n timestamp: Number(timestamp),\n editTimestamp: Number(editTimestamp),\n generated,\n };\n this.emit(RoomEvent.ChatMessage, message, participant);\n } else if (ev.case == 'dataPacketReceived') {\n // Can be undefined if the data is sent from a Server SDK\n const participant = this.remoteParticipants.get(ev.value.participantIdentity!);\n const dataPacket = ev.value.value;\n switch (dataPacket.case) {\n case 'user':\n const buffer = FfiClient.instance.copyBuffer(\n dataPacket.value.data!.data!.dataPtr!,\n Number(dataPacket.value.data!.data!.dataLen),\n );\n new FfiHandle(dataPacket.value.data!.handle!.id!).dispose();\n this.emit(\n RoomEvent.DataReceived,\n buffer,\n participant,\n ev.value.kind,\n dataPacket.value.topic,\n );\n break;\n case 'sipDtmf':\n const { code, digit } = dataPacket.value;\n this.emit(RoomEvent.DtmfReceived, code!, digit!, participant!);\n break;\n default:\n break;\n }\n } else if (ev.case == 'e2eeStateChanged') {\n if (ev.value.state == EncryptionState.INTERNAL_ERROR) {\n // throw generic error until Rust SDK is updated to supply the error alongside INTERNAL_ERROR\n this.emit(RoomEvent.EncryptionError, new Error('internal server error'));\n }\n } else if (ev.case == 'connectionStateChanged') {\n this.connectionState = ev.value.state!;\n this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);\n /*} else if (ev.case == 'connected') {\n this.emit(RoomEvent.Connected);*/\n } else if (ev.case == 'disconnected') {\n this.emit(RoomEvent.Disconnected, ev.value.reason!);\n } else if (ev.case == 'reconnecting') {\n this.emit(RoomEvent.Reconnecting);\n } else if (ev.case == 'reconnected') {\n this.emit(RoomEvent.Reconnected);\n } else if (ev.case == 'roomSidChanged') {\n this.emit(RoomEvent.RoomSidChanged, ev.value.sid!);\n } else if (ev.case === 'streamHeaderReceived' && ev.value.header) {\n this.handleStreamHeader(ev.value.header, ev.value.participantIdentity!);\n } else if (ev.case === 'streamChunkReceived' && ev.value.chunk) {\n this.handleStreamChunk(ev.value.chunk);\n } else if (ev.case === 'streamTrailerReceived' && ev.value.trailer) {\n this.handleStreamTrailer(ev.value.trailer);\n } else if (ev.case === 'roomUpdated') {\n this.info = ev.value;\n this.emit(RoomEvent.RoomUpdated);\n } else if (ev.case === 'moved') {\n this.info = ev.value;\n this.emit(RoomEvent.Moved);\n } else if (ev.case === 'participantsUpdated') {\n for (const info of ev.value.participants) {\n const participant = this.retrieveParticipantByIdentity(info.identity!);\n if (participant) {\n participant.info = info;\n }\n }\n } else if (ev.case === 'participantEncryptionStatusChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n this.emit(\n RoomEvent.ParticipantEncryptionStatusChanged,\n !!ev.value.isEncrypted,\n participant,\n );\n } catch (e: any) {\n console.warn(`RoomEvent.ParticipantEncryptionStatusChanged: ${e.message}`);\n }\n }\n };\n\n private retrieveParticipantByIdentity(identity: string): Participant | undefined {\n if (this.localParticipant?.identity === identity) {\n return this.localParticipant;\n } else {\n return this.remoteParticipants.get(identity);\n }\n }\n\n private requireParticipantByIdentity(identity: string): Participant {\n if (this.localParticipant?.identity === identity) {\n return this.localParticipant;\n } else if (this.remoteParticipants.has(identity)) {\n return this.remoteParticipants.get(identity)!;\n } else {\n throw new TypeError(`participant ${identity} not found`);\n }\n }\n\n private requireRemoteParticipant(identity: string) {\n const participant = this.remoteParticipants.get(identity);\n if (!participant) {\n throw new TypeError(`participant ${identity} not found`);\n }\n return participant;\n }\n\n private requirePublicationOfParticipant(identity: string, trackSid: string) {\n const participant = this.requireParticipantByIdentity(identity);\n const publication = participant.trackPublications.get(trackSid);\n if (!publication) {\n throw new TypeError(`publication ${trackSid} not found`);\n }\n return { participant, publication };\n }\n\n private requirePublicationOfRemoteParticipant(identity: string, trackSid: string) {\n const participant = this.requireRemoteParticipant(identity);\n const publication = participant.trackPublications.get(trackSid);\n if (!publication) {\n throw new TypeError(`publication ${trackSid} not found`);\n }\n return { participant, publication };\n }\n\n private createRemoteParticipant(ownedInfo: OwnedParticipant) {\n if (this.remoteParticipants.has(ownedInfo.info!.identity!)) {\n throw new Error('Participant already exists');\n }\n\n const participant = new RemoteParticipant(ownedInfo);\n this.remoteParticipants.set(ownedInfo.info!.identity!, participant);\n return participant;\n }\n\n private handleStreamHeader(streamHeader: DataStream_Header, participantIdentity: string) {\n if (streamHeader.contentHeader.case === 'byteHeader') {\n const streamHandlerCallback = this.byteStreamHandlers.get(streamHeader.topic ?? '');\n\n if (!streamHandlerCallback) {\n log.debug(\n 'ignoring incoming byte stream due to no handler for topic: %s',\n streamHeader.topic ?? 'undefined',\n );\n return;\n }\n let streamController: ReadableStreamDefaultController<DataStream_Chunk>;\n const stream = new ReadableStream({\n start: (controller) => {\n streamController = controller;\n this.byteStreamControllers.set(streamHeader.streamId!, {\n header: streamHeader,\n controller: streamController,\n startTime: Date.now(),\n });\n },\n });\n const info: ByteStreamInfo = {\n streamId: streamHeader.streamId!,\n name: streamHeader.contentHeader.value.name ?? 'unknown',\n mimeType: streamHeader.mimeType!,\n totalSize: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,\n topic: streamHeader.topic!,\n timestamp: bigIntToNumber(streamHeader.timestamp!),\n attributes: streamHeader.attributes,\n };\n streamHandlerCallback(\n new ByteStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)),\n { identity: participantIdentity },\n );\n } else if (streamHeader.contentHeader.case === 'textHeader') {\n const streamHandlerCallback = this.textStreamHandlers.get(streamHeader.topic ?? '');\n\n if (!streamHandlerCallback) {\n log.debug(\n 'ignoring incoming text stream due to no handler for topic: %s',\n streamHeader.topic ?? 'undefined',\n );\n return;\n }\n let streamController: ReadableStreamDefaultController<DataStream_Chunk>;\n const stream = new ReadableStream<DataStream_Chunk>({\n start: (controller) => {\n streamController = controller;\n this.textStreamControllers.set(streamHeader.streamId!, {\n header: streamHeader,\n controller: streamController,\n startTime: Date.now(),\n });\n },\n });\n const info: TextStreamInfo = {\n streamId: streamHeader.streamId!,\n mimeType: streamHeader.mimeType!,\n totalSize: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,\n topic: streamHeader.topic!,\n timestamp: Number(streamHeader.timestamp),\n attributes: streamHeader.attributes,\n };\n streamHandlerCallback(\n new TextStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)),\n { identity: participantIdentity },\n );\n }\n }\n\n private handleStreamChunk(chunk: DataStream_Chunk) {\n const fileBuffer = this.byteStreamControllers.get(chunk.streamId!);\n if (fileBuffer) {\n if (chunk.content!.length > 0) {\n fileBuffer.controller.enqueue(chunk);\n }\n }\n const textBuffer = this.textStreamControllers.get(chunk.streamId!);\n if (textBuffer) {\n if (chunk.content!.length > 0) {\n textBuffer.controller.enqueue(chunk);\n }\n }\n }\n\n private handleStreamTrailer(trailer: DataStream_Trailer) {\n const streamId = trailer.streamId!;\n const fileBuffer = this.byteStreamControllers.get(streamId);\n if (fileBuffer) {\n fileBuffer.controller.close();\n this.byteStreamControllers.delete(streamId);\n }\n const textBuffer = this.textStreamControllers.get(streamId);\n if (textBuffer) {\n textBuffer.controller.close();\n this.byteStreamControllers.delete(streamId);\n }\n }\n}\n\nexport class ConnectError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport type RoomCallbacks = {\n participantConnected: (participant: RemoteParticipant) => void;\n participantDisconnected: (participant: RemoteParticipant) => void;\n localTrackPublished: (publication: LocalTrackPublication, participant: LocalParticipant) => void;\n localTrackUnpublished: (\n publication: LocalTrackPublication,\n participant: LocalParticipant,\n ) => void;\n localTrackSubscribed: (track: LocalTrack) => void;\n trackPublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackUnpublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackSubscribed: (\n track: RemoteTrack,\n publication: RemoteTrackPublication,\n participant: RemoteParticipant,\n ) => void;\n trackUnsubscribed: (\n track: RemoteTrack,\n publication: RemoteTrackPublication,\n participant: RemoteParticipant,\n ) => void;\n trackSubscriptionFailed: (\n trackSid: string,\n participant: RemoteParticipant,\n reason?: string,\n ) => void;\n trackMuted: (publication: TrackPublication, participant: Participant) => void;\n trackUnmuted: (publication: TrackPublication, participant: Participant) => void;\n activeSpeakersChanged: (speakers: Participant[]) => void;\n roomMetadataChanged: (metadata: string) => void;\n roomInfoUpdated: (info: RoomInfo) => void;\n participantMetadataChanged: (metadata: string | undefined, participant: Participant) => void;\n participantNameChanged: (name: string, participant: Participant) => void;\n participantAttributesChanged: (\n changedAttributes: Record<string, string>,\n participant: Participant,\n ) => void;\n participantEncryptionStatusChanged: (isEncrypted: boolean, participant: Participant) => void;\n connectionQualityChanged: (quality: ConnectionQuality, participant: Participant) => void;\n dataReceived: (\n payload: Uint8Array,\n participant?: RemoteParticipant,\n kind?: DataPacketKind,\n topic?: string,\n encryptionType?: EncryptionType,\n ) => void;\n chatMessage: (message: ChatMessage, participant?: Participant) => void;\n dtmfReceived: (code: number, digit: string, participant: RemoteParticipant) => void;\n encryptionError: (error: Error) => void;\n connectionStateChanged: (state: ConnectionState) => void;\n connected: () => void;\n disconnected: (reason: DisconnectReason) => void;\n reconnecting: () => void;\n reconnected: () => void;\n roomSidChanged: (sid: string) => void;\n roomUpdated: () => void;\n moved: () => void;\n};\n\nexport enum RoomEvent {\n ParticipantConnected = 'participantConnected',\n ParticipantDisconnected = 'participantDisconnected',\n LocalTrackPublished = 'localTrackPublished',\n LocalTrackUnpublished = 'localTrackUnpublished',\n LocalTrackSubscribed = 'localTrackSubscribed',\n TrackPublished = 'trackPublished',\n TrackUnpublished = 'trackUnpublished',\n TrackSubscribed = 'trackSubscribed',\n TrackUnsubscribed = 'trackUnsubscribed',\n TrackSubscriptionFailed = 'trackSubscriptionFailed',\n TrackMuted = 'trackMuted',\n TrackUnmuted = 'trackUnmuted',\n ActiveSpeakersChanged = 'activeSpeakersChanged',\n RoomMetadataChanged = 'roomMetadataChanged',\n RoomSidChanged = 'roomSidChanged',\n ParticipantMetadataChanged = 'participantMetadataChanged',\n ParticipantNameChanged = 'participantNameChanged',\n ParticipantAttributesChanged = 'participantAttributesChanged',\n ParticipantEncryptionStatusChanged = 'participantEncryptionStatusChanged',\n ConnectionQualityChanged = 'connectionQualityChanged',\n DataReceived = 'dataReceived',\n ChatMessage = 'chatMessage',\n DtmfReceived = 'dtmfReceived',\n EncryptionError = 'encryptionError',\n ConnectionStateChanged = 'connectionStateChanged',\n Connected = 'connected',\n Disconnected = 'disconnected',\n Reconnecting = 'reconnecting',\n Reconnected = 'reconnected',\n RoomUpdated = 'roomUpdated',\n Moved = 'moved',\n}\n"],"mappings":"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","names":["RoomEvent"]}
|
|
1
|
+
{"version":3,"sources":["../src/room.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport { Mutex } from '@livekit/mutex';\nimport type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';\nimport EventEmitter from 'events';\nimport { ByteStreamReader, TextStreamReader } from './data_streams/stream_reader.js';\nimport type {\n ByteStreamHandler,\n ByteStreamInfo,\n StreamController,\n TextStreamHandler,\n TextStreamInfo,\n} from './data_streams/types.js';\nimport type { E2EEOptions } from './e2ee.js';\nimport { E2EEManager, defaultE2EEOptions } from './e2ee.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport { log } from './log.js';\nimport type { Participant } from './participant.js';\nimport { LocalParticipant, RemoteParticipant } from './participant.js';\nimport { EncryptionState, type EncryptionType } from './proto/e2ee_pb.js';\nimport type { FfiEvent } from './proto/ffi_pb.js';\nimport type { DisconnectReason, OwnedParticipant } from './proto/participant_pb.js';\nimport type { DataStream_Trailer, DisconnectCallback } from './proto/room_pb.js';\nimport {\n type ConnectCallback,\n ConnectRequest,\n type ConnectResponse,\n type ConnectionQuality,\n ConnectionState,\n ContinualGatheringPolicy,\n type DataPacketKind,\n type DataStream_Chunk,\n type DataStream_Header,\n type DisconnectResponse,\n RoomOptions as FfiRoomOptions,\n type IceServer,\n IceTransportType,\n type RoomInfo,\n} from './proto/room_pb.js';\nimport { TrackKind } from './proto/track_pb.js';\nimport type { LocalTrack, RemoteTrack } from './track.js';\nimport { RemoteAudioTrack, RemoteVideoTrack } from './track.js';\nimport type { LocalTrackPublication, TrackPublication } from './track_publication.js';\nimport { RemoteTrackPublication } from './track_publication.js';\nimport type { ChatMessage } from './types.js';\nimport { bigIntToNumber } from './utils.js';\n\nexport interface RtcConfiguration {\n iceTransportType: IceTransportType;\n continualGatheringPolicy: ContinualGatheringPolicy;\n iceServers: IceServer[];\n}\n\nexport const defaultRtcConfiguration: RtcConfiguration = {\n iceTransportType: IceTransportType.TRANSPORT_ALL,\n continualGatheringPolicy: ContinualGatheringPolicy.GATHER_CONTINUALLY,\n iceServers: [],\n};\n\nexport interface RoomOptions {\n autoSubscribe: boolean;\n dynacast: boolean;\n /**\n * @deprecated Use `encryption` instead. See x for details\n */\n e2ee?: E2EEOptions;\n encryption?: E2EEOptions;\n rtcConfig?: RtcConfiguration;\n}\n\nexport const defaultRoomOptions = new FfiRoomOptions({\n autoSubscribe: true,\n dynacast: false,\n e2ee: undefined,\n encryption: undefined,\n rtcConfig: undefined,\n adaptiveStream: false,\n joinRetries: 1,\n});\n\nexport class Room extends (EventEmitter as new () => TypedEmitter<RoomCallbacks>) {\n private info?: RoomInfo;\n private ffiHandle?: FfiHandle;\n /**\n * used to ensure events are processed sequentially and allow for\n * the local participant to acquire the lock while doing state updates related to FFI events\n * before processing the next events\n */\n private ffiEventLock = new Mutex();\n\n private byteStreamControllers = new Map<string, StreamController<DataStream_Chunk>>();\n private textStreamControllers = new Map<string, StreamController<DataStream_Chunk>>();\n private byteStreamHandlers = new Map<string, ByteStreamHandler>();\n private textStreamHandlers = new Map<string, TextStreamHandler>();\n\n private preConnectEvents: FfiEvent[] = [];\n\n e2eeManager?: E2EEManager;\n connectionState: ConnectionState = ConnectionState.CONN_DISCONNECTED;\n\n remoteParticipants: Map<string, RemoteParticipant> = new Map();\n localParticipant?: LocalParticipant;\n\n constructor() {\n super();\n }\n\n get name(): string | undefined {\n return this.info?.name;\n }\n\n get metadata(): string | undefined {\n return this.info?.metadata;\n }\n\n get isConnected(): boolean {\n return this.ffiHandle != undefined && this.connectionState != ConnectionState.CONN_DISCONNECTED;\n }\n\n /**\n * Gets the room's server ID. This ID is assigned by the LiveKit server\n * and is unique for each room session.\n * SID is assigned asynchronously after connection.\n * @returns Promise that resolves to the room's server ID, or empty string if not connected\n */\n async getSid(): Promise<string> {\n if (!this.isConnected) {\n return '';\n }\n if (this.info?.sid && this.info.sid !== '') {\n return this.info.sid;\n }\n return new Promise((resolve, reject) => {\n const handleRoomUpdate = (sid: string) => {\n if (sid !== '') {\n this.off(RoomEvent.RoomSidChanged, handleRoomUpdate);\n resolve(sid);\n }\n };\n this.on(RoomEvent.RoomSidChanged, handleRoomUpdate);\n this.once(RoomEvent.Disconnected, () => {\n this.off(RoomEvent.RoomSidChanged, handleRoomUpdate);\n reject('Room disconnected before room server id was available');\n });\n });\n }\n\n get numParticipants(): number {\n return this.info?.numParticipants ?? 0;\n }\n\n get numPublishers(): number {\n return this.info?.numPublishers ?? 0;\n }\n\n get creationTime(): Date {\n return new Date(Number(this.info?.creationTime ?? 0));\n }\n\n get isRecording(): boolean {\n return this.info?.activeRecording ?? false;\n }\n\n /**\n * The time in seconds after which a room will be closed after the last\n * participant has disconnected.\n */\n get departureTimeout(): number {\n return this.info?.departureTimeout ?? 0;\n }\n\n /**\n * The time in seconds after which an empty room will be automatically closed.\n */\n get emptyTimeout(): number {\n return this.info?.emptyTimeout ?? 0;\n }\n\n /**\n * Connects to a LiveKit room using the provided URL and access token.\n * @param url - The WebSocket URL of the LiveKit server\n * @param token - A valid LiveKit access token for authentication\n * @param opts - Optional room configuration options\n * @throws ConnectError - if connection fails\n */\n async connect(url: string, token: string, opts?: RoomOptions) {\n const options = { ...defaultRoomOptions, ...opts };\n const e2eeEnabled = options.encryption || options.e2ee;\n const e2eeOptions = options.encryption\n ? { ...defaultE2EEOptions, ...options.encryption }\n : { ...defaultE2EEOptions, ...options.e2ee };\n\n const req = new ConnectRequest({\n url: url,\n token: token,\n options,\n });\n\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onFfiEvent);\n\n const res = FfiClient.instance.request<ConnectResponse>({\n message: {\n case: 'connect',\n value: req,\n },\n });\n\n const cb = await FfiClient.instance.waitFor<ConnectCallback>((ev: FfiEvent) => {\n return ev.message.case == 'connect' && ev.message.value.asyncId == res.asyncId;\n });\n\n log.debug('Connect callback received');\n\n switch (cb.message.case) {\n case 'result':\n this.ffiHandle = new FfiHandle(cb.message.value.room!.handle!.id!);\n this.e2eeManager = e2eeEnabled && new E2EEManager(this.ffiHandle.handle, e2eeOptions);\n\n this.info = cb.message.value.room!.info;\n this.connectionState = ConnectionState.CONN_CONNECTED;\n this.localParticipant = new LocalParticipant(\n cb.message.value.localParticipant!,\n this.ffiEventLock,\n );\n\n for (const pt of cb.message.value.participants) {\n const rp = this.createRemoteParticipant(pt.participant!);\n\n for (const pub of pt.publications) {\n const publication = new RemoteTrackPublication(pub);\n rp.trackPublications.set(publication.sid!, publication);\n }\n }\n break;\n case 'error':\n default:\n throw new ConnectError(cb.message.value || '');\n }\n }\n\n /**\n * Disconnects from the room and cleans up all resources.\n * This will stop all tracks and close the connection.\n */\n async disconnect() {\n if (!this.isConnected) {\n return;\n }\n\n const res = FfiClient.instance.request<DisconnectResponse>({\n message: {\n case: 'disconnect',\n value: {\n roomHandle: this.ffiHandle?.handle,\n },\n },\n });\n\n await FfiClient.instance.waitFor<DisconnectCallback>((ev: FfiEvent) => {\n return ev.message.case == 'disconnect' && ev.message.value.asyncId == res.asyncId;\n });\n\n FfiClient.instance.removeListener(FfiClientEvent.FfiEvent, this.onFfiEvent);\n this.removeAllListeners();\n }\n\n /**\n * Registers a handler for incoming text data streams on a specific topic.\n * Text streams are used for receiving structured text data from other participants.\n * @param topic - The topic to listen for text streams on\n * @param callback - Function to handle incoming text stream data\n * @throws Error - if a handler for this topic is already registered\n */\n registerTextStreamHandler(topic: string, callback: TextStreamHandler) {\n if (this.textStreamHandlers.has(topic)) {\n throw new Error(`A text stream handler for topic \"${topic}\" has already been set.`);\n }\n this.textStreamHandlers.set(topic, callback);\n }\n\n unregisterTextStreamHandler(topic: string) {\n this.textStreamHandlers.delete(topic);\n }\n\n /**\n * Registers a handler for incoming byte data streams on a specific topic.\n * Byte streams are used for receiving binary data like files from other participants.\n * @param topic - The topic to listen for byte streams on\n * @param callback - Function to handle incoming byte stream data\n * @throws Error - if a handler for this topic is already registered\n */\n registerByteStreamHandler(topic: string, callback: ByteStreamHandler) {\n if (this.byteStreamHandlers.has(topic)) {\n throw new Error(`A byte stream handler for topic \"${topic}\" has already been set.`);\n }\n this.byteStreamHandlers.set(topic, callback);\n }\n\n unregisterByteStreamHandler(topic: string) {\n this.byteStreamHandlers.delete(topic);\n }\n\n private onFfiEvent = async (ffiEvent: FfiEvent) => {\n const unlock = await this.ffiEventLock.lock();\n try {\n if (!this.localParticipant || !this.ffiHandle || !this.info) {\n this.preConnectEvents.push(ffiEvent);\n return;\n }\n\n // process preConnectEvents if we received the connectCallback after the events were queued\n for (const ev of this.preConnectEvents) {\n await this.processFfiEvent(ev);\n }\n this.preConnectEvents = [];\n\n await this.processFfiEvent(ffiEvent);\n } finally {\n unlock();\n }\n };\n\n private processFfiEvent = async (ffiEvent: FfiEvent) => {\n if (!this.localParticipant || !this.ffiHandle || !this.info) {\n throw new Error('processFfiEvent called before connect');\n }\n\n if (ffiEvent.message.case == 'rpcMethodInvocation') {\n if (\n ffiEvent.message.value.localParticipantHandle == this.localParticipant.ffi_handle.handle\n ) {\n this.localParticipant.handleRpcMethodInvocation(\n ffiEvent.message.value.invocationId!,\n ffiEvent.message.value.method!,\n ffiEvent.message.value.requestId!,\n ffiEvent.message.value.callerIdentity!,\n ffiEvent.message.value.payload!,\n ffiEvent.message.value.responseTimeoutMs!,\n );\n }\n return;\n } else if (\n ffiEvent.message.case != 'roomEvent' ||\n ffiEvent.message.value.roomHandle != this.ffiHandle.handle\n ) {\n return;\n }\n\n const ev = ffiEvent.message.value.message;\n if (process.env.LIVEKIT_DEBUG_LOG_ROOM_EVENTS) {\n console.log('Room event:', ev);\n }\n if (ev.case == 'participantConnected') {\n const participant = this.createRemoteParticipant(ev.value.info!);\n this.remoteParticipants.set(participant.identity!, participant);\n this.emit(RoomEvent.ParticipantConnected, participant);\n } else if (ev.case == 'participantDisconnected') {\n const participant = this.remoteParticipants.get(ev.value.participantIdentity!);\n if (participant) {\n this.remoteParticipants.delete(participant.identity);\n participant.info.disconnectReason = ev.value.disconnectReason;\n this.emit(RoomEvent.ParticipantDisconnected, participant);\n } else {\n console.log(`RoomEvent.ParticipantDisconnected: Could not find participant`);\n }\n } else if (ev.case == 'localTrackPublished') {\n const publication = this.localParticipant.trackPublications.get(ev.value.trackSid!);\n this.emit(RoomEvent.LocalTrackPublished, publication!, this.localParticipant);\n } else if (ev.case == 'localTrackUnpublished') {\n const publication = this.localParticipant.trackPublications.get(ev.value.publicationSid!);\n this.localParticipant.trackPublications.delete(ev.value.publicationSid!);\n this.emit(RoomEvent.LocalTrackUnpublished, publication!, this.localParticipant!);\n } else if (ev.case == 'localTrackSubscribed') {\n const publication = this.localParticipant.trackPublications.get(ev.value.trackSid!);\n if (publication) {\n publication.resolveFirstSubscription();\n this.emit(RoomEvent.LocalTrackSubscribed, publication!.track!);\n } else {\n console.warn(`RoomEvent.LocalTrackSubscribed: Publication not found: ${ev.value.trackSid}`);\n }\n } else if (ev.case == 'trackPublished') {\n const participant = this.remoteParticipants.get(ev.value.participantIdentity!);\n const publication = new RemoteTrackPublication(ev.value.publication!);\n if (participant) {\n participant.trackPublications.set(publication.sid!, publication);\n } else {\n console.warn(\n `RoomEvent.TrackPublished: Could not find participant: ${ev.value.participantIdentity}`,\n );\n }\n this.emit(RoomEvent.TrackPublished, publication, participant!);\n } else if (ev.case == 'trackUnpublished') {\n const participant = this.requireRemoteParticipant(ev.value.participantIdentity!);\n const publication = participant.trackPublications.get(ev.value.publicationSid!);\n participant.trackPublications.delete(ev.value.publicationSid!);\n if (publication) {\n this.emit(RoomEvent.TrackUnpublished, publication, participant);\n } else {\n console.warn(`RoomEvent.TrackUnpublished: Could not find publication`);\n }\n } else if (ev.case == 'trackSubscribed') {\n const ownedTrack = ev.value.track!;\n const trackInfo = ownedTrack.info!;\n try {\n const { participant, publication } = this.requirePublicationOfRemoteParticipant(\n ev.value.participantIdentity!,\n trackInfo.sid!,\n );\n publication.subscribed = true;\n if (trackInfo.kind == TrackKind.KIND_VIDEO) {\n publication.track = new RemoteVideoTrack(ownedTrack);\n } else if (trackInfo.kind == TrackKind.KIND_AUDIO) {\n publication.track = new RemoteAudioTrack(ownedTrack);\n }\n\n this.emit(RoomEvent.TrackSubscribed, publication.track!, publication, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.TrackSubscribed: ${(e as Error).message}`);\n }\n } else if (ev.case == 'trackUnsubscribed') {\n try {\n const { participant, publication } = this.requirePublicationOfRemoteParticipant(\n ev.value.participantIdentity!,\n ev.value.trackSid!,\n );\n const track = publication.track!;\n publication.track = undefined;\n publication.subscribed = false;\n this.emit(RoomEvent.TrackUnsubscribed, track, publication, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.TrackUnsubscribed: ${(e as Error).message}`);\n }\n } else if (ev.case == 'trackSubscriptionFailed') {\n try {\n const participant = this.requireRemoteParticipant(ev.value.participantIdentity!);\n this.emit(\n RoomEvent.TrackSubscriptionFailed,\n ev.value.trackSid!,\n participant,\n ev.value.error,\n );\n } catch (e: unknown) {\n console.warn(`RoomEvent.TrackSubscriptionFailed: ${(e as Error).message}`);\n }\n } else if (ev.case == 'trackMuted') {\n try {\n const { participant, publication } = this.requirePublicationOfParticipant(\n ev.value.participantIdentity!,\n ev.value.trackSid!,\n );\n publication.info!.muted = true;\n if (publication.track) {\n publication.track.info!.muted = true;\n }\n this.emit(RoomEvent.TrackMuted, publication, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.TrackMuted: ${(e as Error).message}`);\n }\n } else if (ev.case == 'trackUnmuted') {\n try {\n const { participant, publication } = this.requirePublicationOfParticipant(\n ev.value.participantIdentity!,\n ev.value.trackSid!,\n );\n publication.info!.muted = false;\n if (publication.track) {\n publication.track.info!.muted = false;\n }\n this.emit(RoomEvent.TrackUnmuted, publication, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.TrackUnmuted: ${(e as Error).message}`);\n }\n } else if (ev.case == 'activeSpeakersChanged') {\n try {\n const activeSpeakers = ev.value.participantIdentities.map((identity) =>\n this.requireParticipantByIdentity(identity),\n );\n this.emit(RoomEvent.ActiveSpeakersChanged, activeSpeakers);\n } catch (e: unknown) {\n console.warn(`RoomEvent.ActiveSpeakersChanged: ${(e as Error).message}`);\n }\n } else if (ev.case == 'roomMetadataChanged') {\n this.info.metadata = ev.value.metadata ?? '';\n this.emit(RoomEvent.RoomMetadataChanged, this.info.metadata);\n } else if (ev.case == 'participantMetadataChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n participant.info.metadata = ev.value.metadata;\n this.emit(RoomEvent.ParticipantMetadataChanged, participant.metadata, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.ParticipantMetadataChanged: ${(e as Error).message}`);\n }\n } else if (ev.case == 'participantNameChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n participant.info.name = ev.value.name;\n this.emit(RoomEvent.ParticipantNameChanged, participant.name!, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.ParticipantNameChanged: ${(e as Error).message}`);\n }\n } else if (ev.case == 'participantAttributesChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n participant.info.attributes = ev.value.attributes.reduce(\n (acc, value) => {\n acc[value.key!] = value.value!;\n return acc;\n },\n {} as Record<string, string>,\n );\n if (Object.keys(ev.value.changedAttributes).length > 0) {\n const changedAttributes = ev.value.changedAttributes.reduce(\n (acc, value) => {\n acc[value.key!] = value.value!;\n return acc;\n },\n {} as Record<string, string>,\n );\n this.emit(RoomEvent.ParticipantAttributesChanged, changedAttributes, participant);\n }\n } catch (e: unknown) {\n console.warn(`RoomEvent.ParticipantAttributesChanged: ${(e as Error).message}`);\n }\n } else if (ev.case == 'connectionQualityChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n this.emit(RoomEvent.ConnectionQualityChanged, ev.value.quality!, participant);\n } catch (e: unknown) {\n console.warn(`RoomEvent.ConnectionQualityChanged: ${(e as Error).message}`);\n }\n } else if (ev.case == 'chatMessage') {\n const participant = this.retrieveParticipantByIdentity(ev.value.participantIdentity!);\n const { id, message: messageText, timestamp, editTimestamp, generated } = ev.value.message!;\n const message: ChatMessage = {\n id: id!,\n message: messageText!,\n timestamp: Number(timestamp),\n editTimestamp: Number(editTimestamp),\n generated,\n };\n this.emit(RoomEvent.ChatMessage, message, participant);\n } else if (ev.case == 'dataPacketReceived') {\n // Can be undefined if the data is sent from a Server SDK\n const participant = this.remoteParticipants.get(ev.value.participantIdentity!);\n const dataPacket = ev.value.value;\n switch (dataPacket.case) {\n case 'user':\n const buffer = FfiClient.instance.copyBuffer(\n dataPacket.value.data!.data!.dataPtr!,\n Number(dataPacket.value.data!.data!.dataLen),\n );\n new FfiHandle(dataPacket.value.data!.handle!.id!).dispose();\n this.emit(\n RoomEvent.DataReceived,\n buffer,\n participant,\n ev.value.kind,\n dataPacket.value.topic,\n );\n break;\n case 'sipDtmf':\n const { code, digit } = dataPacket.value;\n this.emit(RoomEvent.DtmfReceived, code!, digit!, participant!);\n break;\n default:\n break;\n }\n } else if (ev.case == 'e2eeStateChanged') {\n if (ev.value.state == EncryptionState.INTERNAL_ERROR) {\n // throw generic error until Rust SDK is updated to supply the error alongside INTERNAL_ERROR\n this.emit(RoomEvent.EncryptionError, new Error('internal server error'));\n }\n } else if (ev.case == 'connectionStateChanged') {\n this.connectionState = ev.value.state!;\n this.emit(RoomEvent.ConnectionStateChanged, this.connectionState);\n /*} else if (ev.case == 'connected') {\n this.emit(RoomEvent.Connected);*/\n } else if (ev.case == 'disconnected') {\n this.emit(RoomEvent.Disconnected, ev.value.reason!);\n } else if (ev.case == 'reconnecting') {\n this.emit(RoomEvent.Reconnecting);\n } else if (ev.case == 'reconnected') {\n this.emit(RoomEvent.Reconnected);\n } else if (ev.case == 'roomSidChanged') {\n this.emit(RoomEvent.RoomSidChanged, ev.value.sid!);\n } else if (ev.case === 'streamHeaderReceived' && ev.value.header) {\n this.handleStreamHeader(ev.value.header, ev.value.participantIdentity!);\n } else if (ev.case === 'streamChunkReceived' && ev.value.chunk) {\n this.handleStreamChunk(ev.value.chunk);\n } else if (ev.case === 'streamTrailerReceived' && ev.value.trailer) {\n this.handleStreamTrailer(ev.value.trailer);\n } else if (ev.case === 'roomUpdated') {\n this.info = ev.value;\n this.emit(RoomEvent.RoomUpdated);\n } else if (ev.case === 'moved') {\n this.info = ev.value;\n this.emit(RoomEvent.Moved);\n } else if (ev.case === 'participantsUpdated') {\n for (const info of ev.value.participants) {\n const participant = this.retrieveParticipantByIdentity(info.identity!);\n if (participant) {\n participant.info = info;\n }\n }\n } else if (ev.case === 'participantEncryptionStatusChanged') {\n try {\n const participant = this.requireParticipantByIdentity(ev.value.participantIdentity!);\n this.emit(\n RoomEvent.ParticipantEncryptionStatusChanged,\n !!ev.value.isEncrypted,\n participant,\n );\n } catch (e: unknown) {\n console.warn(`RoomEvent.ParticipantEncryptionStatusChanged: ${(e as Error).message}`);\n }\n }\n };\n\n private retrieveParticipantByIdentity(identity: string): Participant | undefined {\n if (this.localParticipant?.identity === identity) {\n return this.localParticipant;\n } else {\n return this.remoteParticipants.get(identity);\n }\n }\n\n private requireParticipantByIdentity(identity: string): Participant {\n if (this.localParticipant?.identity === identity) {\n return this.localParticipant;\n } else if (this.remoteParticipants.has(identity)) {\n return this.remoteParticipants.get(identity)!;\n } else {\n throw new TypeError(`participant ${identity} not found`);\n }\n }\n\n private requireRemoteParticipant(identity: string) {\n const participant = this.remoteParticipants.get(identity);\n if (!participant) {\n throw new TypeError(`participant ${identity} not found`);\n }\n return participant;\n }\n\n private requirePublicationOfParticipant(identity: string, trackSid: string) {\n const participant = this.requireParticipantByIdentity(identity);\n const publication = participant.trackPublications.get(trackSid);\n if (!publication) {\n throw new TypeError(`publication ${trackSid} not found`);\n }\n return { participant, publication };\n }\n\n private requirePublicationOfRemoteParticipant(identity: string, trackSid: string) {\n const participant = this.requireRemoteParticipant(identity);\n const publication = participant.trackPublications.get(trackSid);\n if (!publication) {\n throw new TypeError(`publication ${trackSid} not found`);\n }\n return { participant, publication };\n }\n\n private createRemoteParticipant(ownedInfo: OwnedParticipant) {\n if (this.remoteParticipants.has(ownedInfo.info!.identity!)) {\n throw new Error('Participant already exists');\n }\n\n const participant = new RemoteParticipant(ownedInfo);\n this.remoteParticipants.set(ownedInfo.info!.identity!, participant);\n return participant;\n }\n\n private handleStreamHeader(streamHeader: DataStream_Header, participantIdentity: string) {\n if (streamHeader.contentHeader.case === 'byteHeader') {\n const streamHandlerCallback = this.byteStreamHandlers.get(streamHeader.topic ?? '');\n\n if (!streamHandlerCallback) {\n log.debug(\n 'ignoring incoming byte stream due to no handler for topic: %s',\n streamHeader.topic ?? 'undefined',\n );\n return;\n }\n let streamController: ReadableStreamDefaultController<DataStream_Chunk>;\n const stream = new ReadableStream({\n start: (controller) => {\n streamController = controller;\n this.byteStreamControllers.set(streamHeader.streamId!, {\n header: streamHeader,\n controller: streamController,\n startTime: Date.now(),\n });\n },\n });\n const info: ByteStreamInfo = {\n streamId: streamHeader.streamId!,\n name: streamHeader.contentHeader.value.name ?? 'unknown',\n mimeType: streamHeader.mimeType!,\n totalSize: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,\n topic: streamHeader.topic!,\n timestamp: bigIntToNumber(streamHeader.timestamp!),\n attributes: streamHeader.attributes,\n };\n streamHandlerCallback(\n new ByteStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)),\n { identity: participantIdentity },\n );\n } else if (streamHeader.contentHeader.case === 'textHeader') {\n const streamHandlerCallback = this.textStreamHandlers.get(streamHeader.topic ?? '');\n\n if (!streamHandlerCallback) {\n log.debug(\n 'ignoring incoming text stream due to no handler for topic: %s',\n streamHeader.topic ?? 'undefined',\n );\n return;\n }\n let streamController: ReadableStreamDefaultController<DataStream_Chunk>;\n const stream = new ReadableStream<DataStream_Chunk>({\n start: (controller) => {\n streamController = controller;\n this.textStreamControllers.set(streamHeader.streamId!, {\n header: streamHeader,\n controller: streamController,\n startTime: Date.now(),\n });\n },\n });\n const info: TextStreamInfo = {\n streamId: streamHeader.streamId!,\n mimeType: streamHeader.mimeType!,\n totalSize: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,\n topic: streamHeader.topic!,\n timestamp: Number(streamHeader.timestamp),\n attributes: streamHeader.attributes,\n };\n streamHandlerCallback(\n new TextStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)),\n { identity: participantIdentity },\n );\n }\n }\n\n private handleStreamChunk(chunk: DataStream_Chunk) {\n const fileBuffer = this.byteStreamControllers.get(chunk.streamId!);\n if (fileBuffer) {\n if (chunk.content!.length > 0) {\n fileBuffer.controller.enqueue(chunk);\n }\n }\n const textBuffer = this.textStreamControllers.get(chunk.streamId!);\n if (textBuffer) {\n if (chunk.content!.length > 0) {\n textBuffer.controller.enqueue(chunk);\n }\n }\n }\n\n private handleStreamTrailer(trailer: DataStream_Trailer) {\n const streamId = trailer.streamId!;\n const fileBuffer = this.byteStreamControllers.get(streamId);\n if (fileBuffer) {\n fileBuffer.controller.close();\n this.byteStreamControllers.delete(streamId);\n }\n const textBuffer = this.textStreamControllers.get(streamId);\n if (textBuffer) {\n textBuffer.controller.close();\n this.byteStreamControllers.delete(streamId);\n }\n }\n}\n\nexport class ConnectError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nexport type RoomCallbacks = {\n participantConnected: (participant: RemoteParticipant) => void;\n participantDisconnected: (participant: RemoteParticipant) => void;\n localTrackPublished: (publication: LocalTrackPublication, participant: LocalParticipant) => void;\n localTrackUnpublished: (\n publication: LocalTrackPublication,\n participant: LocalParticipant,\n ) => void;\n localTrackSubscribed: (track: LocalTrack) => void;\n trackPublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackUnpublished: (publication: RemoteTrackPublication, participant: RemoteParticipant) => void;\n trackSubscribed: (\n track: RemoteTrack,\n publication: RemoteTrackPublication,\n participant: RemoteParticipant,\n ) => void;\n trackUnsubscribed: (\n track: RemoteTrack,\n publication: RemoteTrackPublication,\n participant: RemoteParticipant,\n ) => void;\n trackSubscriptionFailed: (\n trackSid: string,\n participant: RemoteParticipant,\n reason?: string,\n ) => void;\n trackMuted: (publication: TrackPublication, participant: Participant) => void;\n trackUnmuted: (publication: TrackPublication, participant: Participant) => void;\n activeSpeakersChanged: (speakers: Participant[]) => void;\n roomMetadataChanged: (metadata: string) => void;\n roomInfoUpdated: (info: RoomInfo) => void;\n participantMetadataChanged: (metadata: string | undefined, participant: Participant) => void;\n participantNameChanged: (name: string, participant: Participant) => void;\n participantAttributesChanged: (\n changedAttributes: Record<string, string>,\n participant: Participant,\n ) => void;\n participantEncryptionStatusChanged: (isEncrypted: boolean, participant: Participant) => void;\n connectionQualityChanged: (quality: ConnectionQuality, participant: Participant) => void;\n dataReceived: (\n payload: Uint8Array,\n participant?: RemoteParticipant,\n kind?: DataPacketKind,\n topic?: string,\n encryptionType?: EncryptionType,\n ) => void;\n chatMessage: (message: ChatMessage, participant?: Participant) => void;\n dtmfReceived: (code: number, digit: string, participant: RemoteParticipant) => void;\n encryptionError: (error: Error) => void;\n connectionStateChanged: (state: ConnectionState) => void;\n connected: () => void;\n disconnected: (reason: DisconnectReason) => void;\n reconnecting: () => void;\n reconnected: () => void;\n roomSidChanged: (sid: string) => void;\n roomUpdated: () => void;\n moved: () => void;\n};\n\nexport enum RoomEvent {\n ParticipantConnected = 'participantConnected',\n ParticipantDisconnected = 'participantDisconnected',\n LocalTrackPublished = 'localTrackPublished',\n LocalTrackUnpublished = 'localTrackUnpublished',\n LocalTrackSubscribed = 'localTrackSubscribed',\n TrackPublished = 'trackPublished',\n TrackUnpublished = 'trackUnpublished',\n TrackSubscribed = 'trackSubscribed',\n TrackUnsubscribed = 'trackUnsubscribed',\n TrackSubscriptionFailed = 'trackSubscriptionFailed',\n TrackMuted = 'trackMuted',\n TrackUnmuted = 'trackUnmuted',\n ActiveSpeakersChanged = 'activeSpeakersChanged',\n RoomMetadataChanged = 'roomMetadataChanged',\n RoomSidChanged = 'roomSidChanged',\n ParticipantMetadataChanged = 'participantMetadataChanged',\n ParticipantNameChanged = 'participantNameChanged',\n ParticipantAttributesChanged = 'participantAttributesChanged',\n ParticipantEncryptionStatusChanged = 'participantEncryptionStatusChanged',\n ConnectionQualityChanged = 'connectionQualityChanged',\n DataReceived = 'dataReceived',\n ChatMessage = 'chatMessage',\n DtmfReceived = 'dtmfReceived',\n EncryptionError = 'encryptionError',\n ConnectionStateChanged = 'connectionStateChanged',\n Connected = 'connected',\n Disconnected = 'disconnected',\n Reconnecting = 'reconnecting',\n Reconnected = 'reconnected',\n RoomUpdated = 'roomUpdated',\n Moved = 'moved',\n}\n"],"mappings":"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","names":["RoomEvent"]}
|
package/dist/version.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(version_exports, {
|
|
|
21
21
|
SDK_VERSION: () => SDK_VERSION
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(version_exports);
|
|
24
|
-
const SDK_VERSION = "0.13.
|
|
24
|
+
const SDK_VERSION = "0.13.23";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
SDK_VERSION
|
package/dist/version.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.23\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;","names":[]}
|
package/dist/version.d.cts
CHANGED
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.23\";\n"],"mappings":"AAAO,MAAM,cAAc;","names":[]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "LiveKit RTC Node",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"author": "LiveKit",
|
|
6
|
-
"version": "0.13.
|
|
6
|
+
"version": "0.13.23",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"require": "dist/index.cjs",
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
@@ -62,11 +62,11 @@
|
|
|
62
62
|
"typescript": "5.8.2"
|
|
63
63
|
},
|
|
64
64
|
"optionalDependencies": {
|
|
65
|
-
"@livekit/rtc-node-darwin-arm64": "0.13.
|
|
66
|
-
"@livekit/rtc-node-darwin-x64": "0.13.
|
|
67
|
-
"@livekit/rtc-node-linux-arm64-gnu": "0.13.
|
|
68
|
-
"@livekit/rtc-node-linux-x64-gnu": "0.13.
|
|
69
|
-
"@livekit/rtc-node-win32-x64-msvc": "0.13.
|
|
65
|
+
"@livekit/rtc-node-darwin-arm64": "0.13.23",
|
|
66
|
+
"@livekit/rtc-node-darwin-x64": "0.13.23",
|
|
67
|
+
"@livekit/rtc-node-linux-arm64-gnu": "0.13.23",
|
|
68
|
+
"@livekit/rtc-node-linux-x64-gnu": "0.13.23",
|
|
69
|
+
"@livekit/rtc-node-win32-x64-msvc": "0.13.23"
|
|
70
70
|
},
|
|
71
71
|
"engines": {
|
|
72
72
|
"node": ">= 18"
|
package/src/audio_frame.ts
CHANGED
|
@@ -11,6 +11,8 @@ export class AudioFrame {
|
|
|
11
11
|
channels: number;
|
|
12
12
|
samplesPerChannel: number;
|
|
13
13
|
|
|
14
|
+
private _userdata: Record<string, unknown> = {};
|
|
15
|
+
|
|
14
16
|
// note: if converting from Uint8Array to Int16Array, *do not* use buffer.slice!
|
|
15
17
|
// it is marked unstable by Node and can cause undefined behaviour, such as massive chunks of
|
|
16
18
|
// noise being added to the end.
|
|
@@ -51,6 +53,11 @@ export class AudioFrame {
|
|
|
51
53
|
samplesPerChannel: this.samplesPerChannel,
|
|
52
54
|
});
|
|
53
55
|
}
|
|
56
|
+
|
|
57
|
+
/** Returns the user data associated with the audio frame. */
|
|
58
|
+
get userdata() {
|
|
59
|
+
return this._userdata;
|
|
60
|
+
}
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
/**
|
package/src/audio_stream.ts
CHANGED
|
@@ -5,12 +5,14 @@ import type { UnderlyingSource } from 'node:stream/web';
|
|
|
5
5
|
import { AudioFrame } from './audio_frame.js';
|
|
6
6
|
import type { FfiEvent } from './ffi_client.js';
|
|
7
7
|
import { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';
|
|
8
|
+
import { FrameProcessor } from './frame_processor.js';
|
|
9
|
+
import { log } from './log.js';
|
|
8
10
|
import type { NewAudioStreamResponse } from './proto/audio_frame_pb.js';
|
|
9
11
|
import { AudioStreamType, NewAudioStreamRequest } from './proto/audio_frame_pb.js';
|
|
10
12
|
import type { Track } from './track.js';
|
|
11
13
|
|
|
12
14
|
export interface AudioStreamOptions {
|
|
13
|
-
noiseCancellation?: NoiseCancellationOptions
|
|
15
|
+
noiseCancellation?: NoiseCancellationOptions | FrameProcessor<AudioFrame>;
|
|
14
16
|
sampleRate?: number;
|
|
15
17
|
numChannels?: number;
|
|
16
18
|
frameSizeMs?: number;
|
|
@@ -18,6 +20,7 @@ export interface AudioStreamOptions {
|
|
|
18
20
|
|
|
19
21
|
export interface NoiseCancellationOptions {
|
|
20
22
|
moduleId: string;
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
24
|
options: Record<string, any>;
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -26,7 +29,8 @@ class AudioStreamSource implements UnderlyingSource<AudioFrame> {
|
|
|
26
29
|
private ffiHandle: FfiHandle;
|
|
27
30
|
private sampleRate: number;
|
|
28
31
|
private numChannels: number;
|
|
29
|
-
private
|
|
32
|
+
private legacyNcOptions?: NoiseCancellationOptions;
|
|
33
|
+
private frameProcessor?: FrameProcessor<AudioFrame>;
|
|
30
34
|
private frameSizeMs?: number;
|
|
31
35
|
|
|
32
36
|
constructor(
|
|
@@ -37,7 +41,11 @@ class AudioStreamSource implements UnderlyingSource<AudioFrame> {
|
|
|
37
41
|
if (sampleRateOrOptions !== undefined && typeof sampleRateOrOptions !== 'number') {
|
|
38
42
|
this.sampleRate = sampleRateOrOptions.sampleRate ?? 48000;
|
|
39
43
|
this.numChannels = sampleRateOrOptions.numChannels ?? 1;
|
|
40
|
-
|
|
44
|
+
if (sampleRateOrOptions.noiseCancellation instanceof FrameProcessor) {
|
|
45
|
+
this.frameProcessor = sampleRateOrOptions.noiseCancellation;
|
|
46
|
+
} else {
|
|
47
|
+
this.legacyNcOptions = sampleRateOrOptions.noiseCancellation;
|
|
48
|
+
}
|
|
41
49
|
this.frameSizeMs = sampleRateOrOptions.frameSizeMs;
|
|
42
50
|
} else {
|
|
43
51
|
this.sampleRate = (sampleRateOrOptions as number) ?? 48000;
|
|
@@ -50,10 +58,10 @@ class AudioStreamSource implements UnderlyingSource<AudioFrame> {
|
|
|
50
58
|
sampleRate: this.sampleRate,
|
|
51
59
|
numChannels: this.numChannels,
|
|
52
60
|
frameSizeMs: this.frameSizeMs,
|
|
53
|
-
...(this.
|
|
61
|
+
...(this.legacyNcOptions
|
|
54
62
|
? {
|
|
55
|
-
audioFilterModuleId: this.
|
|
56
|
-
audioFilterOptions: JSON.stringify(this.
|
|
63
|
+
audioFilterModuleId: this.legacyNcOptions.moduleId,
|
|
64
|
+
audioFilterOptions: JSON.stringify(this.legacyNcOptions.options),
|
|
57
65
|
}
|
|
58
66
|
: {}),
|
|
59
67
|
});
|
|
@@ -85,7 +93,14 @@ class AudioStreamSource implements UnderlyingSource<AudioFrame> {
|
|
|
85
93
|
const streamEvent = ev.message.value.message;
|
|
86
94
|
switch (streamEvent.case) {
|
|
87
95
|
case 'frameReceived':
|
|
88
|
-
|
|
96
|
+
let frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame!);
|
|
97
|
+
if (this.frameProcessor && this.frameProcessor.isEnabled()) {
|
|
98
|
+
try {
|
|
99
|
+
frame = this.frameProcessor.process(frame);
|
|
100
|
+
} catch (err: unknown) {
|
|
101
|
+
log.warn(`Frame processing failed, passing through original frame: ${err}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
89
104
|
this.controller.enqueue(frame);
|
|
90
105
|
break;
|
|
91
106
|
case 'eos':
|
|
@@ -53,14 +53,14 @@ export class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
|
|
|
53
53
|
try {
|
|
54
54
|
const { done, value } = await reader.read();
|
|
55
55
|
if (done) {
|
|
56
|
-
return { done: true, value: undefined as
|
|
56
|
+
return { done: true, value: undefined as unknown };
|
|
57
57
|
} else {
|
|
58
58
|
this.handleChunkReceived(value);
|
|
59
59
|
return { done: false, value: value.content! };
|
|
60
60
|
}
|
|
61
|
-
} catch (error:
|
|
61
|
+
} catch (error: unknown) {
|
|
62
62
|
log.error('error processing stream update: %s', error);
|
|
63
|
-
return { done: true, value: undefined };
|
|
63
|
+
return { done: true, value: undefined as unknown };
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
66
|
|
|
@@ -135,7 +135,7 @@ export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
|
|
|
135
135
|
value: decoder.decode(value.content!),
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
|
-
} catch (error:
|
|
138
|
+
} catch (error: unknown) {
|
|
139
139
|
log.error('error processing stream update: %s', error);
|
|
140
140
|
return { done: true, value: undefined };
|
|
141
141
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2025 LiveKit, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { type AudioFrame } from './audio_frame.js';
|
|
5
|
+
import { type VideoFrame } from './video_frame.js';
|
|
6
|
+
|
|
7
|
+
export type FrameProcessorStreamInfo = {
|
|
8
|
+
roomName: string;
|
|
9
|
+
participantIdentity: string;
|
|
10
|
+
publicationSid: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type FrameProcessorCredentials = {
|
|
14
|
+
token: string;
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export abstract class FrameProcessor<Frame extends VideoFrame | AudioFrame> {
|
|
19
|
+
abstract isEnabled(): boolean;
|
|
20
|
+
abstract setEnabled(enabled: boolean): void;
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
23
|
+
onStreamInfoUpdated(_info: FrameProcessorStreamInfo): void {}
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
25
|
+
onCredentialsUpdated(_credentials: FrameProcessorCredentials): void {}
|
|
26
|
+
|
|
27
|
+
abstract process(frame: Frame): Frame;
|
|
28
|
+
abstract close(): void;
|
|
29
|
+
}
|