@nonstrict/recordkit 0.51.1 → 0.53.0
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 +174 -1
- package/out/RecordKit.js +108 -2
- package/out/RecordKit.js.map +1 -1
- package/out/Recorder.d.ts +92 -2
- package/out/Recorder.js +93 -0
- 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 +201 -2
- package/out/index.cjs.map +1 -1
- package/package.json +6 -3
- package/src/RecordKit.ts +214 -2
- package/src/Recorder.ts +196 -1
- package/src/WebAudioUtils.ts +108 -0
- package/src/browser.ts +7 -0
- package/tsconfig.json +2 -1
package/out/Recorder.js
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { randomUUID } from "crypto";
|
|
2
2
|
import { EventEmitter } from "stream";
|
|
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":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,oBAAoB,CAClC,iBAAoC,EACpC,YAA0B;IAE1B,mBAAmB;IACnB,IAAI,CAAC,iBAAiB,IAAI,OAAO,iBAAiB,KAAK,QAAQ,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC;QAExF,+BAA+B;QAC/B,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,IAAI,CAAC,IAAI,UAAU,GAAG,MAAM,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,IAAI,CAAC,IAAI,gBAAgB,GAAG,EAAE,EAAE,CAAC;YAC3F,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,IAAI,CAAC,IAAI,cAAc,GAAG,OAAO,EAAE,CAAC;YAC1F,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;YAC3E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,+BAA+B;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,YAAY,YAAY,CAAC,CAAC,EAAE,CAAC;gBAChF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,4CAA4C;YAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;gBACtC,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,WAAW,GAAG,YAAY,CAAC,YAAY,CAAC,gBAAgB,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QAE5F,mCAAmC;QACnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC;YAC5D,MAAM,WAAW,GAAG,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YAExC,gFAAgF;YAChF,IAAI,UAAU,YAAY,YAAY,EAAE,CAAC;gBACvC,+BAA+B;gBAC/B,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACrC,+DAA+D;gBAC/D,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;gBAClD,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,6CAA6C;gBAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;oBACxC,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;oBAC7B,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8EAA8E;QAC9E,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
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
|
@@ -244,6 +244,47 @@ 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
|
*/
|
|
@@ -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);
|
|
@@ -417,77 +510,183 @@ class RecordKit extends stream.EventEmitter {
|
|
|
417
510
|
await this.ipcRecordKit.nsrpc.perform({ type: 'Logger', action: 'setLogLevel', params });
|
|
418
511
|
}
|
|
419
512
|
/**
|
|
513
|
+
* A list of Mac displays that can be used for screen recording.
|
|
514
|
+
*
|
|
420
515
|
* @group Discovery
|
|
421
516
|
*/
|
|
422
517
|
async getDisplays() {
|
|
423
518
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getDisplays' });
|
|
424
519
|
}
|
|
425
520
|
/**
|
|
521
|
+
* A list of macOS windows that can be used for screen recording.
|
|
522
|
+
*
|
|
426
523
|
* @group Discovery
|
|
427
524
|
*/
|
|
428
525
|
async getWindows() {
|
|
429
526
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getWindows' });
|
|
430
527
|
}
|
|
431
528
|
/**
|
|
529
|
+
* A list of cameras that are connected to the system.
|
|
530
|
+
*
|
|
531
|
+
* @param params.includeDeskView - Whether to include Desk View cameras in the results
|
|
432
532
|
* @group Discovery
|
|
433
533
|
*/
|
|
434
|
-
async getCameras() {
|
|
435
|
-
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getCameras' });
|
|
534
|
+
async getCameras(params) {
|
|
535
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getCameras', params: { includeDeskView: params?.includeDeskView ?? false } });
|
|
436
536
|
}
|
|
437
537
|
/**
|
|
538
|
+
* A list of microphones that are connected to the system.
|
|
539
|
+
*
|
|
438
540
|
* @group Discovery
|
|
439
541
|
*/
|
|
440
542
|
async getMicrophones() {
|
|
441
543
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getMicrophones' });
|
|
442
544
|
}
|
|
443
545
|
/**
|
|
546
|
+
* A list of iOS devices that are connected to the system.
|
|
547
|
+
*
|
|
444
548
|
* @group Discovery
|
|
445
549
|
*/
|
|
446
550
|
async getAppleDevices() {
|
|
447
551
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getAppleDevices' });
|
|
448
552
|
}
|
|
449
553
|
/**
|
|
554
|
+
* A list of currently running applications that can be used for screen or audio recording.
|
|
555
|
+
*
|
|
450
556
|
* @group Discovery
|
|
451
557
|
*/
|
|
452
558
|
async getRunningApplications() {
|
|
453
559
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'Recorder', action: 'getRunningApplications' });
|
|
454
560
|
}
|
|
455
561
|
/**
|
|
562
|
+
* Indicates if camera can be used.
|
|
563
|
+
*
|
|
564
|
+
* Authorization status that indicates whether the user grants the app permission to capture video.
|
|
565
|
+
*
|
|
456
566
|
* @group Permissions
|
|
457
567
|
*/
|
|
458
568
|
async getCameraAuthorizationStatus() {
|
|
459
569
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getCameraAuthorizationStatus' });
|
|
460
570
|
}
|
|
461
571
|
/**
|
|
572
|
+
* Indicates if microphone can be used.
|
|
573
|
+
*
|
|
574
|
+
* Authorization status that indicates whether the user grants the app permission to capture audio.
|
|
575
|
+
*
|
|
462
576
|
* @group Permissions
|
|
463
577
|
*/
|
|
464
578
|
async getMicrophoneAuthorizationStatus() {
|
|
465
579
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getMicrophoneAuthorizationStatus' });
|
|
466
580
|
}
|
|
467
581
|
/**
|
|
582
|
+
* Indicates if screen can be recorded.
|
|
583
|
+
*
|
|
468
584
|
* @group Permissions
|
|
469
585
|
*/
|
|
470
586
|
async getScreenRecordingAccess() {
|
|
471
587
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getScreenRecordingAccess' });
|
|
472
588
|
}
|
|
473
589
|
/**
|
|
590
|
+
* Indicates if system audio can be recorded.
|
|
591
|
+
*
|
|
592
|
+
* @group Permissions
|
|
593
|
+
*/
|
|
594
|
+
async getSystemAudioRecordingAccess() {
|
|
595
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getSystemAudioRecordingAccess' });
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Indicates if keystroke events of other apps can be recorded via Input Monitoring.
|
|
599
|
+
*
|
|
600
|
+
* @group Permissions
|
|
601
|
+
*/
|
|
602
|
+
async getInputMonitoringAccess() {
|
|
603
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getInputMonitoringAccess' });
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Indicates if other apps can be controlled via Accessibility.
|
|
607
|
+
*
|
|
608
|
+
* @group Permissions
|
|
609
|
+
*/
|
|
610
|
+
async getAccessibilityControlAccess() {
|
|
611
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'getAccessibilityControlAccess' });
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Requests the user's permission to allow the app to capture the camera.
|
|
615
|
+
*
|
|
616
|
+
* Prompts the users if this is the first time requesting access, otherwise immediately returns.
|
|
617
|
+
*
|
|
618
|
+
* @returns Boolean value that indicates whether the user granted or denied access to your app.
|
|
474
619
|
* @group Permissions
|
|
475
620
|
*/
|
|
476
621
|
async requestCameraAccess() {
|
|
477
622
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestCameraAccess' });
|
|
478
623
|
}
|
|
479
624
|
/**
|
|
625
|
+
* Requests the user's permission to allow the app to capture the microphone.
|
|
626
|
+
*
|
|
627
|
+
* Prompts the users if this is the first time requesting access, otherwise immediately returns.
|
|
628
|
+
*
|
|
629
|
+
* @returns Boolean value that indicates whether the user granted or denied access to your app.
|
|
480
630
|
* @group Permissions
|
|
481
631
|
*/
|
|
482
632
|
async requestMicrophoneAccess() {
|
|
483
633
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestMicrophoneAccess' });
|
|
484
634
|
}
|
|
485
635
|
/**
|
|
636
|
+
* Requests the user's permission to allow the app to capture the screen.
|
|
637
|
+
*
|
|
638
|
+
* If this is the first time requesting access, this shows dialog that lets th users open System Settings.
|
|
639
|
+
* In System Settings, the user can allow the app permission to do screen recording.
|
|
640
|
+
*
|
|
641
|
+
* Afterwards, the users needs to restart this app, for the permission to become active in the app.
|
|
642
|
+
*
|
|
486
643
|
* @group Permissions
|
|
487
644
|
*/
|
|
488
645
|
async requestScreenRecordingAccess() {
|
|
489
646
|
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestScreenRecordingAccess' });
|
|
490
647
|
}
|
|
648
|
+
/**
|
|
649
|
+
* Requests the user's permission to allow the app to capture system audio.
|
|
650
|
+
*
|
|
651
|
+
* If this is the first time requesting access, this shows dialog that lets th users open System Settings.
|
|
652
|
+
* In System Settings, the user can allow the app permission to do screen recording.
|
|
653
|
+
*
|
|
654
|
+
* Afterwards, the users needs to restart this app, for the permission to become active in the app.
|
|
655
|
+
*
|
|
656
|
+
* @remarks Currently, system audio recording is currently implemented using ScreenCaptureKit,
|
|
657
|
+
* which means the users needs to grant screen recording access.
|
|
658
|
+
*
|
|
659
|
+
* @group Permissions
|
|
660
|
+
*/
|
|
661
|
+
async requestSystemAudioRecordingAccess() {
|
|
662
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestSystemAudioRecordingAccess' });
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Requests the users's permission to monitor keystrokes of other apps via Input Monitoring.
|
|
666
|
+
*
|
|
667
|
+
* If this is the first time requesting access, this shows dialog that lets th users open System Settings.
|
|
668
|
+
* In System Settings, the user can allow the app permission to monitor other apps.
|
|
669
|
+
*
|
|
670
|
+
* Afterwards, the users needs to restart this app, for the permission to become active in the app.
|
|
671
|
+
*
|
|
672
|
+
* @group Permissions
|
|
673
|
+
*/
|
|
674
|
+
async requestInputMonitoringAccess() {
|
|
675
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestInputMonitoringAccess' });
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Requests the users's permission to control other apps via Accessibility permissions.
|
|
679
|
+
*
|
|
680
|
+
* If this is the first time requesting access, this shows dialog that lets th users open System Settings.
|
|
681
|
+
* In System Settings, the user can allow the app permission to control apps.
|
|
682
|
+
*
|
|
683
|
+
* Afterwards, the users needs to restart this app, for the permission to become active in the app.
|
|
684
|
+
*
|
|
685
|
+
* @group Permissions
|
|
686
|
+
*/
|
|
687
|
+
async requestAccessibilityControlAccess() {
|
|
688
|
+
return await this.ipcRecordKit.nsrpc.perform({ type: 'AuthorizationStatus', action: 'requestAccessibilityControlAccess' });
|
|
689
|
+
}
|
|
491
690
|
async createRecorder(schema) {
|
|
492
691
|
return Recorder.newInstance(this.ipcRecordKit.nsrpc, schema);
|
|
493
692
|
}
|