@livekit/rtc-node 0.13.32 → 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 (110) 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-4M8XlO4-.d.cts → audio_stream-CnODFAmo.d.cts} +1 -0
  8. package/dist/audio_stream.d.cts +1 -1
  9. package/dist/audio_stream.d.ts +61 -18
  10. package/dist/data_streams/index.d.ts +4 -3
  11. package/dist/data_streams/stream_reader.d.ts +48 -2
  12. package/dist/data_streams/stream_writer.d.ts +5 -7
  13. package/dist/data_streams/types.d.ts +41 -2
  14. package/dist/e2ee.d.ts +8 -10
  15. package/dist/ffi_client.d.ts +8 -10
  16. package/dist/frame_processor.d.ts +8 -11
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +2 -2
  19. package/dist/index.d.ts +22 -17
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +1 -107
  22. package/dist/log.d.ts +5 -7
  23. package/dist/participant.cjs +7 -2
  24. package/dist/participant.cjs.map +1 -1
  25. package/dist/participant.d.cts +1 -1
  26. package/dist/participant.d.ts +152 -18
  27. package/dist/participant.d.ts.map +1 -1
  28. package/dist/room.cjs +6 -0
  29. package/dist/room.cjs.map +1 -1
  30. package/dist/room.d.cts +2 -2
  31. package/dist/room.d.ts +220 -18
  32. package/dist/room.d.ts.map +1 -1
  33. package/dist/rpc.d.ts +7 -9
  34. package/dist/track.d.cts +1 -1
  35. package/dist/track.d.ts +67 -18
  36. package/dist/track_publication.d.cts +1 -1
  37. package/dist/track_publication.d.ts +45 -18
  38. package/dist/transcription.d.ts +3 -4
  39. package/dist/types.d.ts +2 -3
  40. package/dist/utils.d.ts +4 -5
  41. package/dist/version.cjs +1 -1
  42. package/dist/version.cjs.map +1 -1
  43. package/dist/version.d.cts +1 -1
  44. package/dist/version.d.ts +2 -3
  45. package/dist/video_frame.d.ts +4 -5
  46. package/dist/video_source.d.ts +6 -8
  47. package/dist/video_stream.d.cts +1 -1
  48. package/dist/video_stream.d.ts +5 -22
  49. package/package.json +5 -6
  50. package/src/index.ts +8 -1
  51. package/src/participant.ts +7 -1
  52. package/src/room.ts +10 -0
  53. package/src/version.ts +1 -1
  54. package/dist/async_queue.js +0 -56
  55. package/dist/async_queue.js.map +0 -1
  56. package/dist/audio_filter.js +0 -24
  57. package/dist/audio_filter.js.map +0 -1
  58. package/dist/audio_frame.js +0 -78
  59. package/dist/audio_frame.js.map +0 -1
  60. package/dist/audio_mixer.js +0 -269
  61. package/dist/audio_mixer.js.map +0 -1
  62. package/dist/audio_resampler.js +0 -154
  63. package/dist/audio_resampler.js.map +0 -1
  64. package/dist/audio_source.js +0 -134
  65. package/dist/audio_source.js.map +0 -1
  66. package/dist/audio_stream-CTyN1Ldy.d.ts +0 -523
  67. package/dist/audio_stream.js +0 -122
  68. package/dist/audio_stream.js.map +0 -1
  69. package/dist/data_streams/index.js +0 -3
  70. package/dist/data_streams/index.js.map +0 -1
  71. package/dist/data_streams/stream_reader.js +0 -124
  72. package/dist/data_streams/stream_reader.js.map +0 -1
  73. package/dist/data_streams/stream_writer.js +0 -26
  74. package/dist/data_streams/stream_writer.js.map +0 -1
  75. package/dist/data_streams/types.js +0 -1
  76. package/dist/data_streams/types.js.map +0 -1
  77. package/dist/e2ee.js +0 -251
  78. package/dist/e2ee.js.map +0 -1
  79. package/dist/ffi_client.js +0 -89
  80. package/dist/ffi_client.js.map +0 -1
  81. package/dist/frame_processor.js +0 -29
  82. package/dist/frame_processor.js.map +0 -1
  83. package/dist/index.js.map +0 -1
  84. package/dist/log.js +0 -9
  85. package/dist/log.js.map +0 -1
  86. package/dist/participant.js +0 -715
  87. package/dist/participant.js.map +0 -1
  88. package/dist/room.js +0 -900
  89. package/dist/room.js.map +0 -1
  90. package/dist/rpc.js +0 -65
  91. package/dist/rpc.js.map +0 -1
  92. package/dist/track.js +0 -234
  93. package/dist/track.js.map +0 -1
  94. package/dist/track_publication.js +0 -100
  95. package/dist/track_publication.js.map +0 -1
  96. package/dist/transcription.js +0 -1
  97. package/dist/transcription.js.map +0 -1
  98. package/dist/types-_PdPVish.d.ts +0 -87
  99. package/dist/types.js +0 -1
  100. package/dist/types.js.map +0 -1
  101. package/dist/utils.js +0 -35
  102. package/dist/utils.js.map +0 -1
  103. package/dist/version.js +0 -5
  104. package/dist/version.js.map +0 -1
  105. package/dist/video_frame.js +0 -207
  106. package/dist/video_frame.js.map +0 -1
  107. package/dist/video_source.js +0 -53
  108. package/dist/video_source.js.map +0 -1
  109. package/dist/video_stream.js +0 -70
  110. package/dist/video_stream.js.map +0 -1
@@ -1,87 +0,0 @@
1
- import { DataStream_Chunk, DataStream_Header } from '@livekit/rtc-ffi-bindings';
2
-
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
- 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
- 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
-
48
- interface StreamController<T extends DataStream_Chunk> {
49
- header: DataStream_Header;
50
- controller: ReadableStreamDefaultController<T>;
51
- startTime: number;
52
- endTime?: number;
53
- }
54
- interface BaseStreamInfo {
55
- streamId: string;
56
- mimeType: string;
57
- topic: string;
58
- timestamp: number;
59
- /** total size in bytes for finite streams and undefined for streams of unknown size */
60
- totalSize?: number;
61
- attributes?: Record<string, string>;
62
- }
63
- type ByteStreamInfo = BaseStreamInfo & {
64
- name: string;
65
- };
66
- type TextStreamInfo = BaseStreamInfo;
67
- interface DataStreamOptions {
68
- topic?: string;
69
- destinationIdentities?: Array<string>;
70
- attributes?: Record<string, string>;
71
- mimeType?: string;
72
- }
73
- interface TextStreamOptions extends DataStreamOptions {
74
- attachments?: [];
75
- }
76
- interface ByteStreamOptions extends DataStreamOptions {
77
- name?: string;
78
- onProgress?: (progress: number) => void;
79
- }
80
- type ByteStreamHandler = (reader: ByteStreamReader, participantInfo: {
81
- identity: string;
82
- }) => void;
83
- type TextStreamHandler = (reader: TextStreamReader, participantInfo: {
84
- identity: string;
85
- }) => void;
86
-
87
- export { type BaseStreamInfo as B, type DataStreamOptions as D, type StreamController as S, type TextStreamHandler as T, type ByteStreamHandler as a, type ByteStreamInfo as b, type ByteStreamOptions as c, ByteStreamReader as d, type TextStreamInfo as e, type TextStreamOptions as f, TextStreamReader as g };
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/utils.js DELETED
@@ -1,35 +0,0 @@
1
- function bigIntToNumber(value) {
2
- return value !== void 0 ? Number(value) : void 0;
3
- }
4
- function numberToBigInt(value) {
5
- return value !== void 0 ? BigInt(value) : void 0;
6
- }
7
- function splitUtf8(s, n) {
8
- if (n < 4) {
9
- throw new Error("n must be at least 4 due to utf8 encoding rules");
10
- }
11
- const result = [];
12
- let encoded = new TextEncoder().encode(s);
13
- while (encoded.length > n) {
14
- let k = n;
15
- while (k > 0) {
16
- const byte = encoded[k];
17
- if (byte !== void 0 && (byte & 192) !== 128) {
18
- break;
19
- }
20
- k--;
21
- }
22
- result.push(encoded.slice(0, k));
23
- encoded = encoded.slice(k);
24
- }
25
- if (encoded.length > 0) {
26
- result.push(encoded);
27
- }
28
- return result;
29
- }
30
- export {
31
- bigIntToNumber,
32
- numberToBigInt,
33
- splitUtf8
34
- };
35
- //# sourceMappingURL=utils.js.map
package/dist/utils.js.map DELETED
@@ -1 +0,0 @@
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":"AAKO,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;","names":[]}
package/dist/version.js DELETED
@@ -1,5 +0,0 @@
1
- const SDK_VERSION = "0.13.32";
2
- export {
3
- SDK_VERSION
4
- };
5
- //# sourceMappingURL=version.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const SDK_VERSION = \"0.13.32\";\n"],"mappings":"AAAO,MAAM,cAAc;","names":[]}
@@ -1,207 +0,0 @@
1
- import {
2
- VideoBufferInfo,
3
- VideoBufferInfo_ComponentInfo,
4
- VideoBufferType
5
- } from "@livekit/rtc-ffi-bindings";
6
- import { FfiClient, FfiHandle, FfiRequest } from "./ffi_client.js";
7
- class VideoFrame {
8
- constructor(data, width, height, type) {
9
- this.data = data;
10
- this.width = width;
11
- this.height = height;
12
- this.type = type;
13
- }
14
- /** @internal */
15
- get dataPtr() {
16
- return FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer));
17
- }
18
- /** @internal */
19
- protoInfo() {
20
- const info = new VideoBufferInfo({
21
- width: this.width,
22
- height: this.height,
23
- type: this.type,
24
- dataPtr: this.dataPtr
25
- });
26
- switch (this.type) {
27
- case VideoBufferType.ARGB:
28
- case VideoBufferType.RGBA:
29
- case VideoBufferType.ABGR:
30
- case VideoBufferType.BGRA:
31
- info.stride = this.width * 4;
32
- break;
33
- case VideoBufferType.RGB24:
34
- info.stride = this.width * 3;
35
- break;
36
- default:
37
- info.stride = 0;
38
- }
39
- info.components.push(...getPlaneInfos(this.dataPtr, this.type, this.width, this.height));
40
- return info;
41
- }
42
- /** @internal */
43
- static fromOwnedInfo(owned) {
44
- const info = owned.info;
45
- const frame = new VideoFrame(
46
- FfiClient.instance.copyBuffer(
47
- info.dataPtr,
48
- getPlaneLength(info.type, info.width, info.height)
49
- ),
50
- info.width,
51
- info.height,
52
- info.type
53
- );
54
- new FfiHandle(owned.handle.id).dispose();
55
- return frame;
56
- }
57
- getPlane(planeNth) {
58
- const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height);
59
- if (planeNth >= planeInfos.length) return;
60
- const planeInfo = planeInfos[planeNth];
61
- return FfiClient.instance.copyBuffer(planeInfo.dataPtr, planeInfo.size);
62
- }
63
- convert(dstType, flipY = false) {
64
- const req = new FfiRequest({
65
- message: {
66
- case: "videoConvert",
67
- value: {
68
- flipY,
69
- dstType,
70
- buffer: this.protoInfo()
71
- }
72
- }
73
- });
74
- const resp = FfiClient.instance.request(req);
75
- switch (resp.message.case) {
76
- case "buffer":
77
- return VideoFrame.fromOwnedInfo(resp.message.value);
78
- case "error":
79
- default:
80
- throw resp.message.value;
81
- }
82
- }
83
- }
84
- const getPlaneLength = (type, width, height) => {
85
- const chromaWidth = Math.trunc((width + 1) / 2);
86
- const chromaHeight = Math.trunc((height + 1) / 2);
87
- switch (type) {
88
- case VideoBufferType.ARGB:
89
- case VideoBufferType.RGBA:
90
- case VideoBufferType.ABGR:
91
- case VideoBufferType.BGRA:
92
- return width * height * 4;
93
- case VideoBufferType.RGB24:
94
- case VideoBufferType.I444:
95
- return width * height * 3;
96
- case VideoBufferType.I420:
97
- return width * height + chromaWidth * chromaHeight * 2;
98
- case VideoBufferType.I420A:
99
- return width * height * 2 + chromaWidth * chromaWidth * 2;
100
- case VideoBufferType.I422:
101
- return width * height + chromaWidth * height * 2;
102
- case VideoBufferType.I010:
103
- return width * height * 2 + chromaWidth * chromaHeight * 4;
104
- case VideoBufferType.NV12:
105
- return width * height + chromaWidth * chromaWidth * 2;
106
- }
107
- };
108
- const getPlaneInfos = (dataPtr, type, width, height) => {
109
- const chromaWidth = Math.trunc((width + 1) / 2);
110
- const chromaHeight = Math.trunc((height + 1) / 2);
111
- switch (type) {
112
- case VideoBufferType.I420: {
113
- const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
114
- const u = new VideoBufferInfo_ComponentInfo({
115
- dataPtr: y.dataPtr + BigInt(y.size),
116
- stride: chromaWidth,
117
- size: chromaWidth * chromaHeight
118
- });
119
- const v = new VideoBufferInfo_ComponentInfo({
120
- dataPtr: u.dataPtr + BigInt(u.size),
121
- stride: chromaWidth,
122
- size: chromaWidth * chromaHeight
123
- });
124
- return [y, u, v];
125
- }
126
- case VideoBufferType.I420A: {
127
- const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
128
- const u = new VideoBufferInfo_ComponentInfo({
129
- dataPtr: y.dataPtr + BigInt(y.size),
130
- stride: chromaWidth,
131
- size: chromaWidth * chromaHeight
132
- });
133
- const v = new VideoBufferInfo_ComponentInfo({
134
- dataPtr: u.dataPtr + BigInt(u.size),
135
- stride: chromaWidth,
136
- size: chromaWidth * chromaHeight
137
- });
138
- const a = new VideoBufferInfo_ComponentInfo({
139
- dataPtr: v.dataPtr + BigInt(v.size),
140
- stride: width,
141
- size: width * height
142
- });
143
- return [y, u, v, a];
144
- }
145
- case VideoBufferType.I422: {
146
- const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
147
- const u = new VideoBufferInfo_ComponentInfo({
148
- dataPtr: y.dataPtr + BigInt(y.size),
149
- stride: chromaWidth,
150
- size: chromaWidth * height
151
- });
152
- const v = new VideoBufferInfo_ComponentInfo({
153
- dataPtr: u.dataPtr + BigInt(u.size),
154
- stride: chromaWidth,
155
- size: chromaWidth * height
156
- });
157
- return [y, u, v];
158
- }
159
- case VideoBufferType.I444: {
160
- const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
161
- const u = new VideoBufferInfo_ComponentInfo({
162
- dataPtr: y.dataPtr + BigInt(y.size),
163
- stride: width,
164
- size: width * height
165
- });
166
- const v = new VideoBufferInfo_ComponentInfo({
167
- dataPtr: u.dataPtr + BigInt(u.size),
168
- stride: width,
169
- size: width * height
170
- });
171
- return [y, u, v];
172
- }
173
- case VideoBufferType.I010: {
174
- const y = new VideoBufferInfo_ComponentInfo({
175
- dataPtr,
176
- stride: width * 2,
177
- size: width * height * 2
178
- });
179
- const u = new VideoBufferInfo_ComponentInfo({
180
- dataPtr: y.dataPtr + BigInt(y.size),
181
- stride: chromaWidth * 2,
182
- size: chromaWidth * chromaHeight * 2
183
- });
184
- const v = new VideoBufferInfo_ComponentInfo({
185
- dataPtr: u.dataPtr + BigInt(u.size),
186
- stride: chromaWidth * 2,
187
- size: chromaWidth * chromaHeight * 2
188
- });
189
- return [y, u, v];
190
- }
191
- case VideoBufferType.NV12: {
192
- const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });
193
- const uv = new VideoBufferInfo_ComponentInfo({
194
- dataPtr: y.dataPtr + BigInt(y.size),
195
- stride: chromaWidth * 2,
196
- size: chromaWidth * chromaHeight * 2
197
- });
198
- return [y, uv];
199
- }
200
- default:
201
- return [];
202
- }
203
- };
204
- export {
205
- VideoFrame
206
- };
207
- //# sourceMappingURL=video_frame.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/video_frame.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { OwnedVideoBuffer, VideoConvertResponse } from '@livekit/rtc-ffi-bindings';\nimport {\n VideoBufferInfo,\n VideoBufferInfo_ComponentInfo,\n VideoBufferType,\n} from '@livekit/rtc-ffi-bindings';\nimport { FfiClient, FfiHandle, FfiRequest } from './ffi_client.js';\n\nexport class VideoFrame {\n data: Uint8Array;\n width: number;\n height: number;\n type: VideoBufferType;\n\n constructor(data: Uint8Array, width: number, height: number, type: VideoBufferType) {\n this.data = data;\n this.width = width;\n this.height = height;\n this.type = type;\n }\n\n /** @internal */\n get dataPtr(): bigint {\n return FfiClient.instance.retrievePtr(new Uint8Array(this.data.buffer));\n }\n\n /** @internal */\n protoInfo(): VideoBufferInfo {\n const info = new VideoBufferInfo({\n width: this.width,\n height: this.height,\n type: this.type,\n dataPtr: this.dataPtr,\n });\n\n switch (this.type) {\n case VideoBufferType.ARGB:\n case VideoBufferType.RGBA:\n case VideoBufferType.ABGR:\n case VideoBufferType.BGRA:\n info.stride = this.width * 4;\n break;\n case VideoBufferType.RGB24:\n info.stride = this.width * 3;\n break;\n default:\n info.stride = 0;\n }\n\n info.components.push(...getPlaneInfos(this.dataPtr, this.type, this.width, this.height));\n\n return info;\n }\n\n /** @internal */\n static fromOwnedInfo(owned: OwnedVideoBuffer): VideoFrame {\n const info = owned.info!;\n const frame = new VideoFrame(\n FfiClient.instance.copyBuffer(\n info.dataPtr!,\n getPlaneLength(info.type!, info.width!, info.height!),\n ),\n info.width!,\n info.height!,\n info.type!,\n );\n // Dispose of the handle to prevent memory leaks\n new FfiHandle(owned.handle!.id!).dispose();\n return frame;\n }\n\n getPlane(planeNth: number): Uint8Array | void {\n const planeInfos = getPlaneInfos(this.dataPtr, this.type, this.width, this.height);\n if (planeNth >= planeInfos.length) return;\n\n const planeInfo = planeInfos[planeNth]!;\n return FfiClient.instance.copyBuffer(planeInfo.dataPtr!, planeInfo.size!);\n }\n\n convert(dstType: VideoBufferType, flipY = false): VideoFrame {\n const req = new FfiRequest({\n message: {\n case: 'videoConvert',\n value: {\n flipY,\n dstType,\n buffer: this.protoInfo(),\n },\n },\n });\n const resp = FfiClient.instance.request<VideoConvertResponse>(req);\n\n switch (resp.message.case) {\n case 'buffer':\n return VideoFrame.fromOwnedInfo(resp.message.value);\n case 'error':\n default:\n throw resp.message.value;\n }\n }\n}\n\nconst getPlaneLength = (type: VideoBufferType, width: number, height: number): number => {\n const chromaWidth = Math.trunc((width + 1) / 2);\n const chromaHeight = Math.trunc((height + 1) / 2);\n switch (type) {\n case VideoBufferType.ARGB:\n case VideoBufferType.RGBA:\n case VideoBufferType.ABGR:\n case VideoBufferType.BGRA:\n return width * height * 4;\n case VideoBufferType.RGB24:\n case VideoBufferType.I444:\n return width * height * 3;\n case VideoBufferType.I420:\n return width * height + chromaWidth * chromaHeight * 2;\n case VideoBufferType.I420A:\n return width * height * 2 + chromaWidth * chromaWidth * 2;\n case VideoBufferType.I422:\n return width * height + chromaWidth * height * 2;\n case VideoBufferType.I010:\n return width * height * 2 + chromaWidth * chromaHeight * 4;\n case VideoBufferType.NV12:\n return width * height + chromaWidth * chromaWidth * 2;\n }\n};\n\nconst getPlaneInfos = (\n dataPtr: bigint,\n type: VideoBufferType,\n width: number,\n height: number,\n): VideoBufferInfo_ComponentInfo[] => {\n const chromaWidth = Math.trunc((width + 1) / 2);\n const chromaHeight = Math.trunc((height + 1) / 2);\n switch (type) {\n case VideoBufferType.I420: {\n const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });\n const u = new VideoBufferInfo_ComponentInfo({\n dataPtr: y.dataPtr! + BigInt(y.size!),\n stride: chromaWidth,\n size: chromaWidth * chromaHeight,\n });\n const v = new VideoBufferInfo_ComponentInfo({\n dataPtr: u.dataPtr! + BigInt(u.size!),\n stride: chromaWidth,\n size: chromaWidth * chromaHeight,\n });\n return [y, u, v];\n }\n case VideoBufferType.I420A: {\n const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });\n const u = new VideoBufferInfo_ComponentInfo({\n dataPtr: y.dataPtr! + BigInt(y.size!),\n stride: chromaWidth,\n size: chromaWidth * chromaHeight,\n });\n const v = new VideoBufferInfo_ComponentInfo({\n dataPtr: u.dataPtr! + BigInt(u.size!),\n stride: chromaWidth,\n size: chromaWidth * chromaHeight,\n });\n const a = new VideoBufferInfo_ComponentInfo({\n dataPtr: v.dataPtr! + BigInt(v.size!),\n stride: width,\n size: width * height,\n });\n return [y, u, v, a];\n }\n case VideoBufferType.I422: {\n const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });\n const u = new VideoBufferInfo_ComponentInfo({\n dataPtr: y.dataPtr! + BigInt(y.size!),\n stride: chromaWidth,\n size: chromaWidth * height,\n });\n const v = new VideoBufferInfo_ComponentInfo({\n dataPtr: u.dataPtr! + BigInt(u.size!),\n stride: chromaWidth,\n size: chromaWidth * height,\n });\n return [y, u, v];\n }\n case VideoBufferType.I444: {\n const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });\n const u = new VideoBufferInfo_ComponentInfo({\n dataPtr: y.dataPtr! + BigInt(y.size!),\n stride: width,\n size: width * height,\n });\n const v = new VideoBufferInfo_ComponentInfo({\n dataPtr: u.dataPtr! + BigInt(u.size!),\n stride: width,\n size: width * height,\n });\n return [y, u, v];\n }\n case VideoBufferType.I010: {\n const y = new VideoBufferInfo_ComponentInfo({\n dataPtr,\n stride: width * 2,\n size: width * height * 2,\n });\n const u = new VideoBufferInfo_ComponentInfo({\n dataPtr: y.dataPtr! + BigInt(y.size!),\n stride: chromaWidth * 2,\n size: chromaWidth * chromaHeight * 2,\n });\n const v = new VideoBufferInfo_ComponentInfo({\n dataPtr: u.dataPtr! + BigInt(u.size!),\n stride: chromaWidth * 2,\n size: chromaWidth * chromaHeight * 2,\n });\n return [y, u, v];\n }\n case VideoBufferType.NV12: {\n const y = new VideoBufferInfo_ComponentInfo({ dataPtr, stride: width, size: width * height });\n const uv = new VideoBufferInfo_ComponentInfo({\n dataPtr: y.dataPtr! + BigInt(y.size!),\n stride: chromaWidth * 2,\n size: chromaWidth * chromaHeight * 2,\n });\n return [y, uv];\n }\n default:\n return [];\n }\n};\n"],"mappings":"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","names":[]}
@@ -1,53 +0,0 @@
1
- import {
2
- CaptureVideoFrameRequest,
3
- NewVideoSourceRequest,
4
- VideoRotation,
5
- VideoSourceType
6
- } from "@livekit/rtc-ffi-bindings";
7
- import { FfiClient, FfiHandle } from "./ffi_client.js";
8
- class VideoSource {
9
- constructor(width, height) {
10
- /** @internal */
11
- this.closed = false;
12
- var _a;
13
- this.width = width;
14
- this.height = height;
15
- const req = new NewVideoSourceRequest({
16
- type: VideoSourceType.VIDEO_SOURCE_NATIVE,
17
- resolution: {
18
- width,
19
- height
20
- }
21
- });
22
- const res = FfiClient.instance.request({
23
- message: {
24
- case: "newVideoSource",
25
- value: req
26
- }
27
- });
28
- this.info = (_a = res.source) == null ? void 0 : _a.info;
29
- this.ffiHandle = new FfiHandle(res.source.handle.id);
30
- }
31
- captureFrame(frame, timestampUs = BigInt(0), rotation = VideoRotation.VIDEO_ROTATION_0) {
32
- if (this.closed) {
33
- throw new Error("VideoSource is closed");
34
- }
35
- const req = new CaptureVideoFrameRequest({
36
- sourceHandle: this.ffiHandle.handle,
37
- buffer: frame.protoInfo(),
38
- rotation,
39
- timestampUs
40
- });
41
- FfiClient.instance.request({
42
- message: { case: "captureVideoFrame", value: req }
43
- });
44
- }
45
- async close() {
46
- this.ffiHandle.dispose();
47
- this.closed = true;
48
- }
49
- }
50
- export {
51
- VideoSource
52
- };
53
- //# sourceMappingURL=video_source.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/video_source.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type {\n CaptureVideoFrameResponse,\n NewVideoSourceResponse,\n VideoSourceInfo,\n} from '@livekit/rtc-ffi-bindings';\nimport {\n CaptureVideoFrameRequest,\n NewVideoSourceRequest,\n VideoRotation,\n VideoSourceType,\n} from '@livekit/rtc-ffi-bindings';\nimport { FfiClient, FfiHandle } from './ffi_client.js';\nimport type { VideoFrame } from './video_frame.js';\n\nexport class VideoSource {\n /** @internal */\n info?: VideoSourceInfo;\n /** @internal */\n ffiHandle: FfiHandle;\n /** @internal */\n closed = false;\n\n width: number;\n height: number;\n\n constructor(width: number, height: number) {\n this.width = width;\n this.height = height;\n\n const req = new NewVideoSourceRequest({\n type: VideoSourceType.VIDEO_SOURCE_NATIVE,\n resolution: {\n width: width,\n height: height,\n },\n });\n\n const res = FfiClient.instance.request<NewVideoSourceResponse>({\n message: {\n case: 'newVideoSource',\n value: req,\n },\n });\n\n this.info = res.source?.info;\n this.ffiHandle = new FfiHandle(res.source!.handle!.id!);\n }\n\n captureFrame(\n frame: VideoFrame,\n timestampUs = BigInt(0),\n rotation = VideoRotation.VIDEO_ROTATION_0,\n ) {\n if (this.closed) {\n throw new Error('VideoSource is closed');\n }\n const req = new CaptureVideoFrameRequest({\n sourceHandle: this.ffiHandle.handle,\n buffer: frame.protoInfo(),\n rotation,\n timestampUs,\n });\n\n FfiClient.instance.request<CaptureVideoFrameResponse>({\n message: { case: 'captureVideoFrame', value: req },\n });\n }\n\n async close() {\n this.ffiHandle.dispose();\n this.closed = true;\n }\n}\n"],"mappings":"AAQA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,iBAAiB;AAG9B,MAAM,YAAY;AAAA,EAWvB,YAAY,OAAe,QAAgB;AAL3C;AAAA,kBAAS;AAvBX;AA6BI,SAAK,QAAQ;AACb,SAAK,SAAS;AAEd,UAAM,MAAM,IAAI,sBAAsB;AAAA,MACpC,MAAM,gBAAgB;AAAA,MACtB,YAAY;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,MAAM,UAAU,SAAS,QAAgC;AAAA,MAC7D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,SAAK,QAAO,SAAI,WAAJ,mBAAY;AACxB,SAAK,YAAY,IAAI,UAAU,IAAI,OAAQ,OAAQ,EAAG;AAAA,EACxD;AAAA,EAEA,aACE,OACA,cAAc,OAAO,CAAC,GACtB,WAAW,cAAc,kBACzB;AACA,QAAI,KAAK,QAAQ;AACf,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AACA,UAAM,MAAM,IAAI,yBAAyB;AAAA,MACvC,cAAc,KAAK,UAAU;AAAA,MAC7B,QAAQ,MAAM,UAAU;AAAA,MACxB;AAAA,MACA;AAAA,IACF,CAAC;AAED,cAAU,SAAS,QAAmC;AAAA,MACpD,SAAS,EAAE,MAAM,qBAAqB,OAAO,IAAI;AAAA,IACnD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AACZ,SAAK,UAAU,QAAQ;AACvB,SAAK,SAAS;AAAA,EAChB;AACF;","names":[]}
@@ -1,70 +0,0 @@
1
- import { NewVideoStreamRequest, VideoStreamType } from "@livekit/rtc-ffi-bindings";
2
- import { FfiClient, FfiClientEvent, FfiHandle } from "./ffi_client.js";
3
- import { VideoFrame } from "./video_frame.js";
4
- class VideoStreamSource {
5
- constructor(track) {
6
- this.disposed = false;
7
- this.onEvent = (ev) => {
8
- if (!this.controller) {
9
- throw new Error("Stream controller not initialized");
10
- }
11
- if (ev.message.case != "videoStreamEvent" || ev.message.value.streamHandle != this.ffiHandle.handle) {
12
- return;
13
- }
14
- const streamEvent = ev.message.value.message;
15
- switch (streamEvent.case) {
16
- case "frameReceived":
17
- const rotation = streamEvent.value.rotation;
18
- const timestampUs = streamEvent.value.timestampUs;
19
- const frame = VideoFrame.fromOwnedInfo(streamEvent.value.buffer);
20
- const value = { rotation, timestampUs, frame };
21
- const videoFrameEvent = {
22
- frame: value.frame,
23
- timestampUs: value.timestampUs,
24
- rotation: value.rotation
25
- };
26
- this.controller.enqueue(videoFrameEvent);
27
- break;
28
- case "eos":
29
- FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);
30
- this.controller.close();
31
- if (!this.disposed) {
32
- this.disposed = true;
33
- this.ffiHandle.dispose();
34
- }
35
- break;
36
- }
37
- };
38
- const req = new NewVideoStreamRequest({
39
- type: VideoStreamType.VIDEO_STREAM_NATIVE,
40
- trackHandle: track.ffi_handle.handle
41
- });
42
- const res = FfiClient.instance.request({
43
- message: {
44
- case: "newVideoStream",
45
- value: req
46
- }
47
- });
48
- this.ffiHandle = new FfiHandle(res.stream.handle.id);
49
- FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);
50
- }
51
- start(controller) {
52
- this.controller = controller;
53
- }
54
- cancel() {
55
- FfiClient.instance.off(FfiClientEvent.FfiEvent, this.onEvent);
56
- if (!this.disposed) {
57
- this.disposed = true;
58
- this.ffiHandle.dispose();
59
- }
60
- }
61
- }
62
- class VideoStream extends ReadableStream {
63
- constructor(track) {
64
- super(new VideoStreamSource(track));
65
- }
66
- }
67
- export {
68
- VideoStream
69
- };
70
- //# sourceMappingURL=video_stream.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/video_stream.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2024 LiveKit, Inc.\n//\n// SPDX-License-Identifier: Apache-2.0\nimport type { NewVideoStreamResponse, VideoRotation } from '@livekit/rtc-ffi-bindings';\nimport { NewVideoStreamRequest, VideoStreamType } from '@livekit/rtc-ffi-bindings';\nimport type { UnderlyingSource } from 'node:stream/web';\nimport type { FfiEvent } from './ffi_client.js';\nimport { FfiClient, FfiClientEvent, FfiHandle } from './ffi_client.js';\nimport type { Track } from './track.js';\nimport { VideoFrame } from './video_frame.js';\n\nexport type VideoFrameEvent = {\n frame: VideoFrame;\n timestampUs: bigint;\n rotation: VideoRotation;\n};\n\nclass VideoStreamSource implements UnderlyingSource<VideoFrameEvent> {\n private controller?: ReadableStreamDefaultController<VideoFrameEvent>;\n private ffiHandle: FfiHandle;\n private disposed = false;\n\n constructor(track: Track) {\n const req = new NewVideoStreamRequest({\n type: VideoStreamType.VIDEO_STREAM_NATIVE,\n trackHandle: track.ffi_handle.handle,\n });\n\n const res = FfiClient.instance.request<NewVideoStreamResponse>({\n message: {\n case: 'newVideoStream',\n value: req,\n },\n });\n\n this.ffiHandle = new FfiHandle(res.stream!.handle!.id!);\n FfiClient.instance.on(FfiClientEvent.FfiEvent, this.onEvent);\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 != 'videoStreamEvent' ||\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 const rotation = streamEvent.value.rotation;\n const timestampUs = streamEvent.value.timestampUs;\n const frame = VideoFrame.fromOwnedInfo(streamEvent.value.buffer!);\n const value = { rotation, timestampUs, frame };\n const videoFrameEvent = {\n frame: value.frame,\n timestampUs: value.timestampUs!,\n rotation: value.rotation!,\n };\n this.controller.enqueue(videoFrameEvent);\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.ffiHandle.dispose();\n }\n break;\n }\n };\n\n start(controller: ReadableStreamDefaultController<VideoFrameEvent>) {\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.ffiHandle.dispose();\n }\n }\n}\n\nexport class VideoStream extends ReadableStream<VideoFrameEvent> {\n constructor(track: Track) {\n super(new VideoStreamSource(track));\n }\n}\n"],"mappings":"AAIA,SAAS,uBAAuB,uBAAuB;AAGvD,SAAS,WAAW,gBAAgB,iBAAiB;AAErD,SAAS,kBAAkB;AAQ3B,MAAM,kBAA+D;AAAA,EAKnE,YAAY,OAAc;AAF1B,SAAQ,WAAW;AAmBnB,SAAQ,UAAU,CAAC,OAAiB;AAClC,UAAI,CAAC,KAAK,YAAY;AACpB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,UACE,GAAG,QAAQ,QAAQ,sBACnB,GAAG,QAAQ,MAAM,gBAAgB,KAAK,UAAU,QAChD;AACA;AAAA,MACF;AAEA,YAAM,cAAc,GAAG,QAAQ,MAAM;AACrC,cAAQ,YAAY,MAAM;AAAA,QACxB,KAAK;AACH,gBAAM,WAAW,YAAY,MAAM;AACnC,gBAAM,cAAc,YAAY,MAAM;AACtC,gBAAM,QAAQ,WAAW,cAAc,YAAY,MAAM,MAAO;AAChE,gBAAM,QAAQ,EAAE,UAAU,aAAa,MAAM;AAC7C,gBAAM,kBAAkB;AAAA,YACtB,OAAO,MAAM;AAAA,YACb,aAAa,MAAM;AAAA,YACnB,UAAU,MAAM;AAAA,UAClB;AACA,eAAK,WAAW,QAAQ,eAAe;AACvC;AAAA,QACF,KAAK;AACH,oBAAU,SAAS,IAAI,eAAe,UAAU,KAAK,OAAO;AAC5D,eAAK,WAAW,MAAM;AAKtB,cAAI,CAAC,KAAK,UAAU;AAClB,iBAAK,WAAW;AAChB,iBAAK,UAAU,QAAQ;AAAA,UACzB;AACA;AAAA,MACJ;AAAA,IACF;AAvDE,UAAM,MAAM,IAAI,sBAAsB;AAAA,MACpC,MAAM,gBAAgB;AAAA,MACtB,aAAa,MAAM,WAAW;AAAA,IAChC,CAAC;AAED,UAAM,MAAM,UAAU,SAAS,QAAgC;AAAA,MAC7D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,SAAK,YAAY,IAAI,UAAU,IAAI,OAAQ,OAAQ,EAAG;AACtD,cAAU,SAAS,GAAG,eAAe,UAAU,KAAK,OAAO;AAAA,EAC7D;AAAA,EA2CA,MAAM,YAA8D;AAClE,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,SAAS;AACP,cAAU,SAAS,IAAI,eAAe,UAAU,KAAK,OAAO;AAC5D,QAAI,CAAC,KAAK,UAAU;AAClB,WAAK,WAAW;AAChB,WAAK,UAAU,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;AAEO,MAAM,oBAAoB,eAAgC;AAAA,EAC/D,YAAY,OAAc;AACxB,UAAM,IAAI,kBAAkB,KAAK,CAAC;AAAA,EACpC;AACF;","names":[]}