@nonstrict/recordkit 0.87.2 → 0.97.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.
Files changed (54) hide show
  1. package/bin/README.md +1 -1
  2. package/bin/recordkit-rpc +0 -0
  3. package/out/Errors.d.ts +91 -0
  4. package/out/Errors.js +63 -0
  5. package/out/Errors.js.map +1 -0
  6. package/out/InputEvents.d.ts +661 -0
  7. package/out/InputEvents.js +8 -0
  8. package/out/InputEvents.js.map +1 -0
  9. package/out/IpcRecordKit.js +13 -0
  10. package/out/IpcRecordKit.js.map +1 -1
  11. package/out/NonstrictRPC.d.ts +9 -0
  12. package/out/NonstrictRPC.js +27 -4
  13. package/out/NonstrictRPC.js.map +1 -1
  14. package/out/RecordKit.d.ts +267 -5
  15. package/out/RecordKit.js +243 -3
  16. package/out/RecordKit.js.map +1 -1
  17. package/out/Recorder.d.ts +451 -53
  18. package/out/Recorder.js +80 -2
  19. package/out/Recorder.js.map +1 -1
  20. package/out/RecordingMetadata.d.ts +96 -0
  21. package/out/RecordingMetadata.js +12 -0
  22. package/out/RecordingMetadata.js.map +1 -0
  23. package/out/WebAudioUtils.d.ts +35 -0
  24. package/out/WebAudioUtils.js +37 -0
  25. package/out/WebAudioUtils.js.map +1 -1
  26. package/out/WindowLevels.d.ts +46 -0
  27. package/out/WindowLevels.js +41 -0
  28. package/out/WindowLevels.js.map +1 -0
  29. package/out/browser.d.ts +8 -1
  30. package/out/browser.js +3 -1
  31. package/out/browser.js.map +1 -1
  32. package/out/index.cjs +603 -9
  33. package/out/index.cjs.map +1 -1
  34. package/out/index.d.ts +8 -0
  35. package/out/index.js +3 -0
  36. package/out/index.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/Errors.test.ts +38 -0
  39. package/src/Errors.ts +151 -0
  40. package/src/InputEvents.ts +695 -0
  41. package/src/IpcRecordKit.ts +12 -0
  42. package/src/NonstrictRPC.test.ts +24 -1
  43. package/src/NonstrictRPC.ts +29 -5
  44. package/src/RecordKit.ts +347 -11
  45. package/src/Recorder.schema.test.ts +167 -0
  46. package/src/Recorder.ts +558 -80
  47. package/src/RecordingMetadata.ts +125 -0
  48. package/src/WebAudioUtils.test.ts +78 -0
  49. package/src/WebAudioUtils.ts +57 -1
  50. package/src/WindowLevels.test.ts +34 -0
  51. package/src/WindowLevels.ts +47 -0
  52. package/src/browser.ts +12 -2
  53. package/src/index.ts +8 -0
  54. package/src/__snapshots__/NonstrictRPC.test.ts.snap +0 -24
package/out/Recorder.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import { NSRPC } from "./NonstrictRPC.js";
3
3
  import { EventEmitter } from "events";
4
- import { AppleDevice, Camera, Display, Microphone, Window } from "./RecordKit.js";
4
+ import { AppleDevice, Bounds, Camera, Display, Microphone, Window } from "./RecordKit.js";
5
+ import type { RecordKitErrorCode } from "./Errors.js";
5
6
  /**
6
7
  * @group Recording
7
8
  */
@@ -12,114 +13,424 @@ export declare class Recorder extends EventEmitter {
12
13
  static newInstance(rpc: NSRPC, schema: {
13
14
  output_directory?: string;
14
15
  items: RecorderSchemaItem[];
15
- settings?: {
16
- allowFrameReordering?: boolean;
17
- };
16
+ settings?: RecorderSettings;
18
17
  }): Promise<Recorder>;
19
18
  /** @ignore */
20
19
  constructor(rpc: NSRPC, target: string);
21
- prepare(): Promise<void>;
20
+ /**
21
+ * Prepares the recording session for instant recording, allocating resources and validating the
22
+ * configuration.
23
+ *
24
+ * Preparing ahead of time lets {@link start} begin recording instantly; without it, starting incurs
25
+ * a setup delay.
26
+ *
27
+ * @returns The expected {@link BundleInfo} describing the file assets that will be produced by this
28
+ * recording, allowing you to inspect the planned output (filenames, asset types, sizes) before
29
+ * recording starts.
30
+ */
31
+ prepare(): Promise<BundleInfo>;
32
+ /**
33
+ * Starts recording. If the session was not already {@link prepare}d this performs setup first,
34
+ * incurring a short delay; call {@link prepare} ahead of time to start instantly.
35
+ */
22
36
  start(): Promise<void>;
37
+ /**
38
+ * Pauses the recording. The capture hardware remains active so recording can be resumed quickly.
39
+ *
40
+ * Call {@link resume} to continue recording, or {@link stop} to finish.
41
+ */
42
+ pause(): Promise<void>;
43
+ /**
44
+ * Resumes a recording that was previously paused with {@link pause}.
45
+ */
46
+ resume(): Promise<void>;
47
+ /**
48
+ * Stops the recording, finalizes the output files, and returns the {@link RecordingResult}
49
+ * describing the completed bundle. The recorder cannot be reused after stopping.
50
+ *
51
+ * @remarks Known limitation: when the recording failed, the returned promise rejects with the
52
+ * failure but the partial recording result is not available over the RPC bridge (the Swift API
53
+ * surfaces it as `PartialResultError`). Any partially-written files do remain on disk in the
54
+ * bundle inside the schema's `output_directory`.
55
+ */
23
56
  stop(): Promise<RecordingResult>;
57
+ /**
58
+ * Cancels the recording and releases its resources without finalizing output. Use this to discard
59
+ * an in-progress or prepared recording; call {@link stop} instead to keep the result.
60
+ */
24
61
  cancel(): Promise<void>;
25
62
  }
26
63
  /**
64
+ * Typed event overloads for {@link Recorder}. Declaration-merges with the class so that
65
+ * `recorder.on('abort', reason => …)` receives a typed {@link AbortReason} instead of `any`.
66
+ *
27
67
  * @group Recording
28
68
  */
29
- export type RecorderSchemaItem = WebcamSchema | DisplaySchema | WindowBasedCropSchema | AppleDeviceStaticOrientationSchema | AppleDeviceSchema | SystemAudioSchema | ApplicationAudioSchema | MicrophoneSchema;
69
+ export interface Recorder {
70
+ /** Fires when the recording is aborted by an error or a system interruption. */
71
+ on(event: 'abort', listener: (reason: AbortReason) => void): this;
72
+ /** @see {@link Recorder.on} */
73
+ once(event: 'abort', listener: (reason: AbortReason) => void): this;
74
+ /** @see {@link Recorder.on} */
75
+ off(event: 'abort', listener: (reason: AbortReason) => void): this;
76
+ /** @see {@link Recorder.on} */
77
+ emit(event: 'abort', reason: AbortReason): boolean;
78
+ /**
79
+ * Fires whenever the set of active {@link Signal}s changes, with all signals active at that
80
+ * moment. An empty array means everything is healthy again. Events are asynchronous, so one can
81
+ * still arrive just after {@link Recorder.stop} resolved; the last one is always an empty array.
82
+ */
83
+ on(event: 'signals', listener: (signals: Signal[]) => void): this;
84
+ /** @see {@link Recorder.on} */
85
+ once(event: 'signals', listener: (signals: Signal[]) => void): this;
86
+ /** @see {@link Recorder.on} */
87
+ off(event: 'signals', listener: (signals: Signal[]) => void): this;
88
+ /** @see {@link Recorder.on} */
89
+ emit(event: 'signals', signals: Signal[]): boolean;
90
+ }
30
91
  /**
31
- * Creates a recorder item for a webcam movie file, using the provided microphone and camera. Output is stored in a RecordKit bundle.
92
+ * Settings that apply to the whole recording session.
93
+ *
94
+ * @group Recording
95
+ */
96
+ export interface RecorderSettings {
97
+ /**
98
+ * Specifies if RecordKit is allowed to do frame reordering in video files. Defaults to `true`.
99
+ *
100
+ * When enabled, to achieve the best compression some video encoders can reorder frames and
101
+ * generate B-frames.
102
+ */
103
+ allowFrameReordering?: boolean;
104
+ /**
105
+ * Whether a successful recording updates the user's preferred devices for the sources it used.
106
+ * Defaults to `true`.
107
+ *
108
+ * When enabled, starting a recording sets the devices in the schema as the user's preferred
109
+ * devices (for the device types that support this).
110
+ */
111
+ updatesUserPreferred?: boolean;
112
+ /** Target duration, in whole seconds, of each audio segment when using segmented output. Defaults to `6`. Fractional values are not supported. */
113
+ audioSegmentDuration?: number;
114
+ /** Target duration, in whole seconds, of each video segment when using segmented output. Defaults to `2`. Fractional values are not supported. */
115
+ videoSegmentDuration?: number;
116
+ /**
117
+ * Maximum interval, in seconds, between keyframes in the video stream. Defaults to no forced
118
+ * interval.
119
+ *
120
+ * When set, the encoder places a keyframe at least every this many seconds. The frame-count based
121
+ * maximum keyframe interval is computed automatically from the video frame rate. When omitted, the
122
+ * encoder uses its default keyframe-placement heuristic.
123
+ */
124
+ keyframeIntervalDuration?: number;
125
+ /**
126
+ * Free disk space, in bytes, below which a running recording is aborted.
127
+ * Defaults to `104857600` (100 MB).
128
+ *
129
+ * While recording, RecordKit periodically checks the actual available capacity of the volume the
130
+ * recording is written to (purgeable/opportunistic space is not counted). Shortly after the
131
+ * available capacity drops below this level the recording is aborted with an
132
+ * `insufficientDiskSpace` error. Keep it high enough to absorb whatever is still written between
133
+ * two checks and to leave room to finalize the recording.
134
+ * Set to `0` to never abort on disk space (record until the disk is full), which may result in a
135
+ * corrupt recording. A `diskSpaceWarningLevel` keeps being reported either way.
136
+ *
137
+ * @see {@link RecorderSettings.diskSpaceWarningLevel}, the higher level that warns instead of
138
+ * aborting.
139
+ */
140
+ diskSpaceAbortLevel?: number;
141
+ /**
142
+ * Free disk space, in bytes, below which the recording volume counts as running low.
143
+ * Defaults to `157286400` (150 MB).
144
+ *
145
+ * Checked once during `prepare()`, which fails with an `insufficientDiskSpace` error when the
146
+ * volume is already below it, and then periodically while recording. Dropping below it during a
147
+ * recording does not interrupt anything, it raises a `lowDiskSpace` {@link Signal} on the
148
+ * `signals` event so your app can warn the user; the signal clears again once enough space is
149
+ * freed up.
150
+ *
151
+ * Set this higher than `diskSpaceAbortLevel` so there is room to warn before the recording is
152
+ * aborted at that lower level. Set to `0` to disable both the prepare-time check and the
153
+ * signal.
154
+ */
155
+ diskSpaceWarningLevel?: number;
156
+ }
157
+ /**
158
+ * @group Recording
159
+ */
160
+ export type RecorderSchemaItem = WebcamSchema | DisplaySchema | WindowBasedCropSchema | DesktopIndependentWindowSchema | AppleDeviceStaticOrientationSchema | AppleDeviceSchema | SystemAudioSchema | ApplicationAudioSchema | MicrophoneSchema;
161
+ /**
162
+ * A width/height pair. The unit (pixels or points) depends on the consuming API — see the
163
+ * documentation of the specific method or option that takes this value.
32
164
  *
33
165
  * @group Recording Schemas
34
166
  */
35
- export type WebcamSchema = {
36
- type: 'webcam';
37
- camera: Camera | string;
38
- microphone: Microphone | string;
39
- /** Video codec for the recording. Defaults to 'h264'. */
40
- videoCodec?: VideoCodec;
41
- preserveActiveCameraConfiguration?: boolean;
42
- leftAudioChannelOnly?: boolean;
43
- audioDelay?: number;
167
+ export interface Size {
168
+ width: number;
169
+ height: number;
170
+ }
171
+ /**
172
+ * Content that can be excluded from a screen recording.
173
+ *
174
+ * - `currentProcess`: Exclude the windows of the process hosting the recorder from the recording.
175
+ * - `screenRecordingIndicator`: Exclude the orange screen-recording indicator from the recording.
176
+ *
177
+ * @remarks From Electron the process hosting the recorder is the bundled `recordkit-rpc` helper,
178
+ * not your app — so `currentProcess` does not exclude your app's own windows. To exclude those,
179
+ * pass your process IDs (e.g. `process.pid`) via the schema item's `excludedProcessIDs`.
180
+ *
181
+ * @group Recording Schemas
182
+ */
183
+ export type ScreenRecordingExcludeOption = 'currentProcess' | 'screenRecordingIndicator';
184
+ /**
185
+ * Output configuration for JSON sidecar files such as the mouse/keyboard input-event log.
186
+ *
187
+ * - `singleFile`: Write all events to a single JSON file (optionally named via `filename`).
188
+ * - `segmented`: Write events to multiple segmented JSON files; `segmentCallback` is invoked with the
189
+ * path of each segment as it is written to disk.
190
+ *
191
+ * @group Recording Schemas
192
+ */
193
+ export type JSONOutputOptions = {
44
194
  output?: 'singleFile';
45
195
  filename?: string;
46
196
  } | {
197
+ output: 'segmented';
198
+ filenamePrefix?: string;
199
+ segmentCallback?: (url: string) => void;
200
+ };
201
+ interface WebcamSchemaBase {
47
202
  type: 'webcam';
203
+ /** The camera to record, either a {@link Camera} or its `id`. */
48
204
  camera: Camera | string;
205
+ /** The microphone to record alongside the camera, either a {@link Microphone} or its `id`. */
49
206
  microphone: Microphone | string;
207
+ /** Caps the output video to at most these dimensions (in pixels), preserving aspect ratio. */
208
+ maxVideoDimensions?: Size;
50
209
  /** Video codec for the recording. Defaults to 'h264'. */
51
210
  videoCodec?: VideoCodec;
211
+ /**
212
+ * When `true`, leaves the camera's active format/configuration untouched instead of letting
213
+ * RecordKit reconfigure the device for the requested recording. Defaults to `false`.
214
+ */
52
215
  preserveActiveCameraConfiguration?: boolean;
216
+ /** Record only the left channel of the microphone (useful for mono lavalier mics). Defaults to `false`. */
53
217
  leftAudioChannelOnly?: boolean;
218
+ /** Delay applied to the microphone audio relative to the video, in seconds, to correct lip-sync. Defaults to `0`. */
54
219
  audioDelay?: number;
220
+ /** Echo cancellation applied to the microphone audio. Defaults to `'off'`. */
221
+ echoCancellation?: EchoCancellation;
222
+ /** Background blur applied to the camera video. Defaults to `'off'`. */
223
+ backgroundBlur?: BackgroundBlur;
224
+ }
225
+ /**
226
+ * Creates a recorder item for a webcam movie file, using the provided microphone and camera. Output is stored in a RecordKit bundle.
227
+ *
228
+ * @group Recording Schemas
229
+ */
230
+ export type WebcamSchema = (WebcamSchemaBase & {
231
+ output?: 'singleFile';
232
+ filename?: string;
233
+ }) | (WebcamSchemaBase & {
55
234
  output: 'segmented';
56
235
  filenamePrefix?: string;
57
236
  segmentCallback?: (url: string) => void;
237
+ });
238
+ /**
239
+ * Acoustic echo cancellation applied to microphone audio. Captures system/playback audio via Core
240
+ * Audio process taps and removes it from the microphone signal in real time using WebRTC AEC3.
241
+ *
242
+ * - `'off'`: No echo cancellation (default).
243
+ * - `'aggressive'`: Maximum echo removal at the cost of speech quality — aggressive suppression,
244
+ * high-pass filter, and residual echo gate at 16 kHz. Optimized for speech-to-text pipelines where
245
+ * echo removal matters more than audio fidelity.
246
+ * - `'balanced'`: Balanced echo removal that preserves speech quality — balanced suppression with
247
+ * high-pass filter but no residual echo gate at 48 kHz. Optimized for recording pipelines where
248
+ * audio fidelity is more important than pure echo removal.
249
+ * - An object for full control over the AEC3 configuration; omitted fields default to the `'balanced'`
250
+ * preset.
251
+ *
252
+ * @remarks Requires macOS 14.2 or later (Core Audio process taps). On older versions, preparing the
253
+ * recorder fails with a `configurationNotSupported` error.
254
+ *
255
+ * @group Recording Schemas
256
+ */
257
+ export type EchoCancellation = 'off' | 'aggressive' | 'balanced' | {
258
+ /**
259
+ * Sample rate the echo canceller runs at, in Hz. Defaults to `48000`. 16 kHz is sufficient for
260
+ * speech-to-text; 48 kHz preserves full audio fidelity.
261
+ */
262
+ sampleRate?: 16000 | 32000 | 48000;
263
+ /**
264
+ * Echo suppression mode. Defaults to `'balanced'`.
265
+ *
266
+ * - `'balanced'`: Conservative suppression that allows AEC3's transparent mode (passes audio
267
+ * through unchanged when no echo is detected) and protects near-end speech during double-talk.
268
+ * Best where speech naturalness matters.
269
+ * - `'aggressive'`: Disables near-end speech detection so echo is suppressed even during
270
+ * double-talk; removes ~2 dB more echo but attenuates speech by 3-5 dB.
271
+ */
272
+ suppressionMode?: 'balanced' | 'aggressive';
273
+ /**
274
+ * Apply a high-pass filter on the capture signal to remove DC offset and low-frequency noise
275
+ * that can interfere with the adaptive filter. Defaults to `true`.
276
+ */
277
+ highPassFilter?: boolean;
278
+ /**
279
+ * Apply a post-AEC3 gate that attenuates output when the speaker is active but output is quiet
280
+ * (likely residual echo, not speech). Catches echo the suppressor misses, at the cost of
281
+ * occasional clipping of quiet speech. Defaults to `false`.
282
+ */
283
+ residualEchoGate?: boolean;
58
284
  };
59
285
  /**
60
- * Creates a recorder item for recording a single display. Output is stored in a RecordKit bundle.
286
+ * Background blur applied to camera video. The person is segmented from each frame using Apple's
287
+ * Vision person segmentation and composited over a Gaussian-blurred copy of the background, keeping
288
+ * the foreground subject sharp while blurring the background.
289
+ *
290
+ * - `'off'`: No background blur (default).
291
+ * - `'balanced'`: Default-quality blur with a moderate background blur radius and soft mask edges.
292
+ * - `'fast'`: Faster, lower-quality blur for lower-end hardware.
293
+ * - An object for full control over the Vision-based configuration; omitted fields default to the
294
+ * `'balanced'` preset.
61
295
  *
62
296
  * @group Recording Schemas
63
297
  */
64
- export type DisplaySchema = {
298
+ export type BackgroundBlur = 'off' | 'balanced' | 'fast' | {
299
+ /**
300
+ * Trade-off between segmentation speed and accuracy. Defaults to `'balanced'`.
301
+ *
302
+ * - `'accurate'`: Best segmentation quality, highest cost.
303
+ * - `'balanced'`: Default trade-off between quality and cost.
304
+ * - `'fast'`: Lowest cost, suitable for real-time on lower-end hardware.
305
+ */
306
+ quality?: 'accurate' | 'balanced' | 'fast';
307
+ /**
308
+ * Sigma for the Gaussian blur applied to the background. Larger values produce a stronger blur;
309
+ * `0` disables the blur (the background is the original image). Defaults to `10`.
310
+ */
311
+ blurRadius?: number;
312
+ /**
313
+ * Sigma for the Gaussian blur applied to the segmentation mask to soften foreground/background
314
+ * transitions; `0` keeps the raw mask edges. Defaults to `3`.
315
+ */
316
+ featherRadius?: number;
317
+ };
318
+ interface DisplaySchemaBase {
65
319
  type: 'display';
320
+ /** The display to record, either a {@link Display} or its numeric id. */
66
321
  display: Display | number;
322
+ /** Crop rectangle (in points, top-left origin) within the display. Defaults to the full display. */
323
+ crop?: Bounds;
324
+ /**
325
+ * Content to exclude from the recording. Defaults to `['currentProcess', 'screenRecordingIndicator']`.
326
+ * Pass an explicit (possibly empty) array to override the default.
327
+ */
328
+ excludeOptions?: ScreenRecordingExcludeOption[];
329
+ /** Process IDs of applications to exclude from the recording. */
330
+ excludedProcessIDs?: number[];
67
331
  /** Color space for the recording. Defaults to 'sRGB'. Note: 'displayP3' requires 'hevc' video codec. */
68
332
  colorSpace?: ColorSpace;
333
+ /** Minimum interval between frames, in seconds. Caps the frame rate (e.g. `1/30` for 30 fps). Defaults to uncapped. */
334
+ minimumFrameInterval?: number;
335
+ /** Caps the output video to at most these dimensions (in pixels), preserving aspect ratio. */
336
+ maxVideoDimensions?: Size;
69
337
  /** Video codec for the recording. Defaults to 'h264'. */
70
338
  videoCodec?: VideoCodec;
339
+ /** Whether to draw the mouse cursor into the recording. Defaults to `true`. */
71
340
  shows_cursor?: boolean;
341
+ /** Whether to capture mouse input events into a JSON sidecar file. Defaults to `false`. */
72
342
  mouse_events?: boolean;
343
+ /** Whether to capture keyboard input events into a JSON sidecar file. Defaults to `false`. */
73
344
  keyboard_events?: boolean;
345
+ /** Output configuration for the mouse/keyboard input-event JSON sidecar files. */
346
+ inputEventsOutput?: JSONOutputOptions;
347
+ /** Whether to also record the display's audio. Defaults to `false`. */
74
348
  include_audio?: boolean;
349
+ }
350
+ /**
351
+ * Creates a recorder item for recording a single display. Output is stored in a RecordKit bundle.
352
+ *
353
+ * @group Recording Schemas
354
+ */
355
+ export type DisplaySchema = (DisplaySchemaBase & {
75
356
  output?: 'singleFile';
76
357
  filename?: string;
77
- } | {
78
- type: 'display';
79
- display: Display | number;
358
+ }) | (DisplaySchemaBase & {
359
+ output: 'segmented';
360
+ filenamePrefix?: string;
361
+ segmentCallback?: (url: string) => void;
362
+ });
363
+ interface WindowBasedCropSchemaBase {
364
+ type: 'windowBasedCrop';
365
+ /** The window to record, either a {@link Window} or its numeric id. */
366
+ window: Window | number;
80
367
  /** Color space for the recording. Defaults to 'sRGB'. Note: 'displayP3' requires 'hevc' video codec. */
81
368
  colorSpace?: ColorSpace;
369
+ /** Minimum interval between frames, in seconds. Caps the frame rate (e.g. `1/30` for 30 fps). Defaults to uncapped. */
370
+ minimumFrameInterval?: number;
371
+ /** Caps the output video to at most these dimensions (in pixels), preserving aspect ratio. */
372
+ maxVideoDimensions?: Size;
82
373
  /** Video codec for the recording. Defaults to 'h264'. */
83
374
  videoCodec?: VideoCodec;
375
+ /** Whether to draw the mouse cursor into the recording. Defaults to `true`. */
84
376
  shows_cursor?: boolean;
377
+ /** Whether to capture mouse input events into a JSON sidecar file. Defaults to `false`. */
85
378
  mouse_events?: boolean;
379
+ /** Whether to capture keyboard input events into a JSON sidecar file. Defaults to `false`. */
86
380
  keyboard_events?: boolean;
381
+ /** Output configuration for the mouse/keyboard input-event JSON sidecar files. */
382
+ inputEventsOutput?: JSONOutputOptions;
383
+ /** Whether to also record the audio of the window's application. Defaults to `false`. */
87
384
  include_audio?: boolean;
88
- output: 'segmented';
89
- filenamePrefix?: string;
90
- segmentCallback?: (url: string) => void;
91
- };
385
+ }
92
386
  /**
93
387
  * Creates a recorder item for recording the initial crop of a window on a display. Output is stored in a RecordKit bundle.
94
388
  *
95
389
  * @group Recording Schemas
96
390
  */
97
- export type WindowBasedCropSchema = {
98
- type: 'windowBasedCrop';
99
- window: Window | number;
100
- /** Color space for the recording. Defaults to 'sRGB'. Note: 'displayP3' requires 'hevc' video codec. */
101
- colorSpace?: ColorSpace;
102
- /** Video codec for the recording. Defaults to 'h264'. */
103
- videoCodec?: VideoCodec;
104
- shows_cursor?: boolean;
105
- mouse_events?: boolean;
106
- keyboard_events?: boolean;
391
+ export type WindowBasedCropSchema = (WindowBasedCropSchemaBase & {
107
392
  output?: 'singleFile';
108
393
  filename?: string;
109
- } | {
110
- type: 'windowBasedCrop';
394
+ }) | (WindowBasedCropSchemaBase & {
395
+ output: 'segmented';
396
+ filenamePrefix?: string;
397
+ segmentCallback?: (url: string) => void;
398
+ });
399
+ interface DesktopIndependentWindowSchemaBase {
400
+ type: 'desktopIndependentWindow';
111
401
  window: Window | number;
112
402
  /** Color space for the recording. Defaults to 'sRGB'. Note: 'displayP3' requires 'hevc' video codec. */
113
403
  colorSpace?: ColorSpace;
404
+ /** Minimum interval between frames, in seconds. Caps the frame rate (e.g. `1/30` for 30 fps). Defaults to uncapped. */
405
+ minimumFrameInterval?: number;
406
+ /** Caps the output video to at most these dimensions (in pixels), preserving aspect ratio. */
407
+ maxVideoDimensions?: Size;
114
408
  /** Video codec for the recording. Defaults to 'h264'. */
115
409
  videoCodec?: VideoCodec;
116
410
  shows_cursor?: boolean;
117
411
  mouse_events?: boolean;
118
412
  keyboard_events?: boolean;
413
+ /** Output configuration for the mouse/keyboard input-event JSON sidecar files. */
414
+ inputEventsOutput?: JSONOutputOptions;
415
+ /** Whether to also record the audio of the window's application. Defaults to `false`. */
416
+ include_audio?: boolean;
417
+ }
418
+ /**
419
+ * Creates a recorder item that records a single window, following it across the desktop independently of
420
+ * what is drawn on screen (the window can be moved or partially off-screen and is still captured in full).
421
+ * Output is stored in a RecordKit bundle.
422
+ *
423
+ * @remarks Requires macOS 13.1 or later.
424
+ * @group Recording Schemas
425
+ */
426
+ export type DesktopIndependentWindowSchema = (DesktopIndependentWindowSchemaBase & {
427
+ output?: 'singleFile';
428
+ filename?: string;
429
+ }) | (DesktopIndependentWindowSchemaBase & {
119
430
  output: 'segmented';
120
431
  filenamePrefix?: string;
121
432
  segmentCallback?: (url: string) => void;
122
- };
433
+ });
123
434
  /**
124
435
  * Creates a recorder item for an Apple device screen recording, using the provided deviceID. Output is stored in a RecordKit bundle.
125
436
  *
@@ -188,6 +499,10 @@ export type MicrophoneOutputOptionsType = 'singleFile' | 'segmented' | 'stream';
188
499
  * When using `mode: 'exclude'`, all system audio is recorded except for excluded applications.
189
500
  * When using `mode: 'include'`, only audio from specified applications is recorded.
190
501
  *
502
+ * @remarks The default `excludeOptions: ['currentProcess']` refers to the process hosting the
503
+ * recorder — from Electron that is the bundled `recordkit-rpc` helper, which plays no audio. To
504
+ * exclude your own app's audio, pass its process IDs via `excludedProcessIDs`.
505
+ *
191
506
  * @group Recording Schemas
192
507
  */
193
508
  export type SystemAudioSchema = {
@@ -266,33 +581,33 @@ export type ApplicationAudioSchema = {
266
581
  /** Called with real-time audio buffer data compatible with Web Audio API. */
267
582
  streamCallback?: (audioBuffer: AudioStreamBuffer) => void;
268
583
  };
584
+ interface MicrophoneSchemaCommon {
585
+ type: 'microphone';
586
+ microphone: Microphone | string;
587
+ /** Echo cancellation applied to the microphone audio. Defaults to `'off'`. */
588
+ echoCancellation?: EchoCancellation;
589
+ }
269
590
  /**
270
591
  * Creates a recorder item for an audio file, using the provided microphone. Output is stored in a RecordKit bundle.
271
592
  *
272
593
  * @group Recording Schemas
273
594
  */
274
- export type MicrophoneSchema = {
275
- type: 'microphone';
276
- microphone: Microphone | string;
595
+ export type MicrophoneSchema = (MicrophoneSchemaCommon & {
277
596
  leftChannelOnly?: boolean;
278
597
  audioDelay?: number;
279
598
  output?: 'singleFile';
280
599
  filename?: string;
281
- } | {
282
- type: 'microphone';
283
- microphone: Microphone | string;
600
+ }) | (MicrophoneSchemaCommon & {
284
601
  leftChannelOnly?: boolean;
285
602
  audioDelay?: number;
286
603
  output: 'segmented';
287
604
  filenamePrefix?: string;
288
605
  segmentCallback?: (url: string) => void;
289
- } | {
290
- type: 'microphone';
291
- microphone: Microphone | string;
606
+ }) | (MicrophoneSchemaCommon & {
292
607
  output: 'stream';
293
608
  /** Called with real-time audio buffer data compatible with Web Audio API */
294
609
  streamCallback?: (audioBuffer: AudioStreamBuffer) => void;
295
- };
610
+ });
296
611
  /**
297
612
  * Audio buffer compatible with Web Audio API
298
613
  *
@@ -308,6 +623,33 @@ export interface AudioStreamBuffer {
308
623
  /** Non-interleaved Float32 audio data - one array per channel */
309
624
  channelData: Float32Array[];
310
625
  }
626
+ /**
627
+ * A condition detected during a recording that might need the user's attention.
628
+ *
629
+ * Unlike an {@link AbortReason} a signal never ends the recording, it reports something being off
630
+ * while recording continues, so your app can warn the user and let them fix it. A signal stays in
631
+ * the list emitted on the `signals` event for as long as the condition holds.
632
+ *
633
+ * @group Recording
634
+ */
635
+ export interface Signal {
636
+ /** The kind of condition that was detected. */
637
+ kind: SignalKind;
638
+ }
639
+ /**
640
+ * The kind of condition a {@link Signal} reports.
641
+ *
642
+ * @group Recording
643
+ */
644
+ export type SignalKind =
645
+ /**
646
+ * Free space on the recording volume dropped below
647
+ * {@link RecorderSettings.diskSpaceWarningLevel}. The recording continues, but keeps eating into
648
+ * the space that is left; below {@link RecorderSettings.diskSpaceAbortLevel} it is aborted with
649
+ * an `insufficientDiskSpace` error instead. A paused recording is never aborted, since nothing is
650
+ * being written; it is reported on and aborts after resuming.
651
+ */
652
+ 'lowDiskSpace';
311
653
  /**
312
654
  * @group Recording
313
655
  */
@@ -317,10 +659,11 @@ export type AbortReason = {
317
659
  } | {
318
660
  reason: 'interrupted';
319
661
  result: RecordingResult;
320
- error: any;
662
+ error: RecordKitError | NSErrorPayload;
321
663
  } | {
322
664
  reason: 'failed';
323
- error: any;
665
+ result: RecordingResult;
666
+ error: RecordKitError | NSErrorPayload;
324
667
  };
325
668
  /**
326
669
  * @group Recording
@@ -336,9 +679,9 @@ export interface RecordingResult {
336
679
  */
337
680
  export interface RecordKitError {
338
681
  name: "RecordKitError";
339
- /** Error code, used for grouping related errors */
340
- code: string;
341
- /** Error code number */
682
+ /** Error code, used for grouping related errors. See {@link RecordKitErrorCode} for the full list of codes. */
683
+ code: RecordKitErrorCode;
684
+ /** Error code number. See {@link RECORDKIT_ERROR_CODE_NUMBERS}. */
342
685
  codeNumber: number;
343
686
  /** Message describing the problem and possible recovery options, intended to be shown directly to the end-user. */
344
687
  message: string;
@@ -346,12 +689,67 @@ export interface RecordKitError {
346
689
  debugDescription: string;
347
690
  }
348
691
  /**
692
+ * An error produced outside RecordKit's own error domain — a raw `NSError` surfaced over the bridge.
693
+ *
694
+ * Distinguished from {@link RecordKitError} by its `name` discriminator. See the
695
+ * [Logging and Error Handling guide](https://recordkit.dev/guides/logging-and-errors#error-handling).
696
+ *
697
+ * @group Recording
698
+ */
699
+ export interface NSErrorPayload {
700
+ name: "NSError";
701
+ /** The `NSError` domain (e.g. `"NSOSStatusErrorDomain"`). */
702
+ errorDomain: string;
703
+ /** The `NSError` code within {@link NSErrorPayload.errorDomain}. */
704
+ errorCode: number;
705
+ /** Localized, user-facing description of the error. */
706
+ message: string;
707
+ /** Detailed technical description of this error, used in debugging. */
708
+ debugDescription: string;
709
+ }
710
+ /**
711
+ * An error raised by the RPC bridge itself rather than by a RecordKit recording — for example
712
+ * calling a method on a recorder that was already cancelled, requesting a feature that needs a
713
+ * newer macOS version, or referencing a window or camera that cannot be found.
714
+ *
715
+ * Distinguished from {@link RecordKitError} and {@link NSErrorPayload} by its `name` discriminator.
716
+ *
717
+ * @group Recording
718
+ */
719
+ export interface RPCErrorPayload {
720
+ name: "RPCError";
721
+ /** Message describing the problem, intended to be shown directly to the end-user. */
722
+ message: string;
723
+ /** The same message as {@link RPCErrorPayload.message}, kept under its legacy field name. */
724
+ userMessage: string;
725
+ /** Detailed technical description of this error, used in debugging. */
726
+ debugDescription: string;
727
+ }
728
+ /**
729
+ * Describes a recording bundle's contents (the parsed `recordkit.json`). Mirrors the Swift
730
+ * `RKBundleInfo`; the per-event sidecar types live in `RecordingMetadata.ts`.
731
+ *
349
732
  * @group Recording
350
733
  */
351
734
  export interface BundleInfo {
352
735
  version: 1;
736
+ /** Total duration of the recording, in seconds. */
737
+ duration: number;
353
738
  files: {
354
739
  type: 'screen' | 'webcam' | 'audio' | 'mouse' | 'systemAudio' | 'appleDevice' | 'topWindow';
355
740
  filename: string;
741
+ /** Filenames of related sidecar files for this asset (e.g. input-event JSON), relative to the bundle. */
742
+ related?: string[];
743
+ /** Logical size of the recorded area, in points (e.g. `2560x1440` for a Retina 5K display). */
744
+ recordingSize?: {
745
+ width: number;
746
+ height: number;
747
+ };
748
+ /** Dimensions of the output video, in pixels. */
749
+ videoDimensions?: {
750
+ width: number;
751
+ height: number;
752
+ };
356
753
  }[];
357
754
  }
755
+ export {};