@livekit/rtc-node 0.13.31 → 0.13.33

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.
Files changed (120) hide show
  1. package/dist/async_queue.d.ts +2 -3
  2. package/dist/audio_filter.d.ts +2 -3
  3. package/dist/audio_frame.d.ts +5 -6
  4. package/dist/audio_mixer.d.ts +3 -6
  5. package/dist/audio_resampler.d.ts +3 -6
  6. package/dist/audio_source.d.ts +5 -6
  7. package/dist/{audio_stream-B4hGVcKz.d.cts → audio_stream-CnODFAmo.d.cts} +26 -0
  8. package/dist/audio_stream.cjs +31 -18
  9. package/dist/audio_stream.cjs.map +1 -1
  10. package/dist/audio_stream.d.cts +1 -1
  11. package/dist/audio_stream.d.ts +61 -18
  12. package/dist/audio_stream.d.ts.map +1 -1
  13. package/dist/data_streams/index.d.ts +4 -3
  14. package/dist/data_streams/stream_reader.d.ts +48 -2
  15. package/dist/data_streams/stream_writer.d.ts +5 -7
  16. package/dist/data_streams/types.d.ts +41 -2
  17. package/dist/e2ee.d.ts +8 -10
  18. package/dist/ffi_client.d.ts +8 -10
  19. package/dist/frame_processor.d.ts +8 -11
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +2 -2
  22. package/dist/index.d.ts +22 -17
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -107
  25. package/dist/log.d.ts +5 -7
  26. package/dist/participant.cjs +7 -2
  27. package/dist/participant.cjs.map +1 -1
  28. package/dist/participant.d.cts +1 -1
  29. package/dist/participant.d.ts +152 -18
  30. package/dist/participant.d.ts.map +1 -1
  31. package/dist/room.cjs +7 -0
  32. package/dist/room.cjs.map +1 -1
  33. package/dist/room.d.cts +2 -2
  34. package/dist/room.d.ts +220 -18
  35. package/dist/room.d.ts.map +1 -1
  36. package/dist/rpc.d.ts +7 -9
  37. package/dist/track.cjs +16 -0
  38. package/dist/track.cjs.map +1 -1
  39. package/dist/track.d.cts +1 -1
  40. package/dist/track.d.ts +67 -18
  41. package/dist/track.d.ts.map +1 -1
  42. package/dist/track_publication.d.cts +1 -1
  43. package/dist/track_publication.d.ts +45 -18
  44. package/dist/transcription.d.ts +3 -4
  45. package/dist/types.d.ts +2 -3
  46. package/dist/utils.d.ts +4 -5
  47. package/dist/version.cjs +1 -1
  48. package/dist/version.cjs.map +1 -1
  49. package/dist/version.d.cts +1 -1
  50. package/dist/version.d.ts +2 -3
  51. package/dist/video_frame.d.ts +4 -5
  52. package/dist/video_source.d.ts +6 -8
  53. package/dist/video_stream.d.cts +1 -1
  54. package/dist/video_stream.d.ts +5 -22
  55. package/package.json +5 -6
  56. package/src/audio_stream.ts +37 -24
  57. package/src/audio_stream_room_lifecycle.test.ts +50 -3
  58. package/src/index.ts +8 -1
  59. package/src/participant.ts +7 -1
  60. package/src/room.ts +14 -0
  61. package/src/tests/e2e.test.ts +137 -16
  62. package/src/track.ts +17 -0
  63. package/src/version.ts +1 -1
  64. package/dist/async_queue.js +0 -56
  65. package/dist/async_queue.js.map +0 -1
  66. package/dist/audio_filter.js +0 -24
  67. package/dist/audio_filter.js.map +0 -1
  68. package/dist/audio_frame.js +0 -78
  69. package/dist/audio_frame.js.map +0 -1
  70. package/dist/audio_mixer.js +0 -269
  71. package/dist/audio_mixer.js.map +0 -1
  72. package/dist/audio_resampler.js +0 -154
  73. package/dist/audio_resampler.js.map +0 -1
  74. package/dist/audio_source.js +0 -134
  75. package/dist/audio_source.js.map +0 -1
  76. package/dist/audio_stream-DEG1JKge.d.ts +0 -498
  77. package/dist/audio_stream.js +0 -109
  78. package/dist/audio_stream.js.map +0 -1
  79. package/dist/data_streams/index.js +0 -3
  80. package/dist/data_streams/index.js.map +0 -1
  81. package/dist/data_streams/stream_reader.js +0 -124
  82. package/dist/data_streams/stream_reader.js.map +0 -1
  83. package/dist/data_streams/stream_writer.js +0 -26
  84. package/dist/data_streams/stream_writer.js.map +0 -1
  85. package/dist/data_streams/types.js +0 -1
  86. package/dist/data_streams/types.js.map +0 -1
  87. package/dist/e2ee.js +0 -251
  88. package/dist/e2ee.js.map +0 -1
  89. package/dist/ffi_client.js +0 -89
  90. package/dist/ffi_client.js.map +0 -1
  91. package/dist/frame_processor.js +0 -29
  92. package/dist/frame_processor.js.map +0 -1
  93. package/dist/index.js.map +0 -1
  94. package/dist/log.js +0 -9
  95. package/dist/log.js.map +0 -1
  96. package/dist/participant.js +0 -715
  97. package/dist/participant.js.map +0 -1
  98. package/dist/room.js +0 -899
  99. package/dist/room.js.map +0 -1
  100. package/dist/rpc.js +0 -65
  101. package/dist/rpc.js.map +0 -1
  102. package/dist/track.js +0 -218
  103. package/dist/track.js.map +0 -1
  104. package/dist/track_publication.js +0 -100
  105. package/dist/track_publication.js.map +0 -1
  106. package/dist/transcription.js +0 -1
  107. package/dist/transcription.js.map +0 -1
  108. package/dist/types-_PdPVish.d.ts +0 -87
  109. package/dist/types.js +0 -1
  110. package/dist/types.js.map +0 -1
  111. package/dist/utils.js +0 -35
  112. package/dist/utils.js.map +0 -1
  113. package/dist/version.js +0 -5
  114. package/dist/version.js.map +0 -1
  115. package/dist/video_frame.js +0 -207
  116. package/dist/video_frame.js.map +0 -1
  117. package/dist/video_source.js +0 -53
  118. package/dist/video_source.js.map +0 -1
  119. package/dist/video_stream.js +0 -70
  120. package/dist/video_stream.js.map +0 -1
@@ -9,7 +9,7 @@
9
9
  * This eliminates the need for manual coordination logic, polling loops, and
10
10
  * complex state management throughout the rest of the codebase.
11
11
  */
12
- declare class AsyncQueue<T> {
12
+ export declare class AsyncQueue<T> {
13
13
  private capacity;
14
14
  private items;
15
15
  private waitingProducers;
@@ -26,5 +26,4 @@ declare class AsyncQueue<T> {
26
26
  close(): void;
27
27
  get length(): number;
28
28
  }
29
-
30
- export { AsyncQueue };
29
+ //# sourceMappingURL=async_queue.d.ts.map
@@ -1,5 +1,4 @@
1
- declare class AudioFilter {
1
+ export declare class AudioFilter {
2
2
  constructor(moduleId: string, path: string, dependencies?: string[]);
3
3
  }
4
-
5
- export { AudioFilter };
4
+ //# sourceMappingURL=audio_filter.d.ts.map
@@ -1,6 +1,6 @@
1
- import { OwnedAudioFrameBuffer, AudioFrameBufferInfo } from '@livekit/rtc-ffi-bindings';
2
-
3
- declare class AudioFrame {
1
+ import type { OwnedAudioFrameBuffer } from '@livekit/rtc-ffi-bindings';
2
+ import { AudioFrameBufferInfo } from '@livekit/rtc-ffi-bindings';
3
+ export declare class AudioFrame {
4
4
  data: Int16Array;
5
5
  sampleRate: number;
6
6
  channels: number;
@@ -24,6 +24,5 @@ declare class AudioFrame {
24
24
  *
25
25
  * @param buffer - a single AudioFrame or list thereof
26
26
  */
27
- declare const combineAudioFrames: (buffer: AudioFrame | AudioFrame[]) => AudioFrame;
28
-
29
- export { AudioFrame, combineAudioFrames };
27
+ export declare const combineAudioFrames: (buffer: AudioFrame | AudioFrame[]) => AudioFrame;
28
+ //# sourceMappingURL=audio_frame.d.ts.map
@@ -1,13 +1,11 @@
1
1
  import { AudioFrame } from './audio_frame.js';
2
2
  export { AsyncQueue } from './async_queue.js';
3
- import '@livekit/rtc-ffi-bindings';
4
-
5
3
  type AudioStream = {
6
4
  [Symbol.asyncIterator](): {
7
5
  next(): Promise<IteratorResult<AudioFrame>>;
8
6
  };
9
7
  };
10
- interface AudioMixerOptions {
8
+ export interface AudioMixerOptions {
11
9
  /**
12
10
  * The size of the audio block (in samples) for mixing.
13
11
  * If not provided, defaults to sampleRate / 10 (100ms).
@@ -47,7 +45,7 @@ interface AudioMixerOptions {
47
45
  * }
48
46
  * ```
49
47
  */
50
- declare class AudioMixer {
48
+ export declare class AudioMixer {
51
49
  private streams;
52
50
  private buffers;
53
51
  private streamIterators;
@@ -114,5 +112,4 @@ declare class AudioMixer {
114
112
  * cleared via `.finally()` so callers don't need to manage cleanup. */
115
113
  private timeoutRace;
116
114
  }
117
-
118
- export { AudioMixer, type AudioMixerOptions };
115
+ //# sourceMappingURL=audio_mixer.d.ts.map
@@ -1,11 +1,9 @@
1
1
  import { AudioFrame } from './audio_frame.js';
2
- import '@livekit/rtc-ffi-bindings';
3
-
4
2
  /**
5
3
  * Resampler quality. Higher quality settings result in better audio quality but require more
6
4
  * processing power.
7
5
  */
8
- declare enum AudioResamplerQuality {
6
+ export declare enum AudioResamplerQuality {
9
7
  QUICK = 0,
10
8
  LOW = 1,
11
9
  MEDIUM = 2,
@@ -17,7 +15,7 @@ declare enum AudioResamplerQuality {
17
15
  * an output sample rate using the Sox resampling library. It supports multiple channels and
18
16
  * configurable resampling quality.
19
17
  */
20
- declare class AudioResampler {
18
+ export declare class AudioResampler {
21
19
  #private;
22
20
  /**
23
21
  * Initializes a new AudioResampler.
@@ -58,5 +56,4 @@ declare class AudioResampler {
58
56
  */
59
57
  flush(): AudioFrame[];
60
58
  }
61
-
62
- export { AudioResampler, AudioResamplerQuality };
59
+ //# sourceMappingURL=audio_resampler.d.ts.map
@@ -1,7 +1,7 @@
1
- import { AudioSourceInfo, FfiHandle } from '@livekit/rtc-ffi-bindings';
2
- import { AudioFrame } from './audio_frame.js';
3
-
4
- declare class AudioSource {
1
+ import type { AudioSourceInfo } from '@livekit/rtc-ffi-bindings';
2
+ import { FfiHandle } from '@livekit/rtc-ffi-bindings';
3
+ import type { AudioFrame } from './audio_frame.js';
4
+ export declare class AudioSource {
5
5
  /** @internal */
6
6
  info: AudioSourceInfo;
7
7
  /** @internal */
@@ -37,5 +37,4 @@ declare class AudioSource {
37
37
  captureFrame(frame: AudioFrame): Promise<void>;
38
38
  close(): Promise<void>;
39
39
  }
40
-
41
- export { AudioSource };
40
+ //# sourceMappingURL=audio_source.d.ts.map
@@ -108,6 +108,7 @@ declare class LocalParticipant extends Participant {
108
108
  destinationIdentities?: Array<string>;
109
109
  streamId?: string;
110
110
  senderIdentity?: string;
111
+ totalSize?: number;
111
112
  }): Promise<TextStreamWriter>;
112
113
  sendText(text: string, options?: {
113
114
  topic?: string;
@@ -420,6 +421,17 @@ declare abstract class Track {
420
421
  registerAudioStream(stream: AudioStreamSource): void;
421
422
  /** @internal */
422
423
  unregisterAudioStream(stream: AudioStreamSource): void;
424
+ /**
425
+ * End every {@link AudioStream} attached to this track.
426
+ *
427
+ * @remarks
428
+ * The FFI keeps feeding an audio stream until the stream's own handle is
429
+ * dropped, so streams on a track that is no longer subscribed would otherwise
430
+ * go on delivering audio for the lifetime of the process.
431
+ *
432
+ * @internal
433
+ */
434
+ closeAudioStreams(): void;
423
435
  private iterateStreams;
424
436
  private pushProcessorMetadataToStream;
425
437
  get sid(): string | undefined;
@@ -486,6 +498,20 @@ declare class AudioStreamSource implements UnderlyingSource<AudioFrame> {
486
498
  get processor(): FrameProcessor<AudioFrame> | null;
487
499
  private onEvent;
488
500
  start(controller: ReadableStreamDefaultController<AudioFrame>): void;
501
+ /**
502
+ * Detach from the FFI and release resources: on `eos`, on `cancel()`, or
503
+ * because the track went away (e.g. it was unsubscribed — which never
504
+ * produces an `eos`, so without this the stream would keep delivering
505
+ * frames). Already-buffered frames stay readable and the consumer sees `done`
506
+ * after draining them.
507
+ *
508
+ * @remarks
509
+ * Idempotent, so `eos` arriving after a `cancel()` (or vice versa) doesn't
510
+ * double-dispose the handle while buffered frames are still queued.
511
+ *
512
+ * @internal
513
+ */
514
+ teardown(): void;
489
515
  cancel(): void;
490
516
  }
491
517
  declare class AudioStream extends ReadableStream<AudioFrame> {
@@ -53,16 +53,7 @@ class AudioStreamSource {
53
53
  this.controller.enqueue(frame);
54
54
  break;
55
55
  case "eos":
56
- import_ffi_client.FfiClient.instance.off(import_ffi_client.FfiClientEvent.FfiEvent, this.onEvent);
57
- this.controller.close();
58
- if (!this.disposed) {
59
- this.disposed = true;
60
- this.track.unregisterAudioStream(this);
61
- this.ffiHandle.dispose();
62
- if (this.frameProcessor && this.autoCloseProcessor) {
63
- this.frameProcessor.close();
64
- }
65
- }
56
+ this.teardown();
66
57
  break;
67
58
  }
68
59
  };
@@ -109,16 +100,38 @@ class AudioStreamSource {
109
100
  start(controller) {
110
101
  this.controller = controller;
111
102
  }
112
- cancel() {
103
+ /**
104
+ * Detach from the FFI and release resources: on `eos`, on `cancel()`, or
105
+ * because the track went away (e.g. it was unsubscribed — which never
106
+ * produces an `eos`, so without this the stream would keep delivering
107
+ * frames). Already-buffered frames stay readable and the consumer sees `done`
108
+ * after draining them.
109
+ *
110
+ * @remarks
111
+ * Idempotent, so `eos` arriving after a `cancel()` (or vice versa) doesn't
112
+ * double-dispose the handle while buffered frames are still queued.
113
+ *
114
+ * @internal
115
+ */
116
+ teardown() {
117
+ var _a;
113
118
  import_ffi_client.FfiClient.instance.off(import_ffi_client.FfiClientEvent.FfiEvent, this.onEvent);
114
- if (!this.disposed) {
115
- this.disposed = true;
116
- this.track.unregisterAudioStream(this);
117
- this.ffiHandle.dispose();
118
- if (this.frameProcessor && this.autoCloseProcessor) {
119
- this.frameProcessor.close();
120
- }
119
+ if (this.disposed) {
120
+ return;
121
121
  }
122
+ this.disposed = true;
123
+ this.track.unregisterAudioStream(this);
124
+ this.ffiHandle.dispose();
125
+ if (this.frameProcessor && this.autoCloseProcessor) {
126
+ this.frameProcessor.close();
127
+ }
128
+ try {
129
+ (_a = this.controller) == null ? void 0 : _a.close();
130
+ } catch {
131
+ }
132
+ }
133
+ cancel() {
134
+ this.teardown();
122
135
  }
123
136
  }
124
137
  class AudioStream extends ReadableStream {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/audio_stream.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { NewAudioStreamResponse } from '@livekit/rtc-ffi-bindings';\nimport { AudioStreamType, NewAudioStreamRequest } from '@livekit/rtc-ffi-bindings';\nimport type { UnderlyingSource } from 'node:stream/web';\nimport { AudioFrame } from './audio_frame.js';\nimport type { FfiEvent } from './ffi_client.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport { type FrameProcessor, isFrameProcessor } from './frame_processor.js';\nimport { log } from './log.js';\nimport type { Track } from './track.js';\n\nexport interface AudioStreamOptions {\n noiseCancellation?: NoiseCancellationOptions | FrameProcessor<AudioFrame>;\n /**\n * When the audio stream closes, whether to run the {@link FrameProcessor}'s\n * `close()` method. If `false`, the processor is left open so it can be\n * reused with another {@link AudioStream}. Only relevant when\n * `noiseCancellation` is a {@link FrameProcessor}. Defaults to `true`.\n */\n autoCloseNoiseCancellation?: boolean;\n sampleRate?: number;\n numChannels?: number;\n frameSizeMs?: number;\n}\n\nexport interface NoiseCancellationOptions {\n moduleId: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: Record<string, any>;\n}\n\n/** @internal */\nexport class AudioStreamSource implements UnderlyingSource<AudioFrame> {\n private controller?: ReadableStreamDefaultController<AudioFrame>;\n private ffiHandle: FfiHandle;\n private disposed = false;\n private sampleRate: number;\n private numChannels: number;\n private legacyNcOptions?: NoiseCancellationOptions;\n private frameProcessor: FrameProcessor<AudioFrame> | null = null;\n private autoCloseProcessor = true;\n private frameSizeMs?: number;\n private track: Track;\n\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n this.track = track;\n if (sampleRateOrOptions !== undefined && typeof sampleRateOrOptions !== 'number') {\n this.sampleRate = sampleRateOrOptions.sampleRate ?? 48000;\n this.numChannels = sampleRateOrOptions.numChannels ?? 1;\n if (isFrameProcessor(sampleRateOrOptions.noiseCancellation)) {\n this.frameProcessor = sampleRateOrOptions.noiseCancellation;\n this.autoCloseProcessor = sampleRateOrOptions.autoCloseNoiseCancellation ?? true;\n } else {\n this.legacyNcOptions = sampleRateOrOptions.noiseCancellation;\n }\n this.frameSizeMs = sampleRateOrOptions.frameSizeMs;\n } else {\n this.sampleRate = (sampleRateOrOptions as number) ?? 48000;\n this.numChannels = numChannels ?? 1;\n }\n\n const req = new NewAudioStreamRequest({\n type: AudioStreamType.AUDIO_STREAM_NATIVE,\n trackHandle: track.ffi_handle.handle,\n sampleRate: this.sampleRate,\n numChannels: this.numChannels,\n frameSizeMs: this.frameSizeMs,\n ...(this.legacyNcOptions\n ? {\n audioFilterModuleId: this.legacyNcOptions.moduleId,\n audioFilterOptions: JSON.stringify(this.legacyNcOptions.options),\n }\n : {}),\n });\n\n const res = FfiClient.instance.request<NewAudioStreamResponse>({\n message: {\n case: 'newAudioStream',\n value: req,\n },\n });\n\n this.ffiHandle = new FfiHandle(res.stream!.handle!.id!);\n\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);\n track.registerAudioStream(this);\n }\n\n /** @internal */\n get processor(): FrameProcessor<AudioFrame> | null {\n return this.frameProcessor;\n }\n\n private onEvent = (ev: FfiEvent) => {\n if (!this.controller) {\n throw new Error('Stream controller not initialized');\n }\n\n if (\n ev.message.case != 'audioStreamEvent' ||\n ev.message.value.streamHandle != this.ffiHandle.handle\n ) {\n return;\n }\n\n const streamEvent = ev.message.value.message;\n switch (streamEvent.case) {\n case 'frameReceived':\n let frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame!);\n if (this.frameProcessor && this.frameProcessor.isEnabled()) {\n try {\n frame = this.frameProcessor.process(frame);\n } catch (err: unknown) {\n log.warn(`Frame processing failed, passing through original frame: ${err}`);\n }\n }\n this.controller.enqueue(frame);\n break;\n case 'eos':\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n this.controller.close();\n // Dispose the native handle so the FD is released on stream end,\n // not just when cancel() is called explicitly by the consumer.\n // Guard against double-dispose if cancel() is called after EOS\n // while buffered frames are still in the ReadableStream queue.\n if (!this.disposed) {\n this.disposed = true;\n this.track.unregisterAudioStream(this);\n this.ffiHandle.dispose();\n if (this.frameProcessor && this.autoCloseProcessor) {\n this.frameProcessor.close();\n }\n }\n break;\n }\n };\n\n start(controller: ReadableStreamDefaultController<AudioFrame>) {\n this.controller = controller;\n }\n\n cancel() {\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n if (!this.disposed) {\n this.disposed = true;\n this.track.unregisterAudioStream(this);\n this.ffiHandle.dispose();\n // Also close the frame processor on cancel for symmetry with the EOS path,\n // so resources are released regardless of how the stream ends.\n if (this.frameProcessor && this.autoCloseProcessor) {\n this.frameProcessor.close();\n }\n }\n }\n}\n\nexport class AudioStream extends ReadableStream<AudioFrame> {\n constructor(track: Track);\n constructor(track: Track, sampleRate: number);\n constructor(track: Track, sampleRate: number, numChannels: number);\n constructor(track: Track, options: AudioStreamOptions);\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n super(new AudioStreamSource(track, sampleRateOrOptions, numChannels));\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/audio_stream.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { NewAudioStreamResponse } from '@livekit/rtc-ffi-bindings';\nimport { AudioStreamType, NewAudioStreamRequest } from '@livekit/rtc-ffi-bindings';\nimport type { UnderlyingSource } from 'node:stream/web';\nimport { AudioFrame } from './audio_frame.js';\nimport type { FfiEvent } from './ffi_client.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport { type FrameProcessor, isFrameProcessor } from './frame_processor.js';\nimport { log } from './log.js';\nimport type { Track } from './track.js';\n\nexport interface AudioStreamOptions {\n noiseCancellation?: NoiseCancellationOptions | FrameProcessor<AudioFrame>;\n /**\n * When the audio stream closes, whether to run the {@link FrameProcessor}'s\n * `close()` method. If `false`, the processor is left open so it can be\n * reused with another {@link AudioStream}. Only relevant when\n * `noiseCancellation` is a {@link FrameProcessor}. Defaults to `true`.\n */\n autoCloseNoiseCancellation?: boolean;\n sampleRate?: number;\n numChannels?: number;\n frameSizeMs?: number;\n}\n\nexport interface NoiseCancellationOptions {\n moduleId: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: Record<string, any>;\n}\n\n/** @internal */\nexport class AudioStreamSource implements UnderlyingSource<AudioFrame> {\n private controller?: ReadableStreamDefaultController<AudioFrame>;\n private ffiHandle: FfiHandle;\n private disposed = false;\n private sampleRate: number;\n private numChannels: number;\n private legacyNcOptions?: NoiseCancellationOptions;\n private frameProcessor: FrameProcessor<AudioFrame> | null = null;\n private autoCloseProcessor = true;\n private frameSizeMs?: number;\n private track: Track;\n\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n this.track = track;\n if (sampleRateOrOptions !== undefined && typeof sampleRateOrOptions !== 'number') {\n this.sampleRate = sampleRateOrOptions.sampleRate ?? 48000;\n this.numChannels = sampleRateOrOptions.numChannels ?? 1;\n if (isFrameProcessor(sampleRateOrOptions.noiseCancellation)) {\n this.frameProcessor = sampleRateOrOptions.noiseCancellation;\n this.autoCloseProcessor = sampleRateOrOptions.autoCloseNoiseCancellation ?? true;\n } else {\n this.legacyNcOptions = sampleRateOrOptions.noiseCancellation;\n }\n this.frameSizeMs = sampleRateOrOptions.frameSizeMs;\n } else {\n this.sampleRate = (sampleRateOrOptions as number) ?? 48000;\n this.numChannels = numChannels ?? 1;\n }\n\n const req = new NewAudioStreamRequest({\n type: AudioStreamType.AUDIO_STREAM_NATIVE,\n trackHandle: track.ffi_handle.handle,\n sampleRate: this.sampleRate,\n numChannels: this.numChannels,\n frameSizeMs: this.frameSizeMs,\n ...(this.legacyNcOptions\n ? {\n audioFilterModuleId: this.legacyNcOptions.moduleId,\n audioFilterOptions: JSON.stringify(this.legacyNcOptions.options),\n }\n : {}),\n });\n\n const res = FfiClient.instance.request<NewAudioStreamResponse>({\n message: {\n case: 'newAudioStream',\n value: req,\n },\n });\n\n this.ffiHandle = new FfiHandle(res.stream!.handle!.id!);\n\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);\n track.registerAudioStream(this);\n }\n\n /** @internal */\n get processor(): FrameProcessor<AudioFrame> | null {\n return this.frameProcessor;\n }\n\n private onEvent = (ev: FfiEvent) => {\n if (!this.controller) {\n throw new Error('Stream controller not initialized');\n }\n\n if (\n ev.message.case != 'audioStreamEvent' ||\n ev.message.value.streamHandle != this.ffiHandle.handle\n ) {\n return;\n }\n\n const streamEvent = ev.message.value.message;\n switch (streamEvent.case) {\n case 'frameReceived':\n let frame = AudioFrame.fromOwnedInfo(streamEvent.value.frame!);\n if (this.frameProcessor && this.frameProcessor.isEnabled()) {\n try {\n frame = this.frameProcessor.process(frame);\n } catch (err: unknown) {\n log.warn(`Frame processing failed, passing through original frame: ${err}`);\n }\n }\n this.controller.enqueue(frame);\n break;\n case 'eos':\n // Disposes the native handle so the FD is released on stream end, not\n // just when cancel() is called explicitly by the consumer.\n this.teardown();\n break;\n }\n };\n\n start(controller: ReadableStreamDefaultController<AudioFrame>) {\n this.controller = controller;\n }\n\n /**\n * Detach from the FFI and release resources: on `eos`, on `cancel()`, or\n * because the track went away (e.g. it was unsubscribed — which never\n * produces an `eos`, so without this the stream would keep delivering\n * frames). Already-buffered frames stay readable and the consumer sees `done`\n * after draining them.\n *\n * @remarks\n * Idempotent, so `eos` arriving after a `cancel()` (or vice versa) doesn't\n * double-dispose the handle while buffered frames are still queued.\n *\n * @internal\n */\n teardown() {\n FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.track.unregisterAudioStream(this);\n this.ffiHandle.dispose();\n // Close the frame processor on every teardown path so resources are\n // released regardless of how the stream ended.\n if (this.frameProcessor && this.autoCloseProcessor) {\n this.frameProcessor.close();\n }\n try {\n this.controller?.close();\n } catch {\n // Already closed — e.g. cancel(), where the consumer has torn the\n // ReadableStream down before the underlying source is notified.\n }\n }\n\n cancel() {\n this.teardown();\n }\n}\n\nexport class AudioStream extends ReadableStream<AudioFrame> {\n constructor(track: Track);\n constructor(track: Track, sampleRate: number);\n constructor(track: Track, sampleRate: number, numChannels: number);\n constructor(track: Track, options: AudioStreamOptions);\n constructor(\n track: Track,\n sampleRateOrOptions?: number | AudioStreamOptions,\n numChannels?: number,\n ) {\n super(new AudioStreamSource(track, sampleRateOrOptions, numChannels));\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import 'node:stream/web';
2
2
  import './audio_frame.cjs';
3
3
  import './frame_processor.cjs';
4
- export { A as AudioStream, r as AudioStreamOptions, s as AudioStreamSource, N as NoiseCancellationOptions } from './audio_stream-B4hGVcKz.cjs';
4
+ export { A as AudioStream, r as AudioStreamOptions, s as AudioStreamSource, N as NoiseCancellationOptions } from './audio_stream-CnODFAmo.cjs';
5
5
  import '@livekit/rtc-ffi-bindings';
6
6
  import './video_frame.cjs';
7
7
  import './audio_source.cjs';
@@ -1,18 +1,61 @@
1
- import 'node:stream/web';
2
- import './audio_frame.js';
3
- import './frame_processor.js';
4
- export { A as AudioStream, r as AudioStreamOptions, s as AudioStreamSource, N as NoiseCancellationOptions } from './audio_stream-DEG1JKge.js';
5
- import '@livekit/rtc-ffi-bindings';
6
- import './video_frame.js';
7
- import './audio_source.js';
8
- import './ffi_client.js';
9
- import '@livekit/typed-emitter';
10
- import './types-_PdPVish.js';
11
- import './e2ee.js';
12
- import '@livekit/mutex';
13
- import 'node:fs';
14
- import './data_streams/stream_writer.js';
15
- import './rpc.js';
16
- import './transcription.js';
17
- import './types.js';
18
- import './video_source.js';
1
+ import type { UnderlyingSource } from 'node:stream/web';
2
+ import { AudioFrame } from './audio_frame.js';
3
+ import { type FrameProcessor } from './frame_processor.js';
4
+ import type { Track } from './track.js';
5
+ export interface AudioStreamOptions {
6
+ noiseCancellation?: NoiseCancellationOptions | FrameProcessor<AudioFrame>;
7
+ /**
8
+ * When the audio stream closes, whether to run the {@link FrameProcessor}'s
9
+ * `close()` method. If `false`, the processor is left open so it can be
10
+ * reused with another {@link AudioStream}. Only relevant when
11
+ * `noiseCancellation` is a {@link FrameProcessor}. Defaults to `true`.
12
+ */
13
+ autoCloseNoiseCancellation?: boolean;
14
+ sampleRate?: number;
15
+ numChannels?: number;
16
+ frameSizeMs?: number;
17
+ }
18
+ export interface NoiseCancellationOptions {
19
+ moduleId: string;
20
+ options: Record<string, any>;
21
+ }
22
+ /** @internal */
23
+ export declare class AudioStreamSource implements UnderlyingSource<AudioFrame> {
24
+ private controller?;
25
+ private ffiHandle;
26
+ private disposed;
27
+ private sampleRate;
28
+ private numChannels;
29
+ private legacyNcOptions?;
30
+ private frameProcessor;
31
+ private autoCloseProcessor;
32
+ private frameSizeMs?;
33
+ private track;
34
+ constructor(track: Track, sampleRateOrOptions?: number | AudioStreamOptions, numChannels?: number);
35
+ /** @internal */
36
+ get processor(): FrameProcessor<AudioFrame> | null;
37
+ private onEvent;
38
+ start(controller: ReadableStreamDefaultController<AudioFrame>): void;
39
+ /**
40
+ * Detach from the FFI and release resources: on `eos`, on `cancel()`, or
41
+ * because the track went away (e.g. it was unsubscribed — which never
42
+ * produces an `eos`, so without this the stream would keep delivering
43
+ * frames). Already-buffered frames stay readable and the consumer sees `done`
44
+ * after draining them.
45
+ *
46
+ * @remarks
47
+ * Idempotent, so `eos` arriving after a `cancel()` (or vice versa) doesn't
48
+ * double-dispose the handle while buffered frames are still queued.
49
+ *
50
+ * @internal
51
+ */
52
+ teardown(): void;
53
+ cancel(): void;
54
+ }
55
+ export declare class AudioStream extends ReadableStream<AudioFrame> {
56
+ constructor(track: Track);
57
+ constructor(track: Track, sampleRate: number);
58
+ constructor(track: Track, sampleRate: number, numChannels: number);
59
+ constructor(track: Track, options: AudioStreamOptions);
60
+ }
61
+ //# sourceMappingURL=audio_stream.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audio_stream.d.ts","sourceRoot":"","sources":["../src/audio_stream.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,CAAC,EAAE,wBAAwB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC1E;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,gBAAgB;AAChB,qBAAa,iBAAkB,YAAW,gBAAgB,CAAC,UAAU,CAAC;IACpE,OAAO,CAAC,UAAU,CAAC,CAA8C;IACjE,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAC,CAA2B;IACnD,OAAO,CAAC,cAAc,CAA2C;IACjE,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAQ;gBAGnB,KAAK,EAAE,KAAK,EACZ,mBAAmB,CAAC,EAAE,MAAM,GAAG,kBAAkB,EACjD,WAAW,CAAC,EAAE,MAAM;IA6CtB,gBAAgB;IAChB,IAAI,SAAS,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAEjD;IAED,OAAO,CAAC,OAAO,CA0Cb;IAEF,KAAK,CAAC,UAAU,EAAE,+BAA+B,CAAC,UAAU,CAAC;IAI7D,MAAM;CAaP;AAED,qBAAa,WAAY,SAAQ,cAAc,CAAC,UAAU,CAAC;gBAC7C,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM;gBAChC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;gBACrD,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB;CAQtD"}
1
+ {"version":3,"file":"audio_stream.d.ts","sourceRoot":"","sources":["../src/audio_stream.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAE7E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,CAAC,EAAE,wBAAwB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC1E;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,gBAAgB;AAChB,qBAAa,iBAAkB,YAAW,gBAAgB,CAAC,UAAU,CAAC;IACpE,OAAO,CAAC,UAAU,CAAC,CAA8C;IACjE,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAC,CAA2B;IACnD,OAAO,CAAC,cAAc,CAA2C;IACjE,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAQ;gBAGnB,KAAK,EAAE,KAAK,EACZ,mBAAmB,CAAC,EAAE,MAAM,GAAG,kBAAkB,EACjD,WAAW,CAAC,EAAE,MAAM;IA6CtB,gBAAgB;IAChB,IAAI,SAAS,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAEjD;IAED,OAAO,CAAC,OAAO,CA+Bb;IAEF,KAAK,CAAC,UAAU,EAAE,+BAA+B,CAAC,UAAU,CAAC;IAI7D;;;;;;;;;;;;OAYG;IACH,QAAQ;IAqBR,MAAM;CAGP;AAED,qBAAa,WAAY,SAAQ,cAAc,CAAC,UAAU,CAAC;gBAC7C,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM;gBAChC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;gBACrD,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB;CAQtD"}
@@ -1,3 +1,4 @@
1
- export { B as BaseStreamInfo, a as ByteStreamHandler, b as ByteStreamInfo, c as ByteStreamOptions, d as ByteStreamReader, D as DataStreamOptions, S as StreamController, T as TextStreamHandler, e as TextStreamInfo, f as TextStreamOptions, g as TextStreamReader } from '../types-_PdPVish.js';
2
- export { ByteStreamWriter, TextStreamWriter } from './stream_writer.js';
3
- import '@livekit/rtc-ffi-bindings';
1
+ export * from './stream_reader.js';
2
+ export * from './stream_writer.js';
3
+ export type * from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,48 @@
1
- import '@livekit/rtc-ffi-bindings';
2
- export { d as ByteStreamReader, g as TextStreamReader } from '../types-_PdPVish.js';
1
+ import type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';
2
+ import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';
3
+ declare abstract class BaseStreamReader<T extends BaseStreamInfo> {
4
+ protected reader: ReadableStream<DataStream_Chunk>;
5
+ protected totalByteSize?: number;
6
+ protected _info: T;
7
+ protected bytesReceived: number;
8
+ get info(): T;
9
+ constructor(info: T, stream: ReadableStream<DataStream_Chunk>, totalByteSize?: number);
10
+ protected abstract handleChunkReceived(chunk: DataStream_Chunk): void;
11
+ onProgress?: (progress: number | undefined) => void;
12
+ abstract readAll(): Promise<string | Array<Uint8Array>>;
13
+ }
14
+ /**
15
+ * A class to read chunks from a ReadableStream and provide them in a structured format.
16
+ */
17
+ export declare class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
18
+ protected handleChunkReceived(chunk: DataStream_Chunk): void;
19
+ [Symbol.asyncIterator](): {
20
+ next: () => Promise<IteratorResult<Uint8Array>>;
21
+ return(): IteratorResult<Uint8Array>;
22
+ };
23
+ readAll(): Promise<Array<Uint8Array>>;
24
+ }
25
+ /**
26
+ * A class to read chunks from a ReadableStream and provide them in a structured format.
27
+ */
28
+ export declare class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
29
+ private receivedChunks;
30
+ /**
31
+ * A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
32
+ * that has been received up to the current point in time.
33
+ */
34
+ constructor(info: TextStreamInfo, stream: ReadableStream<DataStream_Chunk>, totalChunkCount?: number);
35
+ protected handleChunkReceived(chunk: DataStream_Chunk): void;
36
+ /**
37
+ * Async iterator implementation to allow usage of `for await...of` syntax.
38
+ * Yields structured chunks from the stream.
39
+ *
40
+ */
41
+ [Symbol.asyncIterator](): {
42
+ next: () => Promise<IteratorResult<string>>;
43
+ return(): IteratorResult<string>;
44
+ };
45
+ readAll(): Promise<string>;
46
+ }
47
+ export {};
48
+ //# sourceMappingURL=stream_reader.d.ts.map
@@ -1,6 +1,4 @@
1
- import { B as BaseStreamInfo, e as TextStreamInfo, b as ByteStreamInfo } from '../types-_PdPVish.js';
2
- import '@livekit/rtc-ffi-bindings';
3
-
1
+ import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';
4
2
  declare class BaseStreamWriter<T, InfoType extends BaseStreamInfo> {
5
3
  protected writableStream: WritableStream<T>;
6
4
  protected defaultWriter: WritableStreamDefaultWriter<T>;
@@ -10,9 +8,9 @@ declare class BaseStreamWriter<T, InfoType extends BaseStreamInfo> {
10
8
  write(chunk: T): Promise<void>;
11
9
  close(): Promise<void>;
12
10
  }
13
- declare class TextStreamWriter extends BaseStreamWriter<string, TextStreamInfo> {
11
+ export declare class TextStreamWriter extends BaseStreamWriter<string, TextStreamInfo> {
14
12
  }
15
- declare class ByteStreamWriter extends BaseStreamWriter<Uint8Array, ByteStreamInfo> {
13
+ export declare class ByteStreamWriter extends BaseStreamWriter<Uint8Array, ByteStreamInfo> {
16
14
  }
17
-
18
- export { ByteStreamWriter, TextStreamWriter };
15
+ export {};
16
+ //# sourceMappingURL=stream_writer.d.ts.map
@@ -1,2 +1,41 @@
1
- import '@livekit/rtc-ffi-bindings';
2
- export { B as BaseStreamInfo, a as ByteStreamHandler, b as ByteStreamInfo, c as ByteStreamOptions, D as DataStreamOptions, S as StreamController, T as TextStreamHandler, e as TextStreamInfo, f as TextStreamOptions } from '../types-_PdPVish.js';
1
+ import type { DataStream_Chunk, DataStream_Header } from '@livekit/rtc-ffi-bindings';
2
+ import type { ByteStreamReader, TextStreamReader } from './stream_reader.js';
3
+ export interface StreamController<T extends DataStream_Chunk> {
4
+ header: DataStream_Header;
5
+ controller: ReadableStreamDefaultController<T>;
6
+ startTime: number;
7
+ endTime?: number;
8
+ }
9
+ export interface BaseStreamInfo {
10
+ streamId: string;
11
+ mimeType: string;
12
+ topic: string;
13
+ timestamp: number;
14
+ /** total size in bytes for finite streams and undefined for streams of unknown size */
15
+ totalSize?: number;
16
+ attributes?: Record<string, string>;
17
+ }
18
+ export type ByteStreamInfo = BaseStreamInfo & {
19
+ name: string;
20
+ };
21
+ export type TextStreamInfo = BaseStreamInfo;
22
+ export interface DataStreamOptions {
23
+ topic?: string;
24
+ destinationIdentities?: Array<string>;
25
+ attributes?: Record<string, string>;
26
+ mimeType?: string;
27
+ }
28
+ export interface TextStreamOptions extends DataStreamOptions {
29
+ attachments?: [];
30
+ }
31
+ export interface ByteStreamOptions extends DataStreamOptions {
32
+ name?: string;
33
+ onProgress?: (progress: number) => void;
34
+ }
35
+ export type ByteStreamHandler = (reader: ByteStreamReader, participantInfo: {
36
+ identity: string;
37
+ }) => void;
38
+ export type TextStreamHandler = (reader: TextStreamReader, participantInfo: {
39
+ identity: string;
40
+ }) => void;
41
+ //# sourceMappingURL=types.d.ts.map
package/dist/e2ee.d.ts CHANGED
@@ -1,18 +1,17 @@
1
1
  import { EncryptionType } from '@livekit/rtc-ffi-bindings';
2
-
3
- interface KeyProviderOptions {
2
+ export interface KeyProviderOptions {
4
3
  sharedKey?: Uint8Array;
5
4
  ratchetSalt?: Uint8Array;
6
5
  ratchetWindowSize?: number;
7
6
  failureTolerance?: number;
8
7
  }
9
- declare const defaultKeyProviderOptions: KeyProviderOptions;
10
- interface E2EEOptions {
8
+ export declare const defaultKeyProviderOptions: KeyProviderOptions;
9
+ export interface E2EEOptions {
11
10
  keyProviderOptions: KeyProviderOptions;
12
11
  encryptionType?: EncryptionType;
13
12
  }
14
- declare const defaultE2EEOptions: E2EEOptions;
15
- declare class KeyProvider {
13
+ export declare const defaultE2EEOptions: E2EEOptions;
14
+ export declare class KeyProvider {
16
15
  private roomHandle;
17
16
  options: KeyProviderOptions;
18
17
  /** internal */
@@ -24,7 +23,7 @@ declare class KeyProvider {
24
23
  exportKey(participantIdentity: string, keyIndex: number): Uint8Array;
25
24
  ratchetKey(participantIdentity: string, keyIndex: number): Uint8Array;
26
25
  }
27
- declare class FrameCryptor {
26
+ export declare class FrameCryptor {
28
27
  private roomHandle;
29
28
  participantIdentity: string;
30
29
  keyIndex: number;
@@ -33,7 +32,7 @@ declare class FrameCryptor {
33
32
  setEnabled(enabled: boolean): void;
34
33
  setKeyIndex(keyIndex: number): void;
35
34
  }
36
- declare class E2EEManager {
35
+ export declare class E2EEManager {
37
36
  private roomHandle;
38
37
  private options;
39
38
  private keyProvider;
@@ -42,5 +41,4 @@ declare class E2EEManager {
42
41
  setEnabled(enabled: boolean): void;
43
42
  frameCryptors(): FrameCryptor[];
44
43
  }
45
-
46
- export { E2EEManager, type E2EEOptions, FrameCryptor, KeyProvider, type KeyProviderOptions, defaultE2EEOptions, defaultKeyProviderOptions };
44
+ //# sourceMappingURL=e2ee.d.ts.map
@@ -1,18 +1,17 @@
1
- import { FfiEvent, PartialMessage, FfiRequest } from '@livekit/rtc-ffi-bindings';
2
- export { FfiEvent, FfiHandle, FfiRequest, FfiResponse, livekitDispose as dispose } from '@livekit/rtc-ffi-bindings';
3
- import { TypedEventEmitter } from '@livekit/typed-emitter';
4
-
5
- type FfiClientCallbacks = {
1
+ import { FfiEvent, FfiHandle, FfiRequest, FfiResponse, type PartialMessage, livekitDispose } from '@livekit/rtc-ffi-bindings';
2
+ import type { TypedEventEmitter as TypedEmitter } from '@livekit/typed-emitter';
3
+ export { FfiHandle, type FfiEvent, type FfiResponse, FfiRequest, livekitDispose as dispose };
4
+ export type FfiClientCallbacks = {
6
5
  ffi_event: (event: FfiEvent) => void;
7
6
  };
8
- declare enum FfiClientEvent {
7
+ export declare enum FfiClientEvent {
9
8
  FfiEvent = "ffi_event"
10
9
  }
11
10
  declare global {
12
11
  var _ffiClientInstance: FfiClient | undefined;
13
12
  }
14
- declare const FfiClient_base: new () => TypedEventEmitter<FfiClientCallbacks>;
15
- declare class FfiClient extends FfiClient_base {
13
+ declare const FfiClient_base: new () => TypedEmitter<FfiClientCallbacks>;
14
+ export declare class FfiClient extends FfiClient_base {
16
15
  /** @internal */
17
16
  static get instance(): FfiClient;
18
17
  private _nextRequestAsyncId;
@@ -25,5 +24,4 @@ declare class FfiClient extends FfiClient_base {
25
24
  signal?: AbortSignal;
26
25
  }): Promise<T>;
27
26
  }
28
-
29
- export { FfiClient, type FfiClientCallbacks, FfiClientEvent };
27
+ //# sourceMappingURL=ffi_client.d.ts.map
@@ -1,19 +1,17 @@
1
- import { AudioFrame } from './audio_frame.js';
2
- import { VideoFrame } from './video_frame.js';
3
- import '@livekit/rtc-ffi-bindings';
4
-
5
- type FrameProcessorStreamInfo = {
1
+ import { type AudioFrame } from './audio_frame.js';
2
+ import { type VideoFrame } from './video_frame.js';
3
+ export type FrameProcessorStreamInfo = {
6
4
  roomName: string;
7
5
  participantIdentity: string;
8
6
  publicationSid: string;
9
7
  };
10
- type FrameProcessorCredentials = {
8
+ export type FrameProcessorCredentials = {
11
9
  token: string;
12
10
  url: string;
13
11
  };
14
- declare const FrameProcessorSymbol: unique symbol;
15
- declare function isFrameProcessor<T extends FrameProcessor<AudioFrame> | FrameProcessor<VideoFrame> | unknown>(maybeProcessor: unknown): maybeProcessor is T extends FrameProcessor<AudioFrame> ? FrameProcessor<AudioFrame> : T extends FrameProcessor<VideoFrame> ? FrameProcessor<VideoFrame> : FrameProcessor<AudioFrame> | FrameProcessor<VideoFrame>;
16
- declare abstract class FrameProcessor<Frame extends VideoFrame | AudioFrame> {
12
+ export declare const FrameProcessorSymbol: unique symbol;
13
+ export declare function isFrameProcessor<T extends FrameProcessor<AudioFrame> | FrameProcessor<VideoFrame> | unknown>(maybeProcessor: unknown): maybeProcessor is T extends FrameProcessor<AudioFrame> ? FrameProcessor<AudioFrame> : T extends FrameProcessor<VideoFrame> ? FrameProcessor<VideoFrame> : FrameProcessor<AudioFrame> | FrameProcessor<VideoFrame>;
14
+ export declare abstract class FrameProcessor<Frame extends VideoFrame | AudioFrame> {
17
15
  readonly symbol: symbol;
18
16
  abstract isEnabled(): boolean;
19
17
  abstract setEnabled(enabled: boolean): void;
@@ -24,5 +22,4 @@ declare abstract class FrameProcessor<Frame extends VideoFrame | AudioFrame> {
24
22
  abstract process(frame: Frame): Frame;
25
23
  abstract close(): void;
26
24
  }
27
-
28
- export { FrameProcessor, type FrameProcessorCredentials, type FrameProcessorStreamInfo, FrameProcessorSymbol, isFrameProcessor };
25
+ //# sourceMappingURL=frame_processor.d.ts.map