@nonstrict/recordkit 0.52.0 → 0.53.1
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/bin/README.md +1 -1
- package/bin/recordkit-rpc +0 -0
- package/out/RecordKit.d.ts +1 -2
- package/out/RecordKit.js +1 -1
- package/out/Recorder.d.ts +73 -4
- package/out/Recorder.js +94 -1
- package/out/Recorder.js.map +1 -1
- package/out/WebAudioUtils.d.ts +31 -0
- package/out/WebAudioUtils.js +95 -0
- package/out/WebAudioUtils.js.map +1 -0
- package/out/browser.d.ts +2 -0
- package/out/browser.js +4 -0
- package/out/browser.js.map +1 -0
- package/out/index.cjs +96 -3
- package/out/index.cjs.map +1 -1
- package/package.json +6 -3
- package/src/RecordKit.ts +24 -24
- package/src/Recorder.ts +177 -2
- package/src/WebAudioUtils.ts +108 -0
- package/src/browser.ts +7 -0
- package/tsconfig.json +2 -1
package/bin/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# recordkit-rpc 0.
|
|
1
|
+
# recordkit-rpc 0.53.1
|
package/bin/recordkit-rpc
CHANGED
|
Binary file
|
package/out/RecordKit.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
3
2
|
import { Recorder, RecorderSchemaItem } from "./Recorder.js";
|
|
4
|
-
import { EventEmitter } from "
|
|
3
|
+
import { EventEmitter } from "events";
|
|
5
4
|
/**
|
|
6
5
|
* Entry point for the RecordKit SDK, an instance is available as `recordkit` that can be imported from the module. Do not instantiate this class directly.
|
|
7
6
|
*
|
package/out/RecordKit.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IpcRecordKit } from "./IpcRecordKit.js";
|
|
2
2
|
import { Recorder } from "./Recorder.js";
|
|
3
|
-
import { EventEmitter } from "
|
|
3
|
+
import { EventEmitter } from "events";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
/**
|
|
6
6
|
* Entry point for the RecordKit SDK, an instance is available as `recordkit` that can be imported from the module. Do not instantiate this class directly.
|
package/out/Recorder.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
3
2
|
import { NSRPC } from "./NonstrictRPC.js";
|
|
4
|
-
import { EventEmitter } from "
|
|
3
|
+
import { EventEmitter } from "events";
|
|
5
4
|
import { AppleDevice, Camera, Display, Microphone, Window } from "./RecordKit.js";
|
|
6
5
|
/**
|
|
7
6
|
* @group Recording
|
|
@@ -27,7 +26,7 @@ export declare class Recorder extends EventEmitter {
|
|
|
27
26
|
/**
|
|
28
27
|
* @group Recording
|
|
29
28
|
*/
|
|
30
|
-
export type RecorderSchemaItem = WebcamSchema | DisplaySchema | WindowBasedCropSchema | AppleDeviceStaticOrientationSchema | SystemAudioSchema | ApplicationAudioSchema;
|
|
29
|
+
export type RecorderSchemaItem = WebcamSchema | DisplaySchema | WindowBasedCropSchema | AppleDeviceStaticOrientationSchema | SystemAudioSchema | ApplicationAudioSchema | MicrophoneSchema;
|
|
31
30
|
/**
|
|
32
31
|
* Creates a recorder item for a webcam movie file, using the provided microphone and camera. Output is stored in a RecordKit bundle.
|
|
33
32
|
*
|
|
@@ -113,7 +112,11 @@ export type SystemAudioBackend = 'screenCaptureKit' | '_beta_coreAudio';
|
|
|
113
112
|
/**
|
|
114
113
|
* @group Recording Schemas
|
|
115
114
|
*/
|
|
116
|
-
export type AudioOutputOptionsType = 'singleFile' | 'segmented';
|
|
115
|
+
export type AudioOutputOptionsType = 'singleFile' | 'segmented' | 'stream';
|
|
116
|
+
/**
|
|
117
|
+
* @group Recording Schemas
|
|
118
|
+
*/
|
|
119
|
+
export type MicrophoneOutputOptionsType = 'singleFile' | 'segmented' | 'stream';
|
|
117
120
|
/**
|
|
118
121
|
* Creates a recorder item for recording system audio. By default current process audio is excluded. Output is stored in a RecordKit bundle.
|
|
119
122
|
*
|
|
@@ -139,6 +142,15 @@ export type SystemAudioSchema = {
|
|
|
139
142
|
output: 'segmented';
|
|
140
143
|
filenamePrefix?: string;
|
|
141
144
|
segmentCallback?: (url: string) => void;
|
|
145
|
+
} | {
|
|
146
|
+
type: 'systemAudio';
|
|
147
|
+
mode: 'exclude';
|
|
148
|
+
backend?: SystemAudioBackend;
|
|
149
|
+
excludeOptions?: ('currentProcess')[];
|
|
150
|
+
excludedProcessIDs?: number[];
|
|
151
|
+
output: 'stream';
|
|
152
|
+
/** Called with real-time audio buffer data compatible with Web Audio API. Requires _beta_coreAudio backend and macOS 14.2+ */
|
|
153
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void;
|
|
142
154
|
} | {
|
|
143
155
|
type: 'systemAudio';
|
|
144
156
|
mode: 'include';
|
|
@@ -154,6 +166,14 @@ export type SystemAudioSchema = {
|
|
|
154
166
|
output: 'segmented';
|
|
155
167
|
filenamePrefix?: string;
|
|
156
168
|
segmentCallback?: (url: string) => void;
|
|
169
|
+
} | {
|
|
170
|
+
type: 'systemAudio';
|
|
171
|
+
mode: 'include';
|
|
172
|
+
backend?: SystemAudioBackend;
|
|
173
|
+
includedApplicationIDs?: number[];
|
|
174
|
+
output: 'stream';
|
|
175
|
+
/** Called with real-time audio buffer data compatible with Web Audio API. Requires _beta_coreAudio backend and macOS 14.2+ */
|
|
176
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void;
|
|
157
177
|
};
|
|
158
178
|
/**
|
|
159
179
|
* Creates a recorder item for recording the audio of a single application. Output is stored in a RecordKit bundle.
|
|
@@ -173,7 +193,56 @@ export type ApplicationAudioSchema = {
|
|
|
173
193
|
output: 'segmented';
|
|
174
194
|
filenamePrefix?: string;
|
|
175
195
|
segmentCallback?: (url: string) => void;
|
|
196
|
+
} | {
|
|
197
|
+
type: 'applicationAudio';
|
|
198
|
+
applicationID: number;
|
|
199
|
+
backend?: SystemAudioBackend;
|
|
200
|
+
output: 'stream';
|
|
201
|
+
/** Called with real-time audio buffer data compatible with Web Audio API. Requires _beta_coreAudio backend and macOS 14.2+ */
|
|
202
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void;
|
|
176
203
|
};
|
|
204
|
+
/**
|
|
205
|
+
* Creates a recorder item for an audio file, using the provided microphone. Output is stored in a RecordKit bundle.
|
|
206
|
+
*
|
|
207
|
+
* @group Recording Schemas
|
|
208
|
+
*/
|
|
209
|
+
export type MicrophoneSchema = {
|
|
210
|
+
type: 'microphone';
|
|
211
|
+
microphone: Microphone | string;
|
|
212
|
+
leftChannelOnly?: boolean;
|
|
213
|
+
audioDelay?: number;
|
|
214
|
+
output?: 'singleFile';
|
|
215
|
+
filename?: string;
|
|
216
|
+
} | {
|
|
217
|
+
type: 'microphone';
|
|
218
|
+
microphone: Microphone | string;
|
|
219
|
+
leftChannelOnly?: boolean;
|
|
220
|
+
audioDelay?: number;
|
|
221
|
+
output: 'segmented';
|
|
222
|
+
filenamePrefix?: string;
|
|
223
|
+
segmentCallback?: (url: string) => void;
|
|
224
|
+
} | {
|
|
225
|
+
type: 'microphone';
|
|
226
|
+
microphone: Microphone | string;
|
|
227
|
+
output: 'stream';
|
|
228
|
+
/** Called with real-time audio buffer data compatible with Web Audio API */
|
|
229
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Audio buffer compatible with Web Audio API
|
|
233
|
+
*
|
|
234
|
+
* @group Recording
|
|
235
|
+
*/
|
|
236
|
+
export interface AudioStreamBuffer {
|
|
237
|
+
/** Sample rate in Hz (e.g., 44100, 48000) */
|
|
238
|
+
sampleRate: number;
|
|
239
|
+
/** Number of audio channels */
|
|
240
|
+
numberOfChannels: number;
|
|
241
|
+
/** Number of frames per channel */
|
|
242
|
+
numberOfFrames: number;
|
|
243
|
+
/** Non-interleaved Float32 audio data - one array per channel */
|
|
244
|
+
channelData: Float32Array[];
|
|
245
|
+
}
|
|
177
246
|
/**
|
|
178
247
|
* @group Recording
|
|
179
248
|
*/
|
package/out/Recorder.js
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { randomUUID } from "crypto";
|
|
2
|
-
import { EventEmitter } from "
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
/**
|
|
4
|
+
* Converts RPC audio buffer data to AudioStreamBuffer format
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
function convertRPCParamsToAudioStreamBuffer(params) {
|
|
8
|
+
try {
|
|
9
|
+
// params is the AudioBufferData directly from Swift
|
|
10
|
+
const rawAudioBuffer = params;
|
|
11
|
+
if (!rawAudioBuffer || !Array.isArray(rawAudioBuffer.channelData)) {
|
|
12
|
+
console.error('RecordKit: Invalid audio buffer received from RPC');
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const channelData = [];
|
|
16
|
+
for (const base64Data of rawAudioBuffer.channelData) {
|
|
17
|
+
if (typeof base64Data !== 'string') {
|
|
18
|
+
console.error('RecordKit: Invalid base64 data received');
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
// Decode base64 to binary data
|
|
22
|
+
const binaryString = atob(base64Data);
|
|
23
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
24
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
25
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
26
|
+
}
|
|
27
|
+
// Convert bytes to Float32Array
|
|
28
|
+
const float32Array = new Float32Array(bytes.buffer);
|
|
29
|
+
channelData.push(float32Array);
|
|
30
|
+
}
|
|
31
|
+
const audioStreamBuffer = {
|
|
32
|
+
sampleRate: rawAudioBuffer.sampleRate,
|
|
33
|
+
numberOfChannels: rawAudioBuffer.numberOfChannels,
|
|
34
|
+
numberOfFrames: rawAudioBuffer.numberOfFrames,
|
|
35
|
+
channelData: channelData
|
|
36
|
+
};
|
|
37
|
+
return audioStreamBuffer;
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error('RecordKit: Error processing audio stream buffer:', error);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
3
44
|
/**
|
|
4
45
|
* @group Recording
|
|
5
46
|
*/
|
|
@@ -59,6 +100,19 @@ export class Recorder extends EventEmitter {
|
|
|
59
100
|
lifecycle: object
|
|
60
101
|
});
|
|
61
102
|
}
|
|
103
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
104
|
+
const streamHandler = item.streamCallback;
|
|
105
|
+
item.streamCallback = rpc.registerClosure({
|
|
106
|
+
handler: (params) => {
|
|
107
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
108
|
+
if (audioBuffer) {
|
|
109
|
+
streamHandler(audioBuffer);
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
prefix: 'SystemAudioStream.onAudioBuffer',
|
|
113
|
+
lifecycle: object
|
|
114
|
+
});
|
|
115
|
+
}
|
|
62
116
|
}
|
|
63
117
|
if (item.type == 'applicationAudio') {
|
|
64
118
|
if (item.output == 'segmented' && item.segmentCallback) {
|
|
@@ -69,6 +123,45 @@ export class Recorder extends EventEmitter {
|
|
|
69
123
|
lifecycle: object
|
|
70
124
|
});
|
|
71
125
|
}
|
|
126
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
127
|
+
const streamHandler = item.streamCallback;
|
|
128
|
+
item.streamCallback = rpc.registerClosure({
|
|
129
|
+
handler: (params) => {
|
|
130
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
131
|
+
if (audioBuffer) {
|
|
132
|
+
streamHandler(audioBuffer);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
prefix: 'ApplicationAudioStream.onAudioBuffer',
|
|
136
|
+
lifecycle: object
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (item.type == 'microphone') {
|
|
141
|
+
if (typeof item.microphone != 'string') {
|
|
142
|
+
item.microphone = item.microphone.id;
|
|
143
|
+
}
|
|
144
|
+
if (item.output == 'segmented' && item.segmentCallback) {
|
|
145
|
+
const segmentHandler = item.segmentCallback;
|
|
146
|
+
item.segmentCallback = rpc.registerClosure({
|
|
147
|
+
handler: (params) => { segmentHandler(params.path); },
|
|
148
|
+
prefix: 'Microphone.onSegment',
|
|
149
|
+
lifecycle: object
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
153
|
+
const streamHandler = item.streamCallback;
|
|
154
|
+
item.streamCallback = rpc.registerClosure({
|
|
155
|
+
handler: (params) => {
|
|
156
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
157
|
+
if (audioBuffer) {
|
|
158
|
+
streamHandler(audioBuffer);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
prefix: 'MicrophoneStream.onAudioBuffer',
|
|
162
|
+
lifecycle: object
|
|
163
|
+
});
|
|
164
|
+
}
|
|
72
165
|
}
|
|
73
166
|
});
|
|
74
167
|
const weakRefObject = new WeakRef(object);
|
package/out/Recorder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Recorder.js","sourceRoot":"","sources":["../src/Recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,YAAY;IACvB,GAAG,CAAQ;IACX,MAAM,CAAS;IAEhC,cAAc;IACd,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAU,EAAE,MAMpC;QACC,MAAM,MAAM,GAAG,WAAW,GAAG,UAAU,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAEzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC1B,IAAI,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC1B,IAAI,OAAO,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;oBACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;gBAC9B,CAAC;gBACD,IAAI,OAAO,IAAI,CAAC,UAAU,IAAI,QAAQ,EAAE,CAAC;oBACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAA;gBACtC,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC3B,IAAI,OAAO,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC;oBACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;gBAChC,CAAC;gBACD,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;oBAC3C,IAAY,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;wBAClD,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,IAAc,CAAC,CAAA,CAAC,CAAC;wBAC9D,MAAM,EAAE,mBAAmB;wBAC3B,SAAS,EAAE,MAAM;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,IAAI,iBAAiB,EAAE,CAAC;gBACnC,IAAI,OAAO,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;oBACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;gBAC9B,CAAC;gBACD,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;oBAC3C,IAAY,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;wBAClD,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,IAAc,CAAC,CAAA,CAAC,CAAC;wBAC9D,MAAM,EAAE,kBAAkB;wBAC1B,SAAS,EAAE,MAAM;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,IAAI,8BAA8B,EAAE,CAAC;gBAChD,IAAI,OAAO,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;oBACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;gBAC9B,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;oBAC3C,IAAY,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;wBAClD,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,IAAc,CAAC,CAAA,CAAC,CAAC;wBAC9D,MAAM,EAAE,uBAAuB;wBAC/B,SAAS,EAAE,MAAM;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,IAAI,kBAAkB,EAAE,CAAC;gBACpC,IAAI,IAAI,CAAC,MAAM,IAAI,WAAW,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;oBAC3C,IAAY,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;wBAClD,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,IAAc,CAAC,CAAA,CAAC,CAAC;wBAC9D,MAAM,EAAE,4BAA4B;wBACpC,SAAS,EAAE,MAAM;qBAClB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;YAC1C,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,aAAa,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAqB,CAAC,CAAA,CAAC,CAAC;YAC3F,MAAM,EAAE,kBAAkB;YAC1B,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QAEH,MAAM,GAAG,CAAC,UAAU,CAAC;YACnB,MAAM;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE;YACnC,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QAEH,OAAO,MAAM,CAAA;IACf,CAAC;IAED,cAAc;IACd,YAAY,GAAU,EAAE,MAAc;QACpC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAoB,CAAC;IAC5F,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3C,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"Recorder.js","sourceRoot":"","sources":["../src/Recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AudioStreamBuffer } from './Recorder.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Web Audio API AudioBuffer from a RecordKit AudioStreamBuffer.
|
|
4
|
+
*
|
|
5
|
+
* This utility converts RecordKit's streaming audio format to the standard Web Audio API format,
|
|
6
|
+
* handling various edge cases and IPC serialization issues that may occur in Electron environments.
|
|
7
|
+
*
|
|
8
|
+
* @param audioStreamBuffer - The RecordKit AudioStreamBuffer to convert
|
|
9
|
+
* @param audioContext - The Web Audio API AudioContext to use for buffer creation
|
|
10
|
+
* @returns The created AudioBuffer, or null if conversion failed
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { createWebAudioBuffer } from '@nonstrict/recordkit';
|
|
15
|
+
*
|
|
16
|
+
* // In your stream callback
|
|
17
|
+
* const streamCallback = (audioBuffer: AudioStreamBuffer) => {
|
|
18
|
+
* const audioContext = new AudioContext();
|
|
19
|
+
* const webAudioBuffer = createWebAudioBuffer(audioBuffer, audioContext);
|
|
20
|
+
*
|
|
21
|
+
* if (webAudioBuffer) {
|
|
22
|
+
* // Use the buffer with Web Audio API
|
|
23
|
+
* const source = audioContext.createBufferSource();
|
|
24
|
+
* source.buffer = webAudioBuffer;
|
|
25
|
+
* source.connect(audioContext.destination);
|
|
26
|
+
* source.start();
|
|
27
|
+
* }
|
|
28
|
+
* };
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function createWebAudioBuffer(audioStreamBuffer: AudioStreamBuffer, audioContext: AudioContext): AudioBuffer | null;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a Web Audio API AudioBuffer from a RecordKit AudioStreamBuffer.
|
|
3
|
+
*
|
|
4
|
+
* This utility converts RecordKit's streaming audio format to the standard Web Audio API format,
|
|
5
|
+
* handling various edge cases and IPC serialization issues that may occur in Electron environments.
|
|
6
|
+
*
|
|
7
|
+
* @param audioStreamBuffer - The RecordKit AudioStreamBuffer to convert
|
|
8
|
+
* @param audioContext - The Web Audio API AudioContext to use for buffer creation
|
|
9
|
+
* @returns The created AudioBuffer, or null if conversion failed
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { createWebAudioBuffer } from '@nonstrict/recordkit';
|
|
14
|
+
*
|
|
15
|
+
* // In your stream callback
|
|
16
|
+
* const streamCallback = (audioBuffer: AudioStreamBuffer) => {
|
|
17
|
+
* const audioContext = new AudioContext();
|
|
18
|
+
* const webAudioBuffer = createWebAudioBuffer(audioBuffer, audioContext);
|
|
19
|
+
*
|
|
20
|
+
* if (webAudioBuffer) {
|
|
21
|
+
* // Use the buffer with Web Audio API
|
|
22
|
+
* const source = audioContext.createBufferSource();
|
|
23
|
+
* source.buffer = webAudioBuffer;
|
|
24
|
+
* source.connect(audioContext.destination);
|
|
25
|
+
* source.start();
|
|
26
|
+
* }
|
|
27
|
+
* };
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function createWebAudioBuffer(audioStreamBuffer, audioContext) {
|
|
31
|
+
// Input validation
|
|
32
|
+
if (!audioStreamBuffer || typeof audioStreamBuffer !== 'object') {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (!audioContext || typeof audioContext.createBuffer !== 'function') {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const { sampleRate, numberOfChannels, numberOfFrames, channelData } = audioStreamBuffer;
|
|
40
|
+
// Validate required properties
|
|
41
|
+
if (typeof sampleRate !== 'number' || sampleRate <= 0 || sampleRate > 192000) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (typeof numberOfChannels !== 'number' || numberOfChannels <= 0 || numberOfChannels > 32) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
if (typeof numberOfFrames !== 'number' || numberOfFrames <= 0 || numberOfFrames > 1048576) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (!Array.isArray(channelData) || channelData.length !== numberOfChannels) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
// Validate channel data arrays
|
|
54
|
+
for (let i = 0; i < numberOfChannels; i++) {
|
|
55
|
+
const channel = channelData[i];
|
|
56
|
+
if (!channel || (!Array.isArray(channel) && !(channel instanceof Float32Array))) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
// Check length matches expected frame count
|
|
60
|
+
if (channel.length !== numberOfFrames) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Create Web Audio AudioBuffer
|
|
65
|
+
const audioBuffer = audioContext.createBuffer(numberOfChannels, numberOfFrames, sampleRate);
|
|
66
|
+
// Copy channel data to AudioBuffer
|
|
67
|
+
for (let channel = 0; channel < numberOfChannels; channel++) {
|
|
68
|
+
const outputArray = audioBuffer.getChannelData(channel);
|
|
69
|
+
const inputArray = channelData[channel];
|
|
70
|
+
// Handle both Float32Array and regular arrays (from Electron IPC serialization)
|
|
71
|
+
if (inputArray instanceof Float32Array) {
|
|
72
|
+
// Direct copy for Float32Array
|
|
73
|
+
outputArray.set(inputArray);
|
|
74
|
+
}
|
|
75
|
+
else if (Array.isArray(inputArray)) {
|
|
76
|
+
// Convert regular array to Float32Array for better performance
|
|
77
|
+
const float32Array = new Float32Array(inputArray);
|
|
78
|
+
outputArray.set(float32Array);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// Fallback: manual copy with type conversion
|
|
82
|
+
for (let i = 0; i < numberOfFrames; i++) {
|
|
83
|
+
const sample = inputArray[i];
|
|
84
|
+
outputArray[i] = typeof sample === 'number' && isFinite(sample) ? sample : 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return audioBuffer;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
// Return null for any conversion failures - don't throw in streaming contexts
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=WebAudioUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebAudioUtils.js","sourceRoot":"","sources":["../src/WebAudioUtils.ts"],"names":[],"mappings":"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"}
|
package/out/browser.d.ts
ADDED
package/out/browser.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,2FAA2F;AAE3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/out/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var node_child_process = require('node:child_process');
|
|
4
4
|
var readline = require('readline');
|
|
5
5
|
var crypto = require('crypto');
|
|
6
|
-
var
|
|
6
|
+
var events = require('events');
|
|
7
7
|
var node_fs = require('node:fs');
|
|
8
8
|
|
|
9
9
|
function _interopNamespaceDefault(e) {
|
|
@@ -244,10 +244,51 @@ class IpcRecordKit {
|
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Converts RPC audio buffer data to AudioStreamBuffer format
|
|
249
|
+
* @internal
|
|
250
|
+
*/
|
|
251
|
+
function convertRPCParamsToAudioStreamBuffer(params) {
|
|
252
|
+
try {
|
|
253
|
+
// params is the AudioBufferData directly from Swift
|
|
254
|
+
const rawAudioBuffer = params;
|
|
255
|
+
if (!rawAudioBuffer || !Array.isArray(rawAudioBuffer.channelData)) {
|
|
256
|
+
console.error('RecordKit: Invalid audio buffer received from RPC');
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const channelData = [];
|
|
260
|
+
for (const base64Data of rawAudioBuffer.channelData) {
|
|
261
|
+
if (typeof base64Data !== 'string') {
|
|
262
|
+
console.error('RecordKit: Invalid base64 data received');
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
// Decode base64 to binary data
|
|
266
|
+
const binaryString = atob(base64Data);
|
|
267
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
268
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
269
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
270
|
+
}
|
|
271
|
+
// Convert bytes to Float32Array
|
|
272
|
+
const float32Array = new Float32Array(bytes.buffer);
|
|
273
|
+
channelData.push(float32Array);
|
|
274
|
+
}
|
|
275
|
+
const audioStreamBuffer = {
|
|
276
|
+
sampleRate: rawAudioBuffer.sampleRate,
|
|
277
|
+
numberOfChannels: rawAudioBuffer.numberOfChannels,
|
|
278
|
+
numberOfFrames: rawAudioBuffer.numberOfFrames,
|
|
279
|
+
channelData: channelData
|
|
280
|
+
};
|
|
281
|
+
return audioStreamBuffer;
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
console.error('RecordKit: Error processing audio stream buffer:', error);
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
247
288
|
/**
|
|
248
289
|
* @group Recording
|
|
249
290
|
*/
|
|
250
|
-
class Recorder extends
|
|
291
|
+
class Recorder extends events.EventEmitter {
|
|
251
292
|
rpc;
|
|
252
293
|
target;
|
|
253
294
|
/** @ignore */
|
|
@@ -303,6 +344,19 @@ class Recorder extends stream.EventEmitter {
|
|
|
303
344
|
lifecycle: object
|
|
304
345
|
});
|
|
305
346
|
}
|
|
347
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
348
|
+
const streamHandler = item.streamCallback;
|
|
349
|
+
item.streamCallback = rpc.registerClosure({
|
|
350
|
+
handler: (params) => {
|
|
351
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
352
|
+
if (audioBuffer) {
|
|
353
|
+
streamHandler(audioBuffer);
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
prefix: 'SystemAudioStream.onAudioBuffer',
|
|
357
|
+
lifecycle: object
|
|
358
|
+
});
|
|
359
|
+
}
|
|
306
360
|
}
|
|
307
361
|
if (item.type == 'applicationAudio') {
|
|
308
362
|
if (item.output == 'segmented' && item.segmentCallback) {
|
|
@@ -313,6 +367,45 @@ class Recorder extends stream.EventEmitter {
|
|
|
313
367
|
lifecycle: object
|
|
314
368
|
});
|
|
315
369
|
}
|
|
370
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
371
|
+
const streamHandler = item.streamCallback;
|
|
372
|
+
item.streamCallback = rpc.registerClosure({
|
|
373
|
+
handler: (params) => {
|
|
374
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
375
|
+
if (audioBuffer) {
|
|
376
|
+
streamHandler(audioBuffer);
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
prefix: 'ApplicationAudioStream.onAudioBuffer',
|
|
380
|
+
lifecycle: object
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (item.type == 'microphone') {
|
|
385
|
+
if (typeof item.microphone != 'string') {
|
|
386
|
+
item.microphone = item.microphone.id;
|
|
387
|
+
}
|
|
388
|
+
if (item.output == 'segmented' && item.segmentCallback) {
|
|
389
|
+
const segmentHandler = item.segmentCallback;
|
|
390
|
+
item.segmentCallback = rpc.registerClosure({
|
|
391
|
+
handler: (params) => { segmentHandler(params.path); },
|
|
392
|
+
prefix: 'Microphone.onSegment',
|
|
393
|
+
lifecycle: object
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
397
|
+
const streamHandler = item.streamCallback;
|
|
398
|
+
item.streamCallback = rpc.registerClosure({
|
|
399
|
+
handler: (params) => {
|
|
400
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
401
|
+
if (audioBuffer) {
|
|
402
|
+
streamHandler(audioBuffer);
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
prefix: 'MicrophoneStream.onAudioBuffer',
|
|
406
|
+
lifecycle: object
|
|
407
|
+
});
|
|
408
|
+
}
|
|
316
409
|
}
|
|
317
410
|
});
|
|
318
411
|
const weakRefObject = new WeakRef(object);
|
|
@@ -361,7 +454,7 @@ class Recorder extends stream.EventEmitter {
|
|
|
361
454
|
* @groupDescription Logging
|
|
362
455
|
* Log what's going on to the console for easy debugging and troubleshooting.
|
|
363
456
|
*/
|
|
364
|
-
class RecordKit extends
|
|
457
|
+
class RecordKit extends events.EventEmitter {
|
|
365
458
|
ipcRecordKit = new IpcRecordKit();
|
|
366
459
|
/** @ignore */
|
|
367
460
|
constructor() {
|
package/out/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["finalizationRegistry.js","NonstrictRPC.js","IpcRecordKit.js","Recorder.js","RecordKit.js"],"sourcesContent":["export const finalizationRegistry = new FinalizationRegistry(async (destructor) => { await destructor(); });\n//# sourceMappingURL=finalizationRegistry.js.map","import { randomUUID } from \"crypto\";\nimport { finalizationRegistry } from \"./finalizationRegistry.js\";\nexport class NSRPC {\n logMessages = false;\n send;\n responseHandlers = new Map();\n closureTargets = new Map();\n constructor(send) {\n this.send = send;\n }\n receive(data) {\n // TODO: For now we just assume the message is a valid NSRPC message, but we should:\n // - Check if the nsrpc property is set to a number in the range of 1..<2\n // - Validate the message against the defined interfaces above\n let message;\n try {\n if (this.logMessages) {\n console.log(\"RecordKit: [RPC] <\", data.trimEnd());\n }\n message = JSON.parse(data);\n }\n catch (error) {\n if (this.logMessages) {\n console.error(\"RecordKit: [RPC] !! Above message is invalid JSON, will be ignored.\");\n }\n return;\n }\n if (\"status\" in message) {\n // This is a response, dispatch it so it can be handled\n const responseHandler = this.responseHandlers.get(message.id);\n this.responseHandlers.delete(message.id);\n if (responseHandler === undefined) {\n console.error(\"RecordKit: [RPC] !! Got a response for an unknown request.\", message.id);\n return;\n }\n if (\"error\" in message) {\n responseHandler.reject(message.error);\n }\n else {\n responseHandler.resolve(message.result);\n }\n }\n else {\n // This is a request\n const responseBody = this.handleRequest(message);\n if (responseBody !== undefined) {\n this.sendResponse(message.id, responseBody);\n }\n }\n }\n /* Sending helpers */\n sendMessage(message) {\n const stringMessage = JSON.stringify(message);\n if (this.logMessages) {\n console.log(\"RecordKit: [RPC] >\", stringMessage);\n }\n this.send(stringMessage);\n }\n sendResponse(id, response) {\n if (id === undefined) {\n return;\n }\n this.sendMessage({ ...response, nsrpc: 1, id });\n }\n async sendRequest(request) {\n const id = \"req_\" + randomUUID();\n const response = new Promise((resolve, reject) => {\n this.responseHandlers.set(id, { resolve, reject });\n });\n this.sendMessage({ ...request, nsrpc: 1, id });\n return response;\n }\n /* Request handling */\n handleRequest(request) {\n switch (request.procedure) {\n case \"init\":\n return {\n status: 501,\n error: {\n debugDescription: \"Init procedure not implemented.\",\n userMessage: \"Failed to communicate with external process. (Procedure not implemented)\",\n },\n };\n case \"perform\":\n if (\"action\" in request) {\n return {\n status: 501,\n error: {\n debugDescription: \"Perform procedure for (static) methods not implemented.\",\n userMessage: \"Failed to communicate with external process. (Procedure not implemented)\",\n },\n };\n }\n else {\n return this.handleClosureRequest(request);\n }\n case \"release\":\n return {\n status: 501,\n error: {\n debugDescription: \"Release procedure not implemented.\",\n userMessage: \"Failed to communicate with external process. (Procedure not implemented)\",\n },\n };\n }\n }\n handleClosureRequest(request) {\n const handler = this.closureTargets.get(request.target);\n if (handler === undefined) {\n return {\n status: 404,\n error: {\n debugDescription: `Perform target '${request.target}' not found.`,\n userMessage: \"Failed to communicate with external process. (Target not found)\",\n },\n };\n }\n try {\n const rawresult = handler(request.params ?? {});\n const result = rawresult === undefined ? undefined : rawresult;\n return {\n status: 200,\n result,\n };\n }\n catch (error) {\n return {\n status: 202,\n // TODO: Would be good to have an error type that we can throw that fills these fields more specifically. (But for now it doesn't matter since this is just communicated back the the CLI and not to the user.)\n error: {\n debugDescription: `${error}`,\n userMessage: \"Handler failed to perform request.\",\n underlyingError: error,\n },\n };\n }\n }\n /* Perform remote procedures */\n async initialize(args) {\n const target = args.target;\n finalizationRegistry.register(args.lifecycle, async () => {\n await this.release(target);\n });\n await this.sendRequest({\n target: args.target,\n type: args.type,\n params: args.params,\n procedure: \"init\",\n });\n }\n async perform(body) {\n return await this.sendRequest({\n ...body,\n procedure: \"perform\",\n });\n }\n async release(target) {\n await this.sendRequest({\n procedure: \"release\",\n target,\n });\n }\n async manualRelease(target) {\n await this.sendRequest({\n procedure: \"manual-release\",\n target,\n });\n }\n /* Register locally available targets/actions */\n registerClosure(options) {\n const target = `target_${options.prefix}_${randomUUID()}`;\n this.closureTargets.set(target, options.handler);\n finalizationRegistry.register(options.lifecycle, () => {\n this.closureTargets.delete(target);\n });\n return target;\n }\n}\n//# sourceMappingURL=NonstrictRPC.js.map","import { spawn } from 'node:child_process';\nimport * as readline from 'readline';\nimport { NSRPC } from \"./NonstrictRPC.js\";\nexport class IpcRecordKit {\n childProcess;\n nsrpc;\n constructor() {\n this.nsrpc = new NSRPC((message) => this.write(message));\n }\n async initialize(recordKitRpcPath, logMessages = false) {\n if (this.childProcess !== undefined) {\n throw new Error('RecordKit: [RPC] Already initialized.');\n }\n this.nsrpc.logMessages = logMessages;\n this.childProcess = await new Promise((resolve, reject) => {\n const childProcess = spawn(recordKitRpcPath, { stdio: ['pipe', 'pipe', logMessages ? 'pipe' : 'ignore'] });\n childProcess.on('close', (code, signal) => { console.error(`RecordKit: [RPC] Closed with code ${code} and signal ${signal}`); });\n childProcess.on('error', (error) => { reject(error); });\n childProcess.on('exit', (code, signal) => { console.error(`RecordKit: [RPC] Exited with code ${code} and signal ${signal}`); });\n childProcess.on('spawn', () => { resolve(childProcess); });\n });\n const { stdout, stderr } = this.childProcess;\n if (!stdout) {\n throw new Error('RecordKit: [RPC] !! No stdout stream on child process.');\n }\n readline.createInterface({ input: stdout }).on('line', (line) => {\n this.nsrpc.receive(line);\n });\n if (stderr) {\n readline.createInterface({ input: stderr }).on('line', (line) => {\n console.log(`RecordKit: [RPC] Lognoise on stderr: ${line}`);\n });\n }\n }\n write(message) {\n const stdin = this.childProcess?.stdin;\n if (!stdin) {\n throw new Error('RecordKit: [RPC] !! Missing stdin stream.');\n }\n stdin.write(message + \"\\n\");\n }\n}\n//# sourceMappingURL=IpcRecordKit.js.map","import { randomUUID } from \"crypto\";\nimport { EventEmitter } from \"stream\";\n/**\n * @group Recording\n */\nexport class Recorder extends EventEmitter {\n rpc;\n target;\n /** @ignore */\n static async newInstance(rpc, schema) {\n const target = 'Recorder_' + randomUUID();\n const object = new Recorder(rpc, target);\n schema.items.forEach(item => {\n if (item.type == 'webcam') {\n if (typeof item.camera != 'string') {\n item.camera = item.camera.id;\n }\n if (typeof item.microphone != 'string') {\n item.microphone = item.microphone.id;\n }\n }\n if (item.type == 'display') {\n if (typeof item.display != 'number') {\n item.display = item.display.id;\n }\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'Display.onSegment',\n lifecycle: object\n });\n }\n }\n if (item.type == 'windowBasedCrop') {\n if (typeof item.window != 'number') {\n item.window = item.window.id;\n }\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'Window.onSegment',\n lifecycle: object\n });\n }\n }\n if (item.type == 'appleDeviceStaticOrientation') {\n if (typeof item.device != 'string') {\n item.device = item.device.id;\n }\n }\n if (item.type == 'systemAudio') {\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'SystemAudio.onSegment',\n lifecycle: object\n });\n }\n }\n if (item.type == 'applicationAudio') {\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'ApplicationAudio.onSegment',\n lifecycle: object\n });\n }\n }\n });\n const weakRefObject = new WeakRef(object);\n const onAbortInstance = rpc.registerClosure({\n handler: (params) => { weakRefObject.deref()?.emit('abort', params.reason); },\n prefix: 'Recorder.onAbort',\n lifecycle: object\n });\n await rpc.initialize({\n target,\n type: 'Recorder',\n params: { schema, onAbortInstance },\n lifecycle: object\n });\n return object;\n }\n /** @ignore */\n constructor(rpc, target) {\n super();\n this.rpc = rpc;\n this.target = target;\n }\n async prepare() {\n await this.rpc.perform({ target: this.target, action: 'prepare' });\n }\n async start() {\n await this.rpc.perform({ target: this.target, action: 'start' });\n }\n async stop() {\n return await this.rpc.perform({ target: this.target, action: 'stop' });\n }\n async cancel() {\n await this.rpc.manualRelease(this.target);\n }\n}\n//# sourceMappingURL=Recorder.js.map","import { IpcRecordKit } from \"./IpcRecordKit.js\";\nimport { Recorder } from \"./Recorder.js\";\nimport { EventEmitter } from \"stream\";\nimport { existsSync } from \"node:fs\";\n/**\n * Entry point for the RecordKit SDK, an instance is available as `recordkit` that can be imported from the module. Do not instantiate this class directly.\n *\n * @groupDescription Discovery\n * Discover the windows and devices that are available to record.\n *\n * @groupDescription Permissions\n * Check and request the apps permission to access the recording devices.\n *\n * @groupDescription Logging\n * Log what's going on to the console for easy debugging and troubleshooting.\n */\nexport class RecordKit extends EventEmitter {\n ipcRecordKit = new IpcRecordKit();\n /** @ignore */\n constructor() {\n super();\n }\n /**\n * Initialize the RecordKit SDK.\n *\n * ⚠️ Must be called before calling any other RecordKit method.\n *\n * @param args\n */\n async initialize(args) {\n let rpcBinaryPath = args.rpcBinaryPath;\n if (args.fallbackToNodeModules ?? true) {\n if (!existsSync(rpcBinaryPath)) {\n rpcBinaryPath = rpcBinaryPath.replace('node_modules/electron/dist/Electron.app/Contents/Resources', 'node_modules/@nonstrict/recordkit/bin');\n console.error(`RecordKit: [RPC] !! Falling back to RPC binary from node_modules at ${rpcBinaryPath}`);\n }\n }\n await this.ipcRecordKit.initialize(rpcBinaryPath, args.logRpcMessages);\n const logHandlerInstance = this.ipcRecordKit.nsrpc.registerClosure({\n handler: (params) => {\n console.log('RecordKit:', params.formattedMessage);\n this.emit('log', params);\n },\n prefix: 'RecordKit.logHandler',\n lifecycle: this\n });\n await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogHandler', params: { logHandlerInstance } });\n if (args.logLevel) {\n await this.setLogLevel(args.logLevel);\n }\n }\n /**\n * Set the global log level. Defaults to `debug`.\n *\n * Messages with a lower level than this will be ignored and not passed to any log handlers.\n *\n * @group Logging\n */\n async setLogLevel(logLevel) {\n await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogLevel', params: { logLevel } });\n }\n /**\n * Overrides the global log level for a specific category. Defaults to the global log level.\n *\n * Messages in the given category with a lower level than this will be ignored and not passed to any log handlers.\n *\n * @group Logging\n */\n async setCategoryLogLevel(params) {\n await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogLevel', params });\n }\n /**\n * A list of Mac displays that can be used for screen recording.\n *\n * @group Discovery\n */\n async getDisplays() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getDisplays' });\n }\n /**\n * A list of macOS windows that can be used for screen recording.\n *\n * @group Discovery\n */\n async getWindows() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getWindows' });\n }\n /**\n * A list of cameras that are connected to the system.\n *\n * @param params.includeDeskView - Whether to include Desk View cameras in the results\n * @group Discovery\n */\n async getCameras(params) {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getCameras', params: { includeDeskView: params?.includeDeskView ?? false } });\n }\n /**\n * A list of microphones that are connected to the system.\n *\n * @group Discovery\n */\n async getMicrophones() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getMicrophones' });\n }\n /**\n * A list of iOS devices that are connected to the system.\n *\n * @group Discovery\n */\n async getAppleDevices() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getAppleDevices' });\n }\n /**\n * A list of currently running applications that can be used for screen or audio recording.\n *\n * @group Discovery\n */\n async getRunningApplications() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getRunningApplications' });\n }\n /**\n * Indicates if camera can be used.\n *\n * Authorization status that indicates whether the user grants the app permission to capture video.\n *\n * @group Permissions\n */\n async getCameraAuthorizationStatus() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getCameraAuthorizationStatus' });\n }\n /**\n * Indicates if microphone can be used.\n *\n * Authorization status that indicates whether the user grants the app permission to capture audio.\n *\n * @group Permissions\n */\n async getMicrophoneAuthorizationStatus() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getMicrophoneAuthorizationStatus' });\n }\n /**\n * Indicates if screen can be recorded.\n *\n * @group Permissions\n */\n async getScreenRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getScreenRecordingAccess' });\n }\n /**\n * Indicates if system audio can be recorded.\n *\n * @group Permissions\n */\n async getSystemAudioRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getSystemAudioRecordingAccess' });\n }\n /**\n * Indicates if keystroke events of other apps can be recorded via Input Monitoring.\n *\n * @group Permissions\n */\n async getInputMonitoringAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getInputMonitoringAccess' });\n }\n /**\n * Indicates if other apps can be controlled via Accessibility.\n *\n * @group Permissions\n */\n async getAccessibilityControlAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getAccessibilityControlAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture the camera.\n *\n * Prompts the users if this is the first time requesting access, otherwise immediately returns.\n *\n * @returns Boolean value that indicates whether the user granted or denied access to your app.\n * @group Permissions\n */\n async requestCameraAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestCameraAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture the microphone.\n *\n * Prompts the users if this is the first time requesting access, otherwise immediately returns.\n *\n * @returns Boolean value that indicates whether the user granted or denied access to your app.\n * @group Permissions\n */\n async requestMicrophoneAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestMicrophoneAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture the screen.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to do screen recording.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @group Permissions\n */\n async requestScreenRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestScreenRecordingAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture system audio.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to do screen recording.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @remarks Currently, system audio recording is currently implemented using ScreenCaptureKit,\n * which means the users needs to grant screen recording access.\n *\n * @group Permissions\n */\n async requestSystemAudioRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestSystemAudioRecordingAccess' });\n }\n /**\n * Requests the users's permission to monitor keystrokes of other apps via Input Monitoring.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to monitor other apps.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @group Permissions\n */\n async requestInputMonitoringAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestInputMonitoringAccess' });\n }\n /**\n * Requests the users's permission to control other apps via Accessibility permissions.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to control apps.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @group Permissions\n */\n async requestAccessibilityControlAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestAccessibilityControlAccess' });\n }\n async createRecorder(schema) {\n return Recorder.newInstance(this.ipcRecordKit.nsrpc, schema);\n }\n}\n/** @ignore */\nexport let recordkit = new RecordKit();\n//# sourceMappingURL=RecordKit.js.map"],"names":["randomUUID","spawn","readline","EventEmitter","existsSync"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["finalizationRegistry.js","NonstrictRPC.js","IpcRecordKit.js","Recorder.js","RecordKit.js"],"sourcesContent":["export const finalizationRegistry = new FinalizationRegistry(async (destructor) => { await destructor(); });\n//# sourceMappingURL=finalizationRegistry.js.map","import { randomUUID } from \"crypto\";\nimport { finalizationRegistry } from \"./finalizationRegistry.js\";\nexport class NSRPC {\n logMessages = false;\n send;\n responseHandlers = new Map();\n closureTargets = new Map();\n constructor(send) {\n this.send = send;\n }\n receive(data) {\n // TODO: For now we just assume the message is a valid NSRPC message, but we should:\n // - Check if the nsrpc property is set to a number in the range of 1..<2\n // - Validate the message against the defined interfaces above\n let message;\n try {\n if (this.logMessages) {\n console.log(\"RecordKit: [RPC] <\", data.trimEnd());\n }\n message = JSON.parse(data);\n }\n catch (error) {\n if (this.logMessages) {\n console.error(\"RecordKit: [RPC] !! Above message is invalid JSON, will be ignored.\");\n }\n return;\n }\n if (\"status\" in message) {\n // This is a response, dispatch it so it can be handled\n const responseHandler = this.responseHandlers.get(message.id);\n this.responseHandlers.delete(message.id);\n if (responseHandler === undefined) {\n console.error(\"RecordKit: [RPC] !! Got a response for an unknown request.\", message.id);\n return;\n }\n if (\"error\" in message) {\n responseHandler.reject(message.error);\n }\n else {\n responseHandler.resolve(message.result);\n }\n }\n else {\n // This is a request\n const responseBody = this.handleRequest(message);\n if (responseBody !== undefined) {\n this.sendResponse(message.id, responseBody);\n }\n }\n }\n /* Sending helpers */\n sendMessage(message) {\n const stringMessage = JSON.stringify(message);\n if (this.logMessages) {\n console.log(\"RecordKit: [RPC] >\", stringMessage);\n }\n this.send(stringMessage);\n }\n sendResponse(id, response) {\n if (id === undefined) {\n return;\n }\n this.sendMessage({ ...response, nsrpc: 1, id });\n }\n async sendRequest(request) {\n const id = \"req_\" + randomUUID();\n const response = new Promise((resolve, reject) => {\n this.responseHandlers.set(id, { resolve, reject });\n });\n this.sendMessage({ ...request, nsrpc: 1, id });\n return response;\n }\n /* Request handling */\n handleRequest(request) {\n switch (request.procedure) {\n case \"init\":\n return {\n status: 501,\n error: {\n debugDescription: \"Init procedure not implemented.\",\n userMessage: \"Failed to communicate with external process. (Procedure not implemented)\",\n },\n };\n case \"perform\":\n if (\"action\" in request) {\n return {\n status: 501,\n error: {\n debugDescription: \"Perform procedure for (static) methods not implemented.\",\n userMessage: \"Failed to communicate with external process. (Procedure not implemented)\",\n },\n };\n }\n else {\n return this.handleClosureRequest(request);\n }\n case \"release\":\n return {\n status: 501,\n error: {\n debugDescription: \"Release procedure not implemented.\",\n userMessage: \"Failed to communicate with external process. (Procedure not implemented)\",\n },\n };\n }\n }\n handleClosureRequest(request) {\n const handler = this.closureTargets.get(request.target);\n if (handler === undefined) {\n return {\n status: 404,\n error: {\n debugDescription: `Perform target '${request.target}' not found.`,\n userMessage: \"Failed to communicate with external process. (Target not found)\",\n },\n };\n }\n try {\n const rawresult = handler(request.params ?? {});\n const result = rawresult === undefined ? undefined : rawresult;\n return {\n status: 200,\n result,\n };\n }\n catch (error) {\n return {\n status: 202,\n // TODO: Would be good to have an error type that we can throw that fills these fields more specifically. (But for now it doesn't matter since this is just communicated back the the CLI and not to the user.)\n error: {\n debugDescription: `${error}`,\n userMessage: \"Handler failed to perform request.\",\n underlyingError: error,\n },\n };\n }\n }\n /* Perform remote procedures */\n async initialize(args) {\n const target = args.target;\n finalizationRegistry.register(args.lifecycle, async () => {\n await this.release(target);\n });\n await this.sendRequest({\n target: args.target,\n type: args.type,\n params: args.params,\n procedure: \"init\",\n });\n }\n async perform(body) {\n return await this.sendRequest({\n ...body,\n procedure: \"perform\",\n });\n }\n async release(target) {\n await this.sendRequest({\n procedure: \"release\",\n target,\n });\n }\n async manualRelease(target) {\n await this.sendRequest({\n procedure: \"manual-release\",\n target,\n });\n }\n /* Register locally available targets/actions */\n registerClosure(options) {\n const target = `target_${options.prefix}_${randomUUID()}`;\n this.closureTargets.set(target, options.handler);\n finalizationRegistry.register(options.lifecycle, () => {\n this.closureTargets.delete(target);\n });\n return target;\n }\n}\n//# sourceMappingURL=NonstrictRPC.js.map","import { spawn } from 'node:child_process';\nimport * as readline from 'readline';\nimport { NSRPC } from \"./NonstrictRPC.js\";\nexport class IpcRecordKit {\n childProcess;\n nsrpc;\n constructor() {\n this.nsrpc = new NSRPC((message) => this.write(message));\n }\n async initialize(recordKitRpcPath, logMessages = false) {\n if (this.childProcess !== undefined) {\n throw new Error('RecordKit: [RPC] Already initialized.');\n }\n this.nsrpc.logMessages = logMessages;\n this.childProcess = await new Promise((resolve, reject) => {\n const childProcess = spawn(recordKitRpcPath, { stdio: ['pipe', 'pipe', logMessages ? 'pipe' : 'ignore'] });\n childProcess.on('close', (code, signal) => { console.error(`RecordKit: [RPC] Closed with code ${code} and signal ${signal}`); });\n childProcess.on('error', (error) => { reject(error); });\n childProcess.on('exit', (code, signal) => { console.error(`RecordKit: [RPC] Exited with code ${code} and signal ${signal}`); });\n childProcess.on('spawn', () => { resolve(childProcess); });\n });\n const { stdout, stderr } = this.childProcess;\n if (!stdout) {\n throw new Error('RecordKit: [RPC] !! No stdout stream on child process.');\n }\n readline.createInterface({ input: stdout }).on('line', (line) => {\n this.nsrpc.receive(line);\n });\n if (stderr) {\n readline.createInterface({ input: stderr }).on('line', (line) => {\n console.log(`RecordKit: [RPC] Lognoise on stderr: ${line}`);\n });\n }\n }\n write(message) {\n const stdin = this.childProcess?.stdin;\n if (!stdin) {\n throw new Error('RecordKit: [RPC] !! Missing stdin stream.');\n }\n stdin.write(message + \"\\n\");\n }\n}\n//# sourceMappingURL=IpcRecordKit.js.map","import { randomUUID } from \"crypto\";\nimport { EventEmitter } from \"events\";\n/**\n * Converts RPC audio buffer data to AudioStreamBuffer format\n * @internal\n */\nfunction convertRPCParamsToAudioStreamBuffer(params) {\n try {\n // params is the AudioBufferData directly from Swift\n const rawAudioBuffer = params;\n if (!rawAudioBuffer || !Array.isArray(rawAudioBuffer.channelData)) {\n console.error('RecordKit: Invalid audio buffer received from RPC');\n return null;\n }\n const channelData = [];\n for (const base64Data of rawAudioBuffer.channelData) {\n if (typeof base64Data !== 'string') {\n console.error('RecordKit: Invalid base64 data received');\n return null;\n }\n // Decode base64 to binary data\n const binaryString = atob(base64Data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n // Convert bytes to Float32Array\n const float32Array = new Float32Array(bytes.buffer);\n channelData.push(float32Array);\n }\n const audioStreamBuffer = {\n sampleRate: rawAudioBuffer.sampleRate,\n numberOfChannels: rawAudioBuffer.numberOfChannels,\n numberOfFrames: rawAudioBuffer.numberOfFrames,\n channelData: channelData\n };\n return audioStreamBuffer;\n }\n catch (error) {\n console.error('RecordKit: Error processing audio stream buffer:', error);\n return null;\n }\n}\n/**\n * @group Recording\n */\nexport class Recorder extends EventEmitter {\n rpc;\n target;\n /** @ignore */\n static async newInstance(rpc, schema) {\n const target = 'Recorder_' + randomUUID();\n const object = new Recorder(rpc, target);\n schema.items.forEach(item => {\n if (item.type == 'webcam') {\n if (typeof item.camera != 'string') {\n item.camera = item.camera.id;\n }\n if (typeof item.microphone != 'string') {\n item.microphone = item.microphone.id;\n }\n }\n if (item.type == 'display') {\n if (typeof item.display != 'number') {\n item.display = item.display.id;\n }\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'Display.onSegment',\n lifecycle: object\n });\n }\n }\n if (item.type == 'windowBasedCrop') {\n if (typeof item.window != 'number') {\n item.window = item.window.id;\n }\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'Window.onSegment',\n lifecycle: object\n });\n }\n }\n if (item.type == 'appleDeviceStaticOrientation') {\n if (typeof item.device != 'string') {\n item.device = item.device.id;\n }\n }\n if (item.type == 'systemAudio') {\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'SystemAudio.onSegment',\n lifecycle: object\n });\n }\n if (item.output == 'stream' && item.streamCallback) {\n const streamHandler = item.streamCallback;\n item.streamCallback = rpc.registerClosure({\n handler: (params) => {\n const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);\n if (audioBuffer) {\n streamHandler(audioBuffer);\n }\n },\n prefix: 'SystemAudioStream.onAudioBuffer',\n lifecycle: object\n });\n }\n }\n if (item.type == 'applicationAudio') {\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'ApplicationAudio.onSegment',\n lifecycle: object\n });\n }\n if (item.output == 'stream' && item.streamCallback) {\n const streamHandler = item.streamCallback;\n item.streamCallback = rpc.registerClosure({\n handler: (params) => {\n const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);\n if (audioBuffer) {\n streamHandler(audioBuffer);\n }\n },\n prefix: 'ApplicationAudioStream.onAudioBuffer',\n lifecycle: object\n });\n }\n }\n if (item.type == 'microphone') {\n if (typeof item.microphone != 'string') {\n item.microphone = item.microphone.id;\n }\n if (item.output == 'segmented' && item.segmentCallback) {\n const segmentHandler = item.segmentCallback;\n item.segmentCallback = rpc.registerClosure({\n handler: (params) => { segmentHandler(params.path); },\n prefix: 'Microphone.onSegment',\n lifecycle: object\n });\n }\n if (item.output == 'stream' && item.streamCallback) {\n const streamHandler = item.streamCallback;\n item.streamCallback = rpc.registerClosure({\n handler: (params) => {\n const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);\n if (audioBuffer) {\n streamHandler(audioBuffer);\n }\n },\n prefix: 'MicrophoneStream.onAudioBuffer',\n lifecycle: object\n });\n }\n }\n });\n const weakRefObject = new WeakRef(object);\n const onAbortInstance = rpc.registerClosure({\n handler: (params) => { weakRefObject.deref()?.emit('abort', params.reason); },\n prefix: 'Recorder.onAbort',\n lifecycle: object\n });\n await rpc.initialize({\n target,\n type: 'Recorder',\n params: { schema, onAbortInstance },\n lifecycle: object\n });\n return object;\n }\n /** @ignore */\n constructor(rpc, target) {\n super();\n this.rpc = rpc;\n this.target = target;\n }\n async prepare() {\n await this.rpc.perform({ target: this.target, action: 'prepare' });\n }\n async start() {\n await this.rpc.perform({ target: this.target, action: 'start' });\n }\n async stop() {\n return await this.rpc.perform({ target: this.target, action: 'stop' });\n }\n async cancel() {\n await this.rpc.manualRelease(this.target);\n }\n}\n//# sourceMappingURL=Recorder.js.map","import { IpcRecordKit } from \"./IpcRecordKit.js\";\nimport { Recorder } from \"./Recorder.js\";\nimport { EventEmitter } from \"events\";\nimport { existsSync } from \"node:fs\";\n/**\n * Entry point for the RecordKit SDK, an instance is available as `recordkit` that can be imported from the module. Do not instantiate this class directly.\n *\n * @groupDescription Discovery\n * Discover the windows and devices that are available to record.\n *\n * @groupDescription Permissions\n * Check and request the apps permission to access the recording devices.\n *\n * @groupDescription Logging\n * Log what's going on to the console for easy debugging and troubleshooting.\n */\nexport class RecordKit extends EventEmitter {\n ipcRecordKit = new IpcRecordKit();\n /** @ignore */\n constructor() {\n super();\n }\n /**\n * Initialize the RecordKit SDK.\n *\n * ⚠️ Must be called before calling any other RecordKit method.\n *\n * @param args\n */\n async initialize(args) {\n let rpcBinaryPath = args.rpcBinaryPath;\n if (args.fallbackToNodeModules ?? true) {\n if (!existsSync(rpcBinaryPath)) {\n rpcBinaryPath = rpcBinaryPath.replace('node_modules/electron/dist/Electron.app/Contents/Resources', 'node_modules/@nonstrict/recordkit/bin');\n console.error(`RecordKit: [RPC] !! Falling back to RPC binary from node_modules at ${rpcBinaryPath}`);\n }\n }\n await this.ipcRecordKit.initialize(rpcBinaryPath, args.logRpcMessages);\n const logHandlerInstance = this.ipcRecordKit.nsrpc.registerClosure({\n handler: (params) => {\n console.log('RecordKit:', params.formattedMessage);\n this.emit('log', params);\n },\n prefix: 'RecordKit.logHandler',\n lifecycle: this\n });\n await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogHandler', params: { logHandlerInstance } });\n if (args.logLevel) {\n await this.setLogLevel(args.logLevel);\n }\n }\n /**\n * Set the global log level. Defaults to `debug`.\n *\n * Messages with a lower level than this will be ignored and not passed to any log handlers.\n *\n * @group Logging\n */\n async setLogLevel(logLevel) {\n await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogLevel', params: { logLevel } });\n }\n /**\n * Overrides the global log level for a specific category. Defaults to the global log level.\n *\n * Messages in the given category with a lower level than this will be ignored and not passed to any log handlers.\n *\n * @group Logging\n */\n async setCategoryLogLevel(params) {\n await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogLevel', params });\n }\n /**\n * A list of Mac displays that can be used for screen recording.\n *\n * @group Discovery\n */\n async getDisplays() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getDisplays' });\n }\n /**\n * A list of macOS windows that can be used for screen recording.\n *\n * @group Discovery\n */\n async getWindows() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getWindows' });\n }\n /**\n * A list of cameras that are connected to the system.\n *\n * @param params.includeDeskView - Whether to include Desk View cameras in the results\n * @group Discovery\n */\n async getCameras(params) {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getCameras', params: { includeDeskView: params?.includeDeskView ?? false } });\n }\n /**\n * A list of microphones that are connected to the system.\n *\n * @group Discovery\n */\n async getMicrophones() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getMicrophones' });\n }\n /**\n * A list of iOS devices that are connected to the system.\n *\n * @group Discovery\n */\n async getAppleDevices() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getAppleDevices' });\n }\n /**\n * A list of currently running applications that can be used for screen or audio recording.\n *\n * @group Discovery\n */\n async getRunningApplications() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getRunningApplications' });\n }\n /**\n * Indicates if camera can be used.\n *\n * Authorization status that indicates whether the user grants the app permission to capture video.\n *\n * @group Permissions\n */\n async getCameraAuthorizationStatus() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getCameraAuthorizationStatus' });\n }\n /**\n * Indicates if microphone can be used.\n *\n * Authorization status that indicates whether the user grants the app permission to capture audio.\n *\n * @group Permissions\n */\n async getMicrophoneAuthorizationStatus() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getMicrophoneAuthorizationStatus' });\n }\n /**\n * Indicates if screen can be recorded.\n *\n * @group Permissions\n */\n async getScreenRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getScreenRecordingAccess' });\n }\n /**\n * Indicates if system audio can be recorded.\n *\n * @group Permissions\n */\n async getSystemAudioRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getSystemAudioRecordingAccess' });\n }\n /**\n * Indicates if keystroke events of other apps can be recorded via Input Monitoring.\n *\n * @group Permissions\n */\n async getInputMonitoringAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getInputMonitoringAccess' });\n }\n /**\n * Indicates if other apps can be controlled via Accessibility.\n *\n * @group Permissions\n */\n async getAccessibilityControlAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getAccessibilityControlAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture the camera.\n *\n * Prompts the users if this is the first time requesting access, otherwise immediately returns.\n *\n * @returns Boolean value that indicates whether the user granted or denied access to your app.\n * @group Permissions\n */\n async requestCameraAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestCameraAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture the microphone.\n *\n * Prompts the users if this is the first time requesting access, otherwise immediately returns.\n *\n * @returns Boolean value that indicates whether the user granted or denied access to your app.\n * @group Permissions\n */\n async requestMicrophoneAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestMicrophoneAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture the screen.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to do screen recording.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @group Permissions\n */\n async requestScreenRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestScreenRecordingAccess' });\n }\n /**\n * Requests the user's permission to allow the app to capture system audio.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to do screen recording.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @remarks Currently, system audio recording is currently implemented using ScreenCaptureKit,\n * which means the users needs to grant screen recording access.\n *\n * @group Permissions\n */\n async requestSystemAudioRecordingAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestSystemAudioRecordingAccess' });\n }\n /**\n * Requests the users's permission to monitor keystrokes of other apps via Input Monitoring.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to monitor other apps.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @group Permissions\n */\n async requestInputMonitoringAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestInputMonitoringAccess' });\n }\n /**\n * Requests the users's permission to control other apps via Accessibility permissions.\n *\n * If this is the first time requesting access, this shows dialog that lets th users open System Settings.\n * In System Settings, the user can allow the app permission to control apps.\n *\n * Afterwards, the users needs to restart this app, for the permission to become active in the app.\n *\n * @group Permissions\n */\n async requestAccessibilityControlAccess() {\n return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestAccessibilityControlAccess' });\n }\n async createRecorder(schema) {\n return Recorder.newInstance(this.ipcRecordKit.nsrpc, schema);\n }\n}\n/** @ignore */\nexport let recordkit = new RecordKit();\n//# sourceMappingURL=RecordKit.js.map"],"names":["randomUUID","spawn","readline","EventEmitter","existsSync"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nonstrict/recordkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.1",
|
|
4
4
|
"description": "Powerful screen recording for your Electron app on macOS.",
|
|
5
5
|
"homepage": "https://nonstrict.eu/recordkit",
|
|
6
6
|
"repository": "nonstrict-hq/RecordKit.Electron",
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
"main": "out/index.js",
|
|
9
9
|
"types": "out/index.d.ts",
|
|
10
10
|
"exports": {
|
|
11
|
-
"
|
|
12
|
-
|
|
11
|
+
".": {
|
|
12
|
+
"browser": "./out/browser.js",
|
|
13
|
+
"import": "./out/index.js",
|
|
14
|
+
"require": "./out/index.cjs"
|
|
15
|
+
}
|
|
13
16
|
},
|
|
14
17
|
"engines": {
|
|
15
18
|
"node": ">=18.16"
|
package/src/RecordKit.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IpcRecordKit } from "./IpcRecordKit.js";
|
|
2
2
|
import { Recorder, RecorderSchemaItem } from "./Recorder.js";
|
|
3
|
-
import { EventEmitter } from "
|
|
3
|
+
import { EventEmitter } from "events";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -331,13 +331,13 @@ export type AuthorizationStatus =
|
|
|
331
331
|
export interface AppleDevice {
|
|
332
332
|
/** An identifier that uniquely identifies the device. */
|
|
333
333
|
id: string;
|
|
334
|
-
|
|
334
|
+
|
|
335
335
|
/** A localized device name for display in the user interface. */
|
|
336
336
|
name: string;
|
|
337
|
-
|
|
337
|
+
|
|
338
338
|
/** The model of this device. */
|
|
339
339
|
model_id?: string;
|
|
340
|
-
|
|
340
|
+
|
|
341
341
|
/**
|
|
342
342
|
* The current availability state of this device.
|
|
343
343
|
*
|
|
@@ -358,13 +358,13 @@ export interface AppleDevice {
|
|
|
358
358
|
export interface RunningApplication {
|
|
359
359
|
/** Identifier for this application (process id). */
|
|
360
360
|
id: number; // Int32
|
|
361
|
-
|
|
361
|
+
|
|
362
362
|
/** Display name of the application. */
|
|
363
363
|
name?: string;
|
|
364
|
-
|
|
364
|
+
|
|
365
365
|
/** Bundle identifier of the application (e.g., "com.apple.Safari"). */
|
|
366
366
|
bundle_identifier?: string;
|
|
367
|
-
|
|
367
|
+
|
|
368
368
|
/**
|
|
369
369
|
* The current availability state of this application.
|
|
370
370
|
*
|
|
@@ -382,16 +382,16 @@ export interface RunningApplication {
|
|
|
382
382
|
export interface Camera {
|
|
383
383
|
/** An identifier that uniquely identifies the camera. */
|
|
384
384
|
id: string;
|
|
385
|
-
|
|
385
|
+
|
|
386
386
|
/** A localized camera name for display in the user interface. */
|
|
387
387
|
name: string;
|
|
388
|
-
|
|
388
|
+
|
|
389
389
|
/** The model ID of this camera. */
|
|
390
390
|
model_id: string;
|
|
391
|
-
|
|
391
|
+
|
|
392
392
|
/** The manufacturer of this camera. */
|
|
393
393
|
manufacturer: string;
|
|
394
|
-
|
|
394
|
+
|
|
395
395
|
/**
|
|
396
396
|
* The current availability state of this camera.
|
|
397
397
|
*
|
|
@@ -419,16 +419,16 @@ export interface Camera {
|
|
|
419
419
|
export interface Microphone {
|
|
420
420
|
/** An identifier that uniquely identifies the microphone. */
|
|
421
421
|
id: string;
|
|
422
|
-
|
|
422
|
+
|
|
423
423
|
/** A localized microphone name for display in the user interface. */
|
|
424
424
|
name: string;
|
|
425
|
-
|
|
425
|
+
|
|
426
426
|
/** The model ID of this microphone. */
|
|
427
427
|
model_id: string;
|
|
428
|
-
|
|
428
|
+
|
|
429
429
|
/** The manufacturer of this microphone. */
|
|
430
430
|
manufacturer: string;
|
|
431
|
-
|
|
431
|
+
|
|
432
432
|
/**
|
|
433
433
|
* The current availability state of this microphone.
|
|
434
434
|
*
|
|
@@ -448,16 +448,16 @@ export interface Microphone {
|
|
|
448
448
|
export interface Display {
|
|
449
449
|
/** An identifier that uniquely identifies this Mac display (CGDirectDisplayID). */
|
|
450
450
|
id: number; // UInt32
|
|
451
|
-
|
|
451
|
+
|
|
452
452
|
/** Name of this display. */
|
|
453
453
|
localizedName?: string;
|
|
454
|
-
|
|
454
|
+
|
|
455
455
|
/** Frame of the display, relative to the main display. Uses top-left coordinate space. */
|
|
456
456
|
frame: Bounds
|
|
457
|
-
|
|
457
|
+
|
|
458
458
|
/** Indicates if this is the main display. */
|
|
459
459
|
isMain: boolean
|
|
460
|
-
|
|
460
|
+
|
|
461
461
|
/**
|
|
462
462
|
* The current availability state of this display.
|
|
463
463
|
*
|
|
@@ -476,21 +476,21 @@ export interface Display {
|
|
|
476
476
|
export interface Window {
|
|
477
477
|
/** An identifier that uniquely identifies this macOS window (CGWindowID). */
|
|
478
478
|
id: number; // UInt32
|
|
479
|
-
|
|
479
|
+
|
|
480
480
|
/** Title of the window. */
|
|
481
481
|
title?: string;
|
|
482
|
-
|
|
482
|
+
|
|
483
483
|
/** Frame of the window, relative to the main display. Uses top-left coordinate space. */
|
|
484
484
|
frame: Bounds
|
|
485
|
-
|
|
485
|
+
|
|
486
486
|
/**
|
|
487
487
|
* The level of the window relative to other windows.
|
|
488
488
|
*/
|
|
489
489
|
level: number // Int
|
|
490
|
-
|
|
490
|
+
|
|
491
491
|
/** Process ID of the application that owns this window. */
|
|
492
492
|
application_process_id?: number // Int32
|
|
493
|
-
|
|
493
|
+
|
|
494
494
|
/** Name of the application that owns this window. */
|
|
495
495
|
application_name?: string
|
|
496
496
|
}
|
package/src/Recorder.ts
CHANGED
|
@@ -1,8 +1,56 @@
|
|
|
1
1
|
import { randomUUID } from "crypto";
|
|
2
2
|
import { NSRPC } from "./NonstrictRPC.js";
|
|
3
|
-
import { EventEmitter } from "
|
|
3
|
+
import { EventEmitter } from "events";
|
|
4
4
|
import { AppleDevice, Camera, Display, Microphone, RunningApplication, Window } from "./RecordKit.js";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Converts RPC audio buffer data to AudioStreamBuffer format
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
function convertRPCParamsToAudioStreamBuffer(params: any): AudioStreamBuffer | null {
|
|
11
|
+
try {
|
|
12
|
+
// params is the AudioBufferData directly from Swift
|
|
13
|
+
const rawAudioBuffer = params as any;
|
|
14
|
+
|
|
15
|
+
if (!rawAudioBuffer || !Array.isArray(rawAudioBuffer.channelData)) {
|
|
16
|
+
console.error('RecordKit: Invalid audio buffer received from RPC');
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const channelData: Float32Array[] = [];
|
|
21
|
+
|
|
22
|
+
for (const base64Data of rawAudioBuffer.channelData) {
|
|
23
|
+
if (typeof base64Data !== 'string') {
|
|
24
|
+
console.error('RecordKit: Invalid base64 data received');
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Decode base64 to binary data
|
|
29
|
+
const binaryString = atob(base64Data);
|
|
30
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
31
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
32
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Convert bytes to Float32Array
|
|
36
|
+
const float32Array = new Float32Array(bytes.buffer);
|
|
37
|
+
channelData.push(float32Array);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const audioStreamBuffer: AudioStreamBuffer = {
|
|
41
|
+
sampleRate: rawAudioBuffer.sampleRate,
|
|
42
|
+
numberOfChannels: rawAudioBuffer.numberOfChannels,
|
|
43
|
+
numberOfFrames: rawAudioBuffer.numberOfFrames,
|
|
44
|
+
channelData: channelData
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return audioStreamBuffer;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('RecordKit: Error processing audio stream buffer:', error);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
6
54
|
/**
|
|
7
55
|
* @group Recording
|
|
8
56
|
*/
|
|
@@ -70,6 +118,19 @@ export class Recorder extends EventEmitter {
|
|
|
70
118
|
lifecycle: object
|
|
71
119
|
});
|
|
72
120
|
}
|
|
121
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
122
|
+
const streamHandler = item.streamCallback;
|
|
123
|
+
(item as any).streamCallback = rpc.registerClosure({
|
|
124
|
+
handler: (params) => {
|
|
125
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
126
|
+
if (audioBuffer) {
|
|
127
|
+
streamHandler(audioBuffer);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
prefix: 'SystemAudioStream.onAudioBuffer',
|
|
131
|
+
lifecycle: object
|
|
132
|
+
});
|
|
133
|
+
}
|
|
73
134
|
}
|
|
74
135
|
if (item.type == 'applicationAudio') {
|
|
75
136
|
if (item.output == 'segmented' && item.segmentCallback) {
|
|
@@ -80,6 +141,45 @@ export class Recorder extends EventEmitter {
|
|
|
80
141
|
lifecycle: object
|
|
81
142
|
});
|
|
82
143
|
}
|
|
144
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
145
|
+
const streamHandler = item.streamCallback;
|
|
146
|
+
(item as any).streamCallback = rpc.registerClosure({
|
|
147
|
+
handler: (params) => {
|
|
148
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
149
|
+
if (audioBuffer) {
|
|
150
|
+
streamHandler(audioBuffer);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
prefix: 'ApplicationAudioStream.onAudioBuffer',
|
|
154
|
+
lifecycle: object
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (item.type == 'microphone') {
|
|
159
|
+
if (typeof item.microphone != 'string') {
|
|
160
|
+
item.microphone = item.microphone.id
|
|
161
|
+
}
|
|
162
|
+
if (item.output == 'segmented' && item.segmentCallback) {
|
|
163
|
+
const segmentHandler = item.segmentCallback;
|
|
164
|
+
(item as any).segmentCallback = rpc.registerClosure({
|
|
165
|
+
handler: (params) => { segmentHandler(params.path as string) },
|
|
166
|
+
prefix: 'Microphone.onSegment',
|
|
167
|
+
lifecycle: object
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (item.output == 'stream' && item.streamCallback) {
|
|
171
|
+
const streamHandler = item.streamCallback;
|
|
172
|
+
(item as any).streamCallback = rpc.registerClosure({
|
|
173
|
+
handler: (params) => {
|
|
174
|
+
const audioBuffer = convertRPCParamsToAudioStreamBuffer(params);
|
|
175
|
+
if (audioBuffer) {
|
|
176
|
+
streamHandler(audioBuffer);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
prefix: 'MicrophoneStream.onAudioBuffer',
|
|
180
|
+
lifecycle: object
|
|
181
|
+
});
|
|
182
|
+
}
|
|
83
183
|
}
|
|
84
184
|
})
|
|
85
185
|
|
|
@@ -134,6 +234,7 @@ export type RecorderSchemaItem =
|
|
|
134
234
|
| AppleDeviceStaticOrientationSchema
|
|
135
235
|
| SystemAudioSchema
|
|
136
236
|
| ApplicationAudioSchema
|
|
237
|
+
| MicrophoneSchema
|
|
137
238
|
|
|
138
239
|
/**
|
|
139
240
|
* Creates a recorder item for a webcam movie file, using the provided microphone and camera. Output is stored in a RecordKit bundle.
|
|
@@ -226,7 +327,12 @@ export type SystemAudioBackend = 'screenCaptureKit' | '_beta_coreAudio'
|
|
|
226
327
|
/**
|
|
227
328
|
* @group Recording Schemas
|
|
228
329
|
*/
|
|
229
|
-
export type AudioOutputOptionsType = 'singleFile' | 'segmented'
|
|
330
|
+
export type AudioOutputOptionsType = 'singleFile' | 'segmented' | 'stream'
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @group Recording Schemas
|
|
334
|
+
*/
|
|
335
|
+
export type MicrophoneOutputOptionsType = 'singleFile' | 'segmented' | 'stream'
|
|
230
336
|
|
|
231
337
|
/**
|
|
232
338
|
* Creates a recorder item for recording system audio. By default current process audio is excluded. Output is stored in a RecordKit bundle.
|
|
@@ -253,6 +359,15 @@ export type SystemAudioSchema = {
|
|
|
253
359
|
output: 'segmented'
|
|
254
360
|
filenamePrefix?: string
|
|
255
361
|
segmentCallback?: (url: string) => void
|
|
362
|
+
} | {
|
|
363
|
+
type: 'systemAudio'
|
|
364
|
+
mode: 'exclude'
|
|
365
|
+
backend?: SystemAudioBackend
|
|
366
|
+
excludeOptions?: ('currentProcess')[]
|
|
367
|
+
excludedProcessIDs?: number[] // Int32
|
|
368
|
+
output: 'stream'
|
|
369
|
+
/** Called with real-time audio buffer data compatible with Web Audio API. Requires _beta_coreAudio backend and macOS 14.2+ */
|
|
370
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void
|
|
256
371
|
} | {
|
|
257
372
|
type: 'systemAudio'
|
|
258
373
|
mode: 'include'
|
|
@@ -268,6 +383,14 @@ export type SystemAudioSchema = {
|
|
|
268
383
|
output: 'segmented'
|
|
269
384
|
filenamePrefix?: string
|
|
270
385
|
segmentCallback?: (url: string) => void
|
|
386
|
+
} | {
|
|
387
|
+
type: 'systemAudio'
|
|
388
|
+
mode: 'include'
|
|
389
|
+
backend?: SystemAudioBackend
|
|
390
|
+
includedApplicationIDs?: number[] // Int32
|
|
391
|
+
output: 'stream'
|
|
392
|
+
/** Called with real-time audio buffer data compatible with Web Audio API. Requires _beta_coreAudio backend and macOS 14.2+ */
|
|
393
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void
|
|
271
394
|
}
|
|
272
395
|
|
|
273
396
|
/**
|
|
@@ -288,8 +411,60 @@ export type ApplicationAudioSchema = {
|
|
|
288
411
|
output: 'segmented'
|
|
289
412
|
filenamePrefix?: string
|
|
290
413
|
segmentCallback?: (url: string) => void
|
|
414
|
+
} | {
|
|
415
|
+
type: 'applicationAudio'
|
|
416
|
+
applicationID: number // Int32
|
|
417
|
+
backend?: SystemAudioBackend
|
|
418
|
+
output: 'stream'
|
|
419
|
+
/** Called with real-time audio buffer data compatible with Web Audio API. Requires _beta_coreAudio backend and macOS 14.2+ */
|
|
420
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void
|
|
291
421
|
}
|
|
292
422
|
|
|
423
|
+
/**
|
|
424
|
+
* Creates a recorder item for an audio file, using the provided microphone. Output is stored in a RecordKit bundle.
|
|
425
|
+
*
|
|
426
|
+
* @group Recording Schemas
|
|
427
|
+
*/
|
|
428
|
+
export type MicrophoneSchema = {
|
|
429
|
+
type: 'microphone'
|
|
430
|
+
microphone: Microphone | string
|
|
431
|
+
leftChannelOnly?: boolean
|
|
432
|
+
audioDelay?: number
|
|
433
|
+
output?: 'singleFile'
|
|
434
|
+
filename?: string
|
|
435
|
+
} | {
|
|
436
|
+
type: 'microphone'
|
|
437
|
+
microphone: Microphone | string
|
|
438
|
+
leftChannelOnly?: boolean
|
|
439
|
+
audioDelay?: number
|
|
440
|
+
output: 'segmented'
|
|
441
|
+
filenamePrefix?: string
|
|
442
|
+
segmentCallback?: (url: string) => void
|
|
443
|
+
} | {
|
|
444
|
+
type: 'microphone'
|
|
445
|
+
microphone: Microphone | string
|
|
446
|
+
output: 'stream'
|
|
447
|
+
/** Called with real-time audio buffer data compatible with Web Audio API */
|
|
448
|
+
streamCallback?: (audioBuffer: AudioStreamBuffer) => void
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Audio buffer compatible with Web Audio API
|
|
453
|
+
*
|
|
454
|
+
* @group Recording
|
|
455
|
+
*/
|
|
456
|
+
export interface AudioStreamBuffer {
|
|
457
|
+
/** Sample rate in Hz (e.g., 44100, 48000) */
|
|
458
|
+
sampleRate: number
|
|
459
|
+
/** Number of audio channels */
|
|
460
|
+
numberOfChannels: number
|
|
461
|
+
/** Number of frames per channel */
|
|
462
|
+
numberOfFrames: number
|
|
463
|
+
/** Non-interleaved Float32 audio data - one array per channel */
|
|
464
|
+
channelData: Float32Array[]
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
|
|
293
468
|
/**
|
|
294
469
|
* @group Recording
|
|
295
470
|
*/
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { AudioStreamBuffer } from './Recorder.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a Web Audio API AudioBuffer from a RecordKit AudioStreamBuffer.
|
|
5
|
+
*
|
|
6
|
+
* This utility converts RecordKit's streaming audio format to the standard Web Audio API format,
|
|
7
|
+
* handling various edge cases and IPC serialization issues that may occur in Electron environments.
|
|
8
|
+
*
|
|
9
|
+
* @param audioStreamBuffer - The RecordKit AudioStreamBuffer to convert
|
|
10
|
+
* @param audioContext - The Web Audio API AudioContext to use for buffer creation
|
|
11
|
+
* @returns The created AudioBuffer, or null if conversion failed
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { createWebAudioBuffer } from '@nonstrict/recordkit';
|
|
16
|
+
*
|
|
17
|
+
* // In your stream callback
|
|
18
|
+
* const streamCallback = (audioBuffer: AudioStreamBuffer) => {
|
|
19
|
+
* const audioContext = new AudioContext();
|
|
20
|
+
* const webAudioBuffer = createWebAudioBuffer(audioBuffer, audioContext);
|
|
21
|
+
*
|
|
22
|
+
* if (webAudioBuffer) {
|
|
23
|
+
* // Use the buffer with Web Audio API
|
|
24
|
+
* const source = audioContext.createBufferSource();
|
|
25
|
+
* source.buffer = webAudioBuffer;
|
|
26
|
+
* source.connect(audioContext.destination);
|
|
27
|
+
* source.start();
|
|
28
|
+
* }
|
|
29
|
+
* };
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function createWebAudioBuffer(
|
|
33
|
+
audioStreamBuffer: AudioStreamBuffer,
|
|
34
|
+
audioContext: AudioContext
|
|
35
|
+
): AudioBuffer | null {
|
|
36
|
+
// Input validation
|
|
37
|
+
if (!audioStreamBuffer || typeof audioStreamBuffer !== 'object') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!audioContext || typeof audioContext.createBuffer !== 'function') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const { sampleRate, numberOfChannels, numberOfFrames, channelData } = audioStreamBuffer;
|
|
47
|
+
|
|
48
|
+
// Validate required properties
|
|
49
|
+
if (typeof sampleRate !== 'number' || sampleRate <= 0 || sampleRate > 192000) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (typeof numberOfChannels !== 'number' || numberOfChannels <= 0 || numberOfChannels > 32) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (typeof numberOfFrames !== 'number' || numberOfFrames <= 0 || numberOfFrames > 1048576) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!Array.isArray(channelData) || channelData.length !== numberOfChannels) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Validate channel data arrays
|
|
66
|
+
for (let i = 0; i < numberOfChannels; i++) {
|
|
67
|
+
const channel = channelData[i];
|
|
68
|
+
if (!channel || (!Array.isArray(channel) && !(channel instanceof Float32Array))) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check length matches expected frame count
|
|
73
|
+
if (channel.length !== numberOfFrames) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Create Web Audio AudioBuffer
|
|
79
|
+
const audioBuffer = audioContext.createBuffer(numberOfChannels, numberOfFrames, sampleRate);
|
|
80
|
+
|
|
81
|
+
// Copy channel data to AudioBuffer
|
|
82
|
+
for (let channel = 0; channel < numberOfChannels; channel++) {
|
|
83
|
+
const outputArray = audioBuffer.getChannelData(channel);
|
|
84
|
+
const inputArray = channelData[channel];
|
|
85
|
+
|
|
86
|
+
// Handle both Float32Array and regular arrays (from Electron IPC serialization)
|
|
87
|
+
if (inputArray instanceof Float32Array) {
|
|
88
|
+
// Direct copy for Float32Array
|
|
89
|
+
outputArray.set(inputArray);
|
|
90
|
+
} else if (Array.isArray(inputArray)) {
|
|
91
|
+
// Convert regular array to Float32Array for better performance
|
|
92
|
+
const float32Array = new Float32Array(inputArray);
|
|
93
|
+
outputArray.set(float32Array);
|
|
94
|
+
} else {
|
|
95
|
+
// Fallback: manual copy with type conversion
|
|
96
|
+
for (let i = 0; i < numberOfFrames; i++) {
|
|
97
|
+
const sample = inputArray[i];
|
|
98
|
+
outputArray[i] = typeof sample === 'number' && isFinite(sample) ? sample : 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return audioBuffer;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
// Return null for any conversion failures - don't throw in streaming contexts
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
package/src/browser.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Browser-only exports - safe for use in browser environments
|
|
2
|
+
// This entry point excludes Node.js-specific functionality like EventEmitter, crypto, etc.
|
|
3
|
+
|
|
4
|
+
export { createWebAudioBuffer } from './WebAudioUtils.js';
|
|
5
|
+
|
|
6
|
+
// Type-only exports for browser use
|
|
7
|
+
export type { AudioStreamBuffer } from './Recorder.js';
|
package/tsconfig.json
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
/* Language and Environment */
|
|
18
18
|
"target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
|
19
19
|
"lib": [
|
|
20
|
-
"ES2022"
|
|
20
|
+
"ES2022",
|
|
21
|
+
"DOM"
|
|
21
22
|
], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
22
23
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
23
24
|
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|