@livekit/rtc-node 0.13.32 → 0.13.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/async_queue.d.ts +2 -3
- package/dist/audio_filter.d.ts +2 -3
- package/dist/audio_frame.d.ts +5 -6
- package/dist/audio_mixer.d.ts +3 -6
- package/dist/audio_resampler.d.ts +3 -6
- package/dist/audio_source.d.ts +5 -6
- package/dist/{audio_stream-4M8XlO4-.d.cts → audio_stream-BNVaONuH.d.cts} +36 -10
- package/dist/audio_stream.d.cts +2 -2
- package/dist/audio_stream.d.ts +61 -18
- package/dist/data_streams/index.d.cts +1 -1
- package/dist/data_streams/index.d.ts +4 -3
- package/dist/data_streams/stream_reader.cjs +97 -58
- package/dist/data_streams/stream_reader.cjs.map +1 -1
- package/dist/data_streams/stream_reader.d.cts +1 -1
- package/dist/data_streams/stream_reader.d.ts +65 -2
- package/dist/data_streams/stream_reader.d.ts.map +1 -1
- package/dist/data_streams/stream_writer.d.cts +1 -1
- package/dist/data_streams/stream_writer.d.ts +5 -7
- package/dist/data_streams/types.cjs.map +1 -1
- package/dist/data_streams/types.d.cts +1 -1
- package/dist/data_streams/types.d.ts +47 -2
- package/dist/data_streams/types.d.ts.map +1 -1
- package/dist/e2ee.cjs +5 -1
- package/dist/e2ee.cjs.map +1 -1
- package/dist/e2ee.d.cts +3 -1
- package/dist/e2ee.d.ts +11 -11
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/ffi_client.d.ts +8 -10
- package/dist/frame_processor.d.ts +8 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +22 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -107
- package/dist/log.d.ts +5 -7
- package/dist/participant.cjs +179 -192
- package/dist/participant.cjs.map +1 -1
- package/dist/participant.d.cts +2 -2
- package/dist/participant.d.ts +169 -18
- package/dist/participant.d.ts.map +1 -1
- package/dist/room.cjs +166 -120
- package/dist/room.cjs.map +1 -1
- package/dist/room.d.cts +2 -2
- package/dist/room.d.ts +228 -18
- package/dist/room.d.ts.map +1 -1
- package/dist/rpc.d.ts +7 -9
- package/dist/tests/e2e_common.cjs +157 -0
- package/dist/tests/e2e_common.cjs.map +1 -0
- package/dist/tests/e2e_common.d.cts +56 -0
- package/dist/tests/e2e_common.d.ts +37 -0
- package/dist/tests/e2e_common.d.ts.map +1 -0
- package/dist/track.d.cts +2 -2
- package/dist/track.d.ts +67 -18
- package/dist/track_publication.d.cts +2 -2
- package/dist/track_publication.d.ts +45 -18
- package/dist/transcription.d.ts +3 -4
- package/dist/{types-_PdPVish.d.ts → types-f7wTlFjs.d.cts} +34 -11
- package/dist/types.d.ts +2 -3
- package/dist/utils.cjs +27 -2
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +8 -1
- package/dist/utils.d.ts +10 -5
- package/dist/utils.d.ts.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 +2 -3
- package/dist/video_frame.d.ts +4 -5
- package/dist/video_source.d.ts +6 -8
- package/dist/video_stream.d.cts +2 -2
- package/dist/video_stream.d.ts +5 -22
- package/package.json +6 -7
- package/src/audio_stream_room_lifecycle.test.ts +4 -1
- package/src/data_streams/stream_reader.ts +132 -82
- package/src/data_streams/types.ts +6 -0
- package/src/e2ee.ts +7 -0
- package/src/index.ts +8 -1
- package/src/participant.ts +252 -223
- package/src/room.ts +233 -134
- package/src/tests/e2e.test.ts +50 -139
- package/src/tests/e2e_common.ts +163 -0
- package/src/tests/e2e_data_streams.test.ts +639 -0
- package/src/utils.ts +30 -0
- package/src/version.ts +1 -1
- package/dist/async_queue.js +0 -56
- package/dist/async_queue.js.map +0 -1
- package/dist/audio_filter.js +0 -24
- package/dist/audio_filter.js.map +0 -1
- package/dist/audio_frame.js +0 -78
- package/dist/audio_frame.js.map +0 -1
- package/dist/audio_mixer.js +0 -269
- package/dist/audio_mixer.js.map +0 -1
- package/dist/audio_resampler.js +0 -154
- package/dist/audio_resampler.js.map +0 -1
- package/dist/audio_source.js +0 -134
- package/dist/audio_source.js.map +0 -1
- package/dist/audio_stream-CTyN1Ldy.d.ts +0 -523
- package/dist/audio_stream.js +0 -122
- package/dist/audio_stream.js.map +0 -1
- package/dist/data_streams/index.js +0 -3
- package/dist/data_streams/index.js.map +0 -1
- package/dist/data_streams/stream_reader.js +0 -124
- package/dist/data_streams/stream_reader.js.map +0 -1
- package/dist/data_streams/stream_writer.js +0 -26
- package/dist/data_streams/stream_writer.js.map +0 -1
- package/dist/data_streams/types.js +0 -1
- package/dist/data_streams/types.js.map +0 -1
- package/dist/e2ee.js +0 -251
- package/dist/e2ee.js.map +0 -1
- package/dist/ffi_client.js +0 -89
- package/dist/ffi_client.js.map +0 -1
- package/dist/frame_processor.js +0 -29
- package/dist/frame_processor.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/log.js +0 -9
- package/dist/log.js.map +0 -1
- package/dist/participant.js +0 -715
- package/dist/participant.js.map +0 -1
- package/dist/room.js +0 -900
- package/dist/room.js.map +0 -1
- package/dist/rpc.js +0 -65
- package/dist/rpc.js.map +0 -1
- package/dist/track.js +0 -234
- package/dist/track.js.map +0 -1
- package/dist/track_publication.js +0 -100
- package/dist/track_publication.js.map +0 -1
- package/dist/transcription.js +0 -1
- package/dist/transcription.js.map +0 -1
- package/dist/types-_PdPVish.d.cts +0 -87
- package/dist/types.js +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.js +0 -35
- package/dist/utils.js.map +0 -1
- package/dist/version.js +0 -5
- package/dist/version.js.map +0 -1
- package/dist/video_frame.js +0 -207
- package/dist/video_frame.js.map +0 -1
- package/dist/video_source.js +0 -53
- package/dist/video_source.js.map +0 -1
- package/dist/video_stream.js +0 -70
- package/dist/video_stream.js.map +0 -1
package/dist/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): Uint8Array[] {\n if (n < 4) {\n throw new Error('n must be at least 4 due to utf8 encoding rules');\n }\n // adapted from https://stackoverflow.com/a/6043797\n const result: Uint8Array[] = [];\n let encoded = new TextEncoder().encode(s);\n while (encoded.length > n) {\n let k = n;\n while (k > 0) {\n const byte = encoded[k];\n if (byte !== undefined && (byte & 0xc0) !== 0x80) {\n break;\n }\n k--;\n }\n result.push(encoded.slice(0, k));\n encoded = encoded.slice(k);\n }\n if (encoded.length > 0) {\n result.push(encoded);\n }\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n ByteStreamInfo as ProtoByteStreamInfo,\n TextStreamInfo as ProtoTextStreamInfo,\n} from '@livekit/rtc-ffi-bindings';\nimport type { ByteStreamInfo, TextStreamInfo } from './data_streams/types.js';\n\n/** convert bigints to numbers preserving undefined values */\nexport function bigIntToNumber<T extends bigint | undefined>(\n value: T,\n): T extends bigint ? number : undefined {\n return (value !== undefined ? Number(value) : undefined) as T extends bigint ? number : undefined;\n}\n\n/** convert numbers to bigints preserving undefined values */\nexport function numberToBigInt<T extends number | undefined>(\n value: T,\n): T extends number ? bigint : undefined {\n return (value !== undefined ? BigInt(value) : undefined) as T extends number ? bigint : undefined;\n}\n\nexport function splitUtf8(s: string, n: number): Uint8Array[] {\n if (n < 4) {\n throw new Error('n must be at least 4 due to utf8 encoding rules');\n }\n // adapted from https://stackoverflow.com/a/6043797\n const result: Uint8Array[] = [];\n let encoded = new TextEncoder().encode(s);\n while (encoded.length > n) {\n let k = n;\n while (k > 0) {\n const byte = encoded[k];\n if (byte !== undefined && (byte & 0xc0) !== 0x80) {\n break;\n }\n k--;\n }\n result.push(encoded.slice(0, k));\n encoded = encoded.slice(k);\n }\n if (encoded.length > 0) {\n result.push(encoded);\n }\n return result;\n}\n\n/** @internal */\nexport function textStreamInfoFromProto(info: ProtoTextStreamInfo): TextStreamInfo {\n return {\n streamId: info.streamId!,\n mimeType: info.mimeType!,\n topic: info.topic!,\n timestamp: bigIntToNumber(info.timestamp!),\n totalSize: info.totalLength ? bigIntToNumber(info.totalLength) : undefined,\n attributes: info.attributes,\n };\n}\n\n/** @internal */\nexport function byteStreamInfoFromProto(info: ProtoByteStreamInfo): ByteStreamInfo {\n return {\n streamId: info.streamId!,\n name: info.name ?? 'unknown',\n mimeType: info.mimeType!,\n topic: info.topic!,\n timestamp: bigIntToNumber(info.timestamp!),\n totalSize: info.totalLength !== undefined ? bigIntToNumber(info.totalLength) : undefined,\n attributes: info.attributes,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAGO,SAAS,eACd,OACuC;AACvC,SAAQ,UAAU,SAAY,OAAO,KAAK,IAAI;AAChD;AAEO,SAAS,UAAU,GAAW,GAAyB;AAC5D,MAAI,IAAI,GAAG;AACT,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,QAAM,SAAuB,CAAC;AAC9B,MAAI,UAAU,IAAI,YAAY,EAAE,OAAO,CAAC;AACxC,SAAO,QAAQ,SAAS,GAAG;AACzB,QAAI,IAAI;AACR,WAAO,IAAI,GAAG;AACZ,YAAM,OAAO,QAAQ,CAAC;AACtB,UAAI,SAAS,WAAc,OAAO,SAAU,KAAM;AAChD;AAAA,MACF;AACA;AAAA,IACF;AACA,WAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,CAAC;AAC/B,cAAU,QAAQ,MAAM,CAAC;AAAA,EAC3B;AACA,MAAI,QAAQ,SAAS,GAAG;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,wBAAwB,MAA2C;AACjF,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,eAAe,KAAK,SAAU;AAAA,IACzC,WAAW,KAAK,cAAc,eAAe,KAAK,WAAW,IAAI;AAAA,IACjE,YAAY,KAAK;AAAA,EACnB;AACF;AAGO,SAAS,wBAAwB,MAA2C;AACjF,SAAO;AAAA,IACL,UAAU,KAAK;AAAA,IACf,MAAM,KAAK,QAAQ;AAAA,IACnB,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,eAAe,KAAK,SAAU;AAAA,IACzC,WAAW,KAAK,gBAAgB,SAAY,eAAe,KAAK,WAAW,IAAI;AAAA,IAC/E,YAAY,KAAK;AAAA,EACnB;AACF;","names":[]}
|
package/dist/utils.d.cts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import { ByteStreamInfo, TextStreamInfo } from '@livekit/rtc-ffi-bindings';
|
|
2
|
+
import { b as ByteStreamInfo$1, e as TextStreamInfo$1 } from './types-f7wTlFjs.cjs';
|
|
3
|
+
|
|
1
4
|
/** convert bigints to numbers preserving undefined values */
|
|
2
5
|
declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
|
|
3
6
|
/** convert numbers to bigints preserving undefined values */
|
|
4
7
|
declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
|
|
5
8
|
declare function splitUtf8(s: string, n: number): Uint8Array[];
|
|
9
|
+
/** @internal */
|
|
10
|
+
declare function textStreamInfoFromProto(info: TextStreamInfo): TextStreamInfo$1;
|
|
11
|
+
/** @internal */
|
|
12
|
+
declare function byteStreamInfoFromProto(info: ByteStreamInfo): ByteStreamInfo$1;
|
|
6
13
|
|
|
7
|
-
export { bigIntToNumber, numberToBigInt, splitUtf8 };
|
|
14
|
+
export { bigIntToNumber, byteStreamInfoFromProto, numberToBigInt, splitUtf8, textStreamInfoFromProto };
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import type { ByteStreamInfo as ProtoByteStreamInfo, TextStreamInfo as ProtoTextStreamInfo } from '@livekit/rtc-ffi-bindings';
|
|
2
|
+
import type { ByteStreamInfo, TextStreamInfo } from './data_streams/types.js';
|
|
1
3
|
/** convert bigints to numbers preserving undefined values */
|
|
2
|
-
declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
|
|
4
|
+
export declare function bigIntToNumber<T extends bigint | undefined>(value: T): T extends bigint ? number : undefined;
|
|
3
5
|
/** convert numbers to bigints preserving undefined values */
|
|
4
|
-
declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
|
|
5
|
-
declare function splitUtf8(s: string, n: number): Uint8Array[];
|
|
6
|
-
|
|
7
|
-
export
|
|
6
|
+
export declare function numberToBigInt<T extends number | undefined>(value: T): T extends number ? bigint : undefined;
|
|
7
|
+
export declare function splitUtf8(s: string, n: number): Uint8Array[];
|
|
8
|
+
/** @internal */
|
|
9
|
+
export declare function textStreamInfoFromProto(info: ProtoTextStreamInfo): TextStreamInfo;
|
|
10
|
+
/** @internal */
|
|
11
|
+
export declare function byteStreamInfoFromProto(info: ProtoByteStreamInfo): ByteStreamInfo;
|
|
12
|
+
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,IAAI,mBAAmB,EACrC,cAAc,IAAI,mBAAmB,EACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9E,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EACzD,KAAK,EAAE,CAAC,GACP,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvC;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAuB5D;AAED,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CASjF;AAED,gBAAgB;AAChB,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CAUjF"}
|
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.34";
|
|
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.34\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,cAAc;","names":[]}
|
package/dist/version.d.cts
CHANGED
package/dist/version.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
declare const SDK_VERSION = "0.13.
|
|
2
|
-
|
|
3
|
-
export { SDK_VERSION };
|
|
1
|
+
export declare const SDK_VERSION = "0.13.34";
|
|
2
|
+
//# sourceMappingURL=version.d.ts.map
|
package/dist/video_frame.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
declare class VideoFrame {
|
|
1
|
+
import type { OwnedVideoBuffer } from '@livekit/rtc-ffi-bindings';
|
|
2
|
+
import { VideoBufferInfo, VideoBufferType } from '@livekit/rtc-ffi-bindings';
|
|
3
|
+
export declare class VideoFrame {
|
|
4
4
|
data: Uint8Array;
|
|
5
5
|
width: number;
|
|
6
6
|
height: number;
|
|
@@ -15,5 +15,4 @@ declare class VideoFrame {
|
|
|
15
15
|
getPlane(planeNth: number): Uint8Array | void;
|
|
16
16
|
convert(dstType: VideoBufferType, flipY?: boolean): VideoFrame;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
export { VideoFrame };
|
|
18
|
+
//# sourceMappingURL=video_frame.d.ts.map
|
package/dist/video_source.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { VideoSourceInfo
|
|
2
|
-
import '
|
|
3
|
-
import {
|
|
4
|
-
import '
|
|
5
|
-
|
|
6
|
-
declare class VideoSource {
|
|
1
|
+
import type { VideoSourceInfo } from '@livekit/rtc-ffi-bindings';
|
|
2
|
+
import { VideoRotation } from '@livekit/rtc-ffi-bindings';
|
|
3
|
+
import { FfiHandle } from './ffi_client.js';
|
|
4
|
+
import type { VideoFrame } from './video_frame.js';
|
|
5
|
+
export declare class VideoSource {
|
|
7
6
|
/** @internal */
|
|
8
7
|
info?: VideoSourceInfo;
|
|
9
8
|
/** @internal */
|
|
@@ -16,5 +15,4 @@ declare class VideoSource {
|
|
|
16
15
|
captureFrame(frame: VideoFrame, timestampUs?: bigint, rotation?: VideoRotation): void;
|
|
17
16
|
close(): Promise<void>;
|
|
18
17
|
}
|
|
19
|
-
|
|
20
|
-
export { VideoSource };
|
|
18
|
+
//# sourceMappingURL=video_source.d.ts.map
|
package/dist/video_stream.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VideoRotation } from '@livekit/rtc-ffi-bindings';
|
|
2
|
-
import { T as Track } from './audio_stream-
|
|
2
|
+
import { T as Track } from './audio_stream-BNVaONuH.cjs';
|
|
3
3
|
import { VideoFrame } from './video_frame.cjs';
|
|
4
4
|
import 'node:stream/web';
|
|
5
5
|
import './audio_frame.cjs';
|
|
@@ -7,7 +7,7 @@ import './frame_processor.cjs';
|
|
|
7
7
|
import './audio_source.cjs';
|
|
8
8
|
import './ffi_client.cjs';
|
|
9
9
|
import '@livekit/typed-emitter';
|
|
10
|
-
import './types-
|
|
10
|
+
import './types-f7wTlFjs.cjs';
|
|
11
11
|
import './e2ee.cjs';
|
|
12
12
|
import '@livekit/mutex';
|
|
13
13
|
import 'node:fs';
|
package/dist/video_stream.d.ts
CHANGED
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
import { VideoRotation } from '@livekit/rtc-ffi-bindings';
|
|
2
|
-
import {
|
|
1
|
+
import type { VideoRotation } from '@livekit/rtc-ffi-bindings';
|
|
2
|
+
import type { Track } from './track.js';
|
|
3
3
|
import { VideoFrame } from './video_frame.js';
|
|
4
|
-
|
|
5
|
-
import './audio_frame.js';
|
|
6
|
-
import './frame_processor.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';
|
|
19
|
-
|
|
20
|
-
type VideoFrameEvent = {
|
|
4
|
+
export type VideoFrameEvent = {
|
|
21
5
|
frame: VideoFrame;
|
|
22
6
|
timestampUs: bigint;
|
|
23
7
|
rotation: VideoRotation;
|
|
24
8
|
};
|
|
25
|
-
declare class VideoStream extends ReadableStream<VideoFrameEvent> {
|
|
9
|
+
export declare class VideoStream extends ReadableStream<VideoFrameEvent> {
|
|
26
10
|
constructor(track: Track);
|
|
27
11
|
}
|
|
28
|
-
|
|
29
|
-
export { type VideoFrameEvent, VideoStream };
|
|
12
|
+
//# sourceMappingURL=video_stream.d.ts.map
|
package/package.json
CHANGED
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
"description": "LiveKit RTC Node",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"author": "LiveKit",
|
|
6
|
-
"version": "0.13.
|
|
7
|
-
"main": "dist/index.
|
|
8
|
-
"
|
|
9
|
-
"types": "dist/index.d.ts",
|
|
6
|
+
"version": "0.13.34",
|
|
7
|
+
"main": "dist/index.cjs",
|
|
8
|
+
"types": "dist/index.d.cts",
|
|
10
9
|
"exports": {
|
|
11
10
|
".": {
|
|
12
11
|
"import": {
|
|
@@ -32,7 +31,7 @@
|
|
|
32
31
|
"dependencies": {
|
|
33
32
|
"@datastructures-js/deque": "1.0.8",
|
|
34
33
|
"@livekit/mutex": "^1.0.0",
|
|
35
|
-
"@livekit/rtc-ffi-bindings": "0.12.
|
|
34
|
+
"@livekit/rtc-ffi-bindings": "0.12.73",
|
|
36
35
|
"@livekit/typed-emitter": "^3.0.0",
|
|
37
36
|
"pino": "^9.0.0",
|
|
38
37
|
"pino-pretty": "^13.0.0"
|
|
@@ -44,14 +43,14 @@
|
|
|
44
43
|
"tsup": "^8.3.5",
|
|
45
44
|
"typescript": "5.8.2",
|
|
46
45
|
"vitest": "^4.0.0",
|
|
47
|
-
"livekit-server-sdk": "2.
|
|
46
|
+
"livekit-server-sdk": "2.18.0"
|
|
48
47
|
},
|
|
49
48
|
"engines": {
|
|
50
49
|
"node": ">= 18"
|
|
51
50
|
},
|
|
52
51
|
"scripts": {
|
|
53
52
|
"prebuild": "node -p \"'export const SDK_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
|
|
54
|
-
"build": "pnpm prebuild && tsup
|
|
53
|
+
"build": "pnpm prebuild && tsup && node scripts/postbuild.mjs",
|
|
55
54
|
"lint": "eslint -f unix \"src/**/*.ts\" --ignore-pattern \"src/proto/*\"",
|
|
56
55
|
"test": "vitest run src",
|
|
57
56
|
"test:e2e": "node scripts/run-e2e.mjs"
|
|
@@ -146,12 +146,15 @@ function makeEndTrackingStream(): { stream: AudioStreamSource; endCount: () => n
|
|
|
146
146
|
|
|
147
147
|
function makeLocalParticipant(identity: string): LocalParticipant {
|
|
148
148
|
// Bypass the FFI-touching constructor; set only the fields the lifecycle
|
|
149
|
-
// paths read (identity getter
|
|
149
|
+
// paths read (identity getter, trackPublications map, and the open data
|
|
150
|
+
// stream writers that disconnect cleanup disposes).
|
|
150
151
|
const p = Object.create(LocalParticipant.prototype) as LocalParticipant;
|
|
151
152
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
152
153
|
(p as any).info = { identity };
|
|
153
154
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
155
|
(p as any).trackPublications = new Map();
|
|
156
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
157
|
+
(p as any).openStreamWriters = new Set();
|
|
155
158
|
return p;
|
|
156
159
|
}
|
|
157
160
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import type { DataStream_Chunk } from '@livekit/rtc-ffi-bindings';
|
|
5
5
|
import { log } from '../log.js';
|
|
6
|
-
import { bigIntToNumber } from '../utils.js';
|
|
7
6
|
import type { BaseStreamInfo, ByteStreamInfo, TextStreamInfo } from './types.js';
|
|
8
7
|
|
|
9
8
|
abstract class BaseStreamReader<T extends BaseStreamInfo> {
|
|
@@ -15,6 +14,12 @@ abstract class BaseStreamReader<T extends BaseStreamInfo> {
|
|
|
15
14
|
|
|
16
15
|
protected bytesReceived: number;
|
|
17
16
|
|
|
17
|
+
private closed = false;
|
|
18
|
+
|
|
19
|
+
// The reader held by an in-progress iteration. Cancelling has to go through
|
|
20
|
+
// it, since it holds the stream's lock.
|
|
21
|
+
private activeReader: ReadableStreamDefaultReader<DataStream_Chunk> | null = null;
|
|
22
|
+
|
|
18
23
|
get info() {
|
|
19
24
|
return this._info;
|
|
20
25
|
}
|
|
@@ -26,7 +31,68 @@ abstract class BaseStreamReader<T extends BaseStreamInfo> {
|
|
|
26
31
|
this.bytesReceived = 0;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
protected
|
|
34
|
+
protected handleChunkReceived(chunk: DataStream_Chunk) {
|
|
35
|
+
this.bytesReceived += chunk.content!.byteLength;
|
|
36
|
+
const currentProgress = this.totalByteSize
|
|
37
|
+
? this.bytesReceived / this.totalByteSize
|
|
38
|
+
: undefined;
|
|
39
|
+
this.onProgress?.(currentProgress);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Takes the stream's reader for an iteration, remembering it so that
|
|
43
|
+
* close() can cancel a read that is still in flight. */
|
|
44
|
+
protected acquireReader(): ReadableStreamDefaultReader<DataStream_Chunk> {
|
|
45
|
+
const reader = this.reader.getReader();
|
|
46
|
+
this.activeReader = reader;
|
|
47
|
+
return reader;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Releases the stream lock after an iteration ended on its own — because a
|
|
51
|
+
* read reported end-of-stream, or because the stream itself errored. Either
|
|
52
|
+
* way the stream is in a terminal state and the FFI subscription behind it
|
|
53
|
+
* was already dropped by that terminal event, so there is nothing to cancel.
|
|
54
|
+
*
|
|
55
|
+
* An error raised *around* a read rather than by it — a chunk that failed to
|
|
56
|
+
* process — leaves the stream live, so it has to go through close() instead. */
|
|
57
|
+
protected finishIteration(reader: ReadableStreamDefaultReader<DataStream_Chunk>) {
|
|
58
|
+
this.closed = true;
|
|
59
|
+
if (this.activeReader === reader) {
|
|
60
|
+
this.activeReader = null;
|
|
61
|
+
}
|
|
62
|
+
reader.releaseLock();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Stops receiving this stream and releases the resources behind it.
|
|
67
|
+
*
|
|
68
|
+
* A reader is subscribed to FFI events from the moment it is handed to a
|
|
69
|
+
* stream handler, and only unsubscribes once a read consumes the stream's
|
|
70
|
+
* end-of-stream event. So a reader that is abandoned part-way through, or
|
|
71
|
+
* that a handler never reads at all, has to be closed here or its
|
|
72
|
+
* subscription lives for the rest of the process. Reading to completion — or
|
|
73
|
+
* breaking out of a `for await` — closes the reader for you, and closing an
|
|
74
|
+
* already-closed reader is a no-op.
|
|
75
|
+
*/
|
|
76
|
+
async close(): Promise<void> {
|
|
77
|
+
if (this.closed) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.closed = true;
|
|
81
|
+
const active = this.activeReader;
|
|
82
|
+
this.activeReader = null;
|
|
83
|
+
try {
|
|
84
|
+
if (active) {
|
|
85
|
+
await active.cancel();
|
|
86
|
+
active.releaseLock();
|
|
87
|
+
} else {
|
|
88
|
+
await this.reader.cancel();
|
|
89
|
+
}
|
|
90
|
+
} catch (error: unknown) {
|
|
91
|
+
// The stream was already closed or errored (e.g. the room disconnected
|
|
92
|
+
// mid-stream), in which case its subscription is already gone.
|
|
93
|
+
log.debug('error closing stream reader: %s', error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
30
96
|
|
|
31
97
|
onProgress?: (progress: number | undefined) => void;
|
|
32
98
|
|
|
@@ -37,41 +103,48 @@ abstract class BaseStreamReader<T extends BaseStreamInfo> {
|
|
|
37
103
|
* A class to read chunks from a ReadableStream and provide them in a structured format.
|
|
38
104
|
*/
|
|
39
105
|
export class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
|
|
40
|
-
protected handleChunkReceived(chunk: DataStream_Chunk) {
|
|
41
|
-
this.bytesReceived += chunk.content!.byteLength;
|
|
42
|
-
const currentProgress = this.totalByteSize
|
|
43
|
-
? this.bytesReceived / this.totalByteSize
|
|
44
|
-
: undefined;
|
|
45
|
-
this.onProgress?.(currentProgress);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
106
|
[Symbol.asyncIterator]() {
|
|
49
|
-
const reader = this.
|
|
107
|
+
const reader = this.acquireReader();
|
|
50
108
|
|
|
51
109
|
return {
|
|
52
110
|
next: async (): Promise<IteratorResult<Uint8Array>> => {
|
|
111
|
+
let read: Awaited<ReturnType<typeof reader.read>>;
|
|
53
112
|
try {
|
|
54
|
-
|
|
55
|
-
if (done) {
|
|
56
|
-
// Release the lock when the stream is exhausted so the
|
|
57
|
-
// underlying ReadableStream can be garbage-collected.
|
|
58
|
-
reader.releaseLock();
|
|
59
|
-
return { done: true, value: undefined as unknown };
|
|
60
|
-
} else {
|
|
61
|
-
this.handleChunkReceived(value);
|
|
62
|
-
return { done: false, value: value.content! };
|
|
63
|
-
}
|
|
113
|
+
read = await reader.read();
|
|
64
114
|
} catch (error: unknown) {
|
|
65
|
-
//
|
|
66
|
-
// consumer never calls return() (
|
|
67
|
-
|
|
68
|
-
|
|
115
|
+
// The stream errored, which is terminal: release the lock so it
|
|
116
|
+
// doesn't stay held when the consumer never calls return() (a
|
|
117
|
+
// rejecting next() doesn't trigger it).
|
|
118
|
+
this.finishIteration(reader);
|
|
119
|
+
log.error('error reading stream: %s', error);
|
|
120
|
+
// Propagate abnormal termination (e.g. remote abort, payload over
|
|
121
|
+
// the receiver's size limit) instead of presenting the truncated
|
|
122
|
+
// payload as a clean EOF.
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (read.done) {
|
|
127
|
+
// Release the lock when the stream is exhausted so the
|
|
128
|
+
// underlying ReadableStream can be garbage-collected.
|
|
129
|
+
this.finishIteration(reader);
|
|
69
130
|
return { done: true, value: undefined as unknown };
|
|
70
131
|
}
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
this.handleChunkReceived(read.value);
|
|
135
|
+
return { done: false, value: read.value.content! };
|
|
136
|
+
} catch (error: unknown) {
|
|
137
|
+
// The chunk arrived fine but handling it threw (e.g. a consumer's
|
|
138
|
+
// onProgress callback). The stream is still live, so it has to be
|
|
139
|
+
// cancelled to release its FFI subscription.
|
|
140
|
+
await this.close();
|
|
141
|
+
log.error('error processing stream update: %s', error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
71
144
|
},
|
|
72
145
|
|
|
73
|
-
return(): IteratorResult<Uint8Array
|
|
74
|
-
|
|
146
|
+
return: async (): Promise<IteratorResult<Uint8Array>> => {
|
|
147
|
+
await this.close();
|
|
75
148
|
return { done: true, value: undefined };
|
|
76
149
|
},
|
|
77
150
|
};
|
|
@@ -90,77 +163,54 @@ export class ByteStreamReader extends BaseStreamReader<ByteStreamInfo> {
|
|
|
90
163
|
* A class to read chunks from a ReadableStream and provide them in a structured format.
|
|
91
164
|
*/
|
|
92
165
|
export class TextStreamReader extends BaseStreamReader<TextStreamInfo> {
|
|
93
|
-
private receivedChunks: Map<number, DataStream_Chunk>;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* A TextStreamReader instance can be used as an AsyncIterator that returns the entire string
|
|
97
|
-
* that has been received up to the current point in time.
|
|
98
|
-
*/
|
|
99
|
-
constructor(
|
|
100
|
-
info: TextStreamInfo,
|
|
101
|
-
stream: ReadableStream<DataStream_Chunk>,
|
|
102
|
-
totalChunkCount?: number,
|
|
103
|
-
) {
|
|
104
|
-
super(info, stream, totalChunkCount);
|
|
105
|
-
this.receivedChunks = new Map();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
protected handleChunkReceived(chunk: DataStream_Chunk) {
|
|
109
|
-
const index = bigIntToNumber(chunk.chunkIndex!);
|
|
110
|
-
const previousChunkAtIndex = this.receivedChunks.get(index!);
|
|
111
|
-
if (previousChunkAtIndex && previousChunkAtIndex.version! > chunk.version!) {
|
|
112
|
-
// we have a newer version already, dropping the old one
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
this.receivedChunks.set(index, chunk);
|
|
116
|
-
const currentProgress = this.totalByteSize
|
|
117
|
-
? this.receivedChunks.size / this.totalByteSize
|
|
118
|
-
: undefined;
|
|
119
|
-
this.onProgress?.(currentProgress);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
166
|
/**
|
|
123
167
|
* Async iterator implementation to allow usage of `for await...of` syntax.
|
|
124
168
|
* Yields structured chunks from the stream.
|
|
125
169
|
*
|
|
126
170
|
*/
|
|
127
171
|
[Symbol.asyncIterator]() {
|
|
128
|
-
const reader = this.
|
|
172
|
+
const reader = this.acquireReader();
|
|
129
173
|
const decoder = new TextDecoder();
|
|
130
|
-
const receivedChunks = this.receivedChunks;
|
|
131
174
|
|
|
132
175
|
return {
|
|
133
176
|
next: async (): Promise<IteratorResult<string>> => {
|
|
177
|
+
let read: Awaited<ReturnType<typeof reader.read>>;
|
|
134
178
|
try {
|
|
135
|
-
|
|
136
|
-
if (done) {
|
|
137
|
-
// Release the lock when the stream is exhausted so the
|
|
138
|
-
// underlying ReadableStream can be garbage-collected.
|
|
139
|
-
reader.releaseLock();
|
|
140
|
-
// Clear received chunks so the buffered data can be GC'd.
|
|
141
|
-
receivedChunks.clear();
|
|
142
|
-
return { done: true, value: undefined };
|
|
143
|
-
} else {
|
|
144
|
-
this.handleChunkReceived(value);
|
|
145
|
-
return {
|
|
146
|
-
done: false,
|
|
147
|
-
value: decoder.decode(value.content!),
|
|
148
|
-
};
|
|
149
|
-
}
|
|
179
|
+
read = await reader.read();
|
|
150
180
|
} catch (error: unknown) {
|
|
151
|
-
//
|
|
152
|
-
// consumer never calls return() (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
log.error('error
|
|
181
|
+
// The stream errored, which is terminal: release the lock so it
|
|
182
|
+
// doesn't stay held when the consumer never calls return() (a
|
|
183
|
+
// rejecting next() doesn't trigger it).
|
|
184
|
+
this.finishIteration(reader);
|
|
185
|
+
log.error('error reading stream: %s', error);
|
|
186
|
+
// Propagate abnormal termination (e.g. remote abort, payload over
|
|
187
|
+
// the receiver's size limit) instead of presenting the truncated
|
|
188
|
+
// payload as a clean EOF.
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (read.done) {
|
|
193
|
+
// Release the lock when the stream is exhausted so the
|
|
194
|
+
// underlying ReadableStream can be garbage-collected.
|
|
195
|
+
this.finishIteration(reader);
|
|
156
196
|
return { done: true, value: undefined };
|
|
157
197
|
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
this.handleChunkReceived(read.value);
|
|
201
|
+
return { done: false, value: decoder.decode(read.value.content!) };
|
|
202
|
+
} catch (error: unknown) {
|
|
203
|
+
// The chunk arrived fine but handling it threw (e.g. a consumer's
|
|
204
|
+
// onProgress callback). The stream is still live, so it has to be
|
|
205
|
+
// cancelled to release its FFI subscription.
|
|
206
|
+
await this.close();
|
|
207
|
+
log.error('error processing stream update: %s', error);
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
158
210
|
},
|
|
159
211
|
|
|
160
|
-
return(): IteratorResult<string
|
|
161
|
-
|
|
162
|
-
// Clear received chunks so the buffered data can be GC'd.
|
|
163
|
-
receivedChunks.clear();
|
|
212
|
+
return: async (): Promise<IteratorResult<string>> => {
|
|
213
|
+
await this.close();
|
|
164
214
|
return { done: true, value: undefined };
|
|
165
215
|
},
|
|
166
216
|
};
|
|
@@ -42,6 +42,12 @@ export interface TextStreamOptions extends DataStreamOptions {
|
|
|
42
42
|
export interface ByteStreamOptions extends DataStreamOptions {
|
|
43
43
|
name?: string;
|
|
44
44
|
onProgress?: (progress: number) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the payload may be compressed on the wire. Defaults to true;
|
|
47
|
+
* compression is only applied when it actually reduces the payload size
|
|
48
|
+
* and every recipient supports it.
|
|
49
|
+
*/
|
|
50
|
+
compress?: boolean;
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
export type ByteStreamHandler = (
|
package/src/e2ee.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
FrameCryptorSetKeyIndexRequest,
|
|
18
18
|
GetKeyRequest,
|
|
19
19
|
GetSharedKeyRequest,
|
|
20
|
+
KeyDerivationFunction,
|
|
20
21
|
RatchetKeyRequest,
|
|
21
22
|
RatchetSharedKeyRequest,
|
|
22
23
|
SetKeyRequest,
|
|
@@ -27,18 +28,24 @@ import { FfiClient } from './ffi_client.js';
|
|
|
27
28
|
const DEFAULT_RATCHET_SALT = new TextEncoder().encode('LKFrameEncryptionKey');
|
|
28
29
|
const DEFAULT_RATCHET_WINDOW_SIZE = 16;
|
|
29
30
|
const DEFAULT_FAILURE_TOLERANCE = -1;
|
|
31
|
+
const DEFAULT_KEY_RING_SIZE = 16;
|
|
32
|
+
const DEFAULT_KEY_DERIVATION_FUNCTION = KeyDerivationFunction.PBKDF2;
|
|
30
33
|
|
|
31
34
|
export interface KeyProviderOptions {
|
|
32
35
|
sharedKey?: Uint8Array;
|
|
33
36
|
ratchetSalt?: Uint8Array;
|
|
34
37
|
ratchetWindowSize?: number;
|
|
35
38
|
failureTolerance?: number;
|
|
39
|
+
keyRingSize?: number;
|
|
40
|
+
keyDerivationFunction?: KeyDerivationFunction;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
export const defaultKeyProviderOptions: KeyProviderOptions = {
|
|
39
44
|
ratchetSalt: DEFAULT_RATCHET_SALT,
|
|
40
45
|
ratchetWindowSize: DEFAULT_RATCHET_WINDOW_SIZE,
|
|
41
46
|
failureTolerance: DEFAULT_FAILURE_TOLERANCE,
|
|
47
|
+
keyRingSize: DEFAULT_KEY_RING_SIZE,
|
|
48
|
+
keyDerivationFunction: DEFAULT_KEY_DERIVATION_FUNCTION,
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
export interface E2EEOptions {
|
package/src/index.ts
CHANGED
|
@@ -36,7 +36,14 @@ export {
|
|
|
36
36
|
TrackSource,
|
|
37
37
|
} from '@livekit/rtc-ffi-bindings';
|
|
38
38
|
export { VideoBufferType, VideoCodec, VideoRotation } from '@livekit/rtc-ffi-bindings';
|
|
39
|
-
export {
|
|
39
|
+
export {
|
|
40
|
+
ConnectError,
|
|
41
|
+
Room,
|
|
42
|
+
RoomEvent,
|
|
43
|
+
type RoomDataStreamOptions,
|
|
44
|
+
type RoomOptions,
|
|
45
|
+
type RtcConfiguration,
|
|
46
|
+
} from './room.js';
|
|
40
47
|
export { RpcError, type PerformRpcParams, type RpcInvocationData } from './rpc.js';
|
|
41
48
|
export {
|
|
42
49
|
LocalAudioTrack,
|