@appium/coresim 1.5.0 → 1.7.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +14 -0
  3. package/binding.gyp +7 -0
  4. package/lib/src/commands/video-recording.d.ts +26 -10
  5. package/lib/src/commands/video-recording.d.ts.map +1 -1
  6. package/lib/src/commands/video-recording.js +55 -16
  7. package/lib/src/commands/video-recording.js.map +1 -1
  8. package/lib/src/commands/video-stream.d.ts +55 -7
  9. package/lib/src/commands/video-stream.d.ts.map +1 -1
  10. package/lib/src/commands/video-stream.js +37 -35
  11. package/lib/src/commands/video-stream.js.map +1 -1
  12. package/lib/src/index.d.ts +1 -1
  13. package/lib/src/index.d.ts.map +1 -1
  14. package/lib/src/index.js.map +1 -1
  15. package/lib/src/native-simctl.js +12 -1
  16. package/lib/src/native-simctl.js.map +1 -1
  17. package/lib/src/types.d.ts +82 -10
  18. package/lib/src/types.d.ts.map +1 -1
  19. package/lib/src/utils/index.d.ts +1 -1
  20. package/lib/src/utils/index.d.ts.map +1 -1
  21. package/lib/src/utils/index.js +1 -1
  22. package/lib/src/utils/index.js.map +1 -1
  23. package/lib/src/utils/run-catching.d.ts +4 -0
  24. package/lib/src/utils/run-catching.d.ts.map +1 -1
  25. package/lib/src/utils/run-catching.js +11 -0
  26. package/lib/src/utils/run-catching.js.map +1 -1
  27. package/package.json +1 -1
  28. package/prebuilds/darwin-arm64/@appium+coresim.node +0 -0
  29. package/src/commands/video-recording.ts +75 -25
  30. package/src/commands/video-stream.ts +48 -39
  31. package/src/coresim.mm +547 -118
  32. package/src/index.ts +1 -0
  33. package/src/native/audio_encoder.h +65 -0
  34. package/src/native/audio_encoder.mm +270 -0
  35. package/src/native/av_recording.h +52 -0
  36. package/src/native/av_recording.mm +424 -0
  37. package/src/native/av_stream.h +70 -0
  38. package/src/native/av_stream.mm +217 -0
  39. package/src/native/monotonic_clock.h +20 -0
  40. package/src/native/sim_audio_tap.h +67 -0
  41. package/src/native/sim_audio_tap.mm +350 -0
  42. package/src/native/sim_process.h +10 -0
  43. package/src/native/sim_process.mm +81 -18
  44. package/src/native/sim_video_stream.h +14 -11
  45. package/src/native/sim_video_stream.mm +27 -383
  46. package/src/native/video_encoder.h +76 -0
  47. package/src/native/video_encoder.mm +417 -0
  48. package/src/native-simctl.ts +12 -1
  49. package/src/types.ts +95 -11
  50. package/src/utils/index.ts +1 -1
  51. package/src/utils/run-catching.ts +11 -0
@@ -116,9 +116,43 @@ export interface VideoRecordingOptions {
116
116
  /**
117
117
  * For a non-rectangular display (e.g. a Dynamic Island cutout): `'ignored'` (default) saves the
118
118
  * unmasked framebuffer, `'black'` renders the mask black, `'alpha'` is not supported and
119
- * behaves like `'black'`.
119
+ * behaves like `'black'`. Only applies when neither `audio` nor `fps` is set — see their doc
120
+ * comments.
120
121
  */
121
122
  mask?: 'ignored' | 'alpha' | 'black';
123
+ /**
124
+ * Also capture the device's audio into the same file, muxed as a second track. Defaults to
125
+ * `false`. Requires macOS 14.2+ (Core Audio process taps), the host's "System Audio Recording
126
+ * Only" privacy permission (System Settings > Privacy & Security — cannot be granted
127
+ * programmatically; a denial isn't a thrown error, it surfaces as a silent, audio-less/near-
128
+ * silent recording), a default audio output device on the host, and a booted device that has
129
+ * produced audio at least once. See the README's "Screen capture" section for the full
130
+ * requirements list and known failure modes.
131
+ *
132
+ * Like an explicit `fps`, this switches the implementation to this addon's own VideoToolbox +
133
+ * Core Audio encoders instead of CoreSimulator's private recorder, which can't mux audio.
134
+ */
135
+ audio?: boolean;
136
+ /**
137
+ * Max frames/sec to poll the framebuffer at — see {@link VideoStreamOptions} `fps` for the
138
+ * identical semantics. Meaningless against CoreSimulator's private recorder (it captures on its
139
+ * own cadence, not one we poll), so setting `fps` — even without `audio` — switches this
140
+ * recording to the same own-encoder implementation `audio` does. That switch costs `mask`
141
+ * support, which only the private recorder implements.
142
+ */
143
+ fps?: number;
144
+ /** Target average bitrate, in bits/sec. Respected on either implementation. */
145
+ bitrate?: number;
146
+ }
147
+ /** Options for `NativeSimctl.stopVideoRecording`. */
148
+ export interface StopVideoRecordingOptions {
149
+ /**
150
+ * Best-effort: still attempts the native stop, but releases this device's tracked-active-
151
+ * recording bookkeeping regardless of whether that attempt succeeds, instead of leaving it
152
+ * retryable — see the doc comment above `NativeSimctl.stopVideoRecording` for when a caller
153
+ * needs this over a plain retry.
154
+ */
155
+ force?: boolean;
122
156
  }
123
157
  /** Options for `NativeSimctl.startVideoStream`. */
124
158
  export interface VideoStreamOptions {
@@ -136,17 +170,29 @@ export interface VideoStreamOptions {
136
170
  fps?: number;
137
171
  /** Target average bitrate, in bits/sec. Defaults to 2,000,000 (2 Mbps). */
138
172
  bitrate?: number;
173
+ /**
174
+ * Also stream the device's audio, interleaved into the same `accessUnits()` sequence. Defaults
175
+ * to `false`. Same requirements and failure modes as {@link VideoRecordingOptions.audio} — see
176
+ * its doc comment and the README's "Screen capture" section.
177
+ */
178
+ audio?: boolean;
139
179
  }
140
180
  /**
141
- * One encoded frame from `VideoStream.accessUnits()` — Annex-B NAL units. A keyframe's `data` has
142
- * parameter sets (SPS/PPS, or VPS/SPS/PPS for HEVC) prepended, so it's self-decodable alone.
181
+ * One encoded unit from `VideoStream.accessUnits()`, discriminated by `track`: a video unit
182
+ * (Annex-B NAL units — a keyframe's `data` has parameter sets, SPS/PPS or VPS/SPS/PPS for HEVC,
183
+ * prepended, so it's self-decodable alone) or, when {@link VideoStreamOptions.audio} was set, an
184
+ * interleaved audio unit (an ADTS-framed AAC-LC packet — the 7-byte ADTS header carries sample
185
+ * rate/channel count itself, so no separate decoder-config exchange is needed; always
186
+ * independently decodable, so `isKeyFrame` is always `true`). Without `audio`, every unit has
187
+ * `track: 'video'`.
143
188
  */
144
189
  export interface VideoAccessUnit {
190
+ track: 'video' | 'audio';
145
191
  data: Buffer;
146
192
  isKeyFrame: boolean;
147
- /** Monotonically increasing per stream, starting at 0. */
193
+ /** Monotonically increasing per track, starting at 0 — independent between `'video'` and `'audio'`. */
148
194
  sequence: number;
149
- /** Microseconds since the stream started. */
195
+ /** Microseconds since the stream started, on one shared clock across both tracks. */
150
196
  timestampMicros: number;
151
197
  }
152
198
  /**
@@ -242,6 +288,7 @@ export interface NativeSpawnResult {
242
288
  export type NativeSpawnExitCallback = (code: number | null, signal: number | null) => void;
243
289
  /** Raw shape of an access unit as the native addon delivers it — see {@link VideoAccessUnit}. */
244
290
  export interface NativeVideoAccessUnit {
291
+ track: 'video' | 'audio';
245
292
  data: Buffer;
246
293
  isKeyFrame: boolean;
247
294
  sequence: number;
@@ -249,12 +296,27 @@ export interface NativeVideoAccessUnit {
249
296
  }
250
297
  export type NativeVideoAccessUnitCallback = (unit: NativeVideoAccessUnit) => void;
251
298
  export type NativeVideoErrorCallback = (err: Error) => void;
252
- /** A live encoder session, wrapped by `coresim.mm`'s `NativeVideoStream` — what `NativeDeviceHandle.startVideoStream()` resolves to. */
299
+ /**
300
+ * A live encoder session, wrapped by `coresim.mm`'s `NativeVideoStream` (video only) or
301
+ * `NativeAVStream` (`audio: true` — see {@link VideoStreamOptions}) — either way, what
302
+ * `NativeDeviceHandle.startVideoStream()` resolves to; the two native wrapper classes expose the
303
+ * identical shape below, so callers never need to know which one they got.
304
+ */
253
305
  export interface NativeVideoStreamHandle {
254
306
  stop(): Promise<void>;
255
- /** Forces the next encoded frame to be a keyframe — trivial in-memory flag, so synchronous. */
307
+ /** Forces the next encoded video frame to be a keyframe — trivial in-memory flag, so synchronous. */
256
308
  requestKeyFrame(): void;
257
309
  }
310
+ /**
311
+ * A live recording, wrapped by `coresim.mm`'s `NativePrivateRecordingHandle` (video only,
312
+ * addressing CoreSimulator's own internally-tracked private recorder) or `NativeAVRecording`
313
+ * (`audio: true` — see {@link VideoRecordingOptions}, a real local resource with no server-side
314
+ * counterpart) — either way, what `NativeDeviceHandle.startVideoRecording()` resolves to.
315
+ */
316
+ export interface NativeVideoRecordingHandle {
317
+ /** Resolves once the output file has been finalized on disk and is safe to read. */
318
+ stop(): Promise<void>;
319
+ }
258
320
  /** A `SimDevice`, wrapped by `coresim.mm`'s `NativeDevice` — what `NativeSimctl`'s `_findDevice()` resolves to. */
259
321
  export interface NativeDeviceHandle {
260
322
  udid(): string;
@@ -305,17 +367,20 @@ export interface NativeDeviceHandle {
305
367
  quality?: number;
306
368
  }): Promise<Buffer>;
307
369
  getDisplays(): Promise<SimDisplayInfo[]>;
308
- startVideoRecording(outputFile: string, options?: {
370
+ startVideoRecording(outputFile: string, options: {
309
371
  displayId?: string;
310
372
  codec?: 'h264' | 'hevc';
311
373
  mask?: 'ignored' | 'alpha' | 'black';
312
- }): Promise<void>;
313
- stopVideoRecording(): Promise<void>;
374
+ audio?: boolean;
375
+ fps?: number;
376
+ bitrate?: number;
377
+ } | undefined, onError: NativeVideoErrorCallback): Promise<NativeVideoRecordingHandle>;
314
378
  startVideoStream(options: {
315
379
  displayId?: string;
316
380
  codec?: 'h264' | 'hevc';
317
381
  fps?: number;
318
382
  bitrate?: number;
383
+ audio?: boolean;
319
384
  } | undefined, onAccessUnit: NativeVideoAccessUnitCallback, onError: NativeVideoErrorCallback): Promise<NativeVideoStreamHandle>;
320
385
  spawn(path: string, options: SpawnOptions | undefined, onExit: NativeSpawnExitCallback): Promise<NativeSpawnResult>;
321
386
  }
@@ -336,5 +401,12 @@ export interface NativeServiceContextHandle {
336
401
  export interface NativeCoreSimModule {
337
402
  sharedServiceContext(developerDir: string): Promise<NativeServiceContextHandle>;
338
403
  frameworkVersion(): Promise<string>;
404
+ /**
405
+ * Synchronously (not a Promise) stops every still-live video/AV stream or AV recording, blocking
406
+ * until each has released its resources. Meant to be called from a `process.on('exit', ...)`
407
+ * listener (see native-simctl.ts) — cleanup hooks alone don't run under `process.exit()` on the
408
+ * main process/thread, only on a natural empty-event-loop exit or a Worker's own termination.
409
+ */
410
+ flushActiveSessions(): void;
339
411
  }
340
412
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  export { getPkgRoot, PACKAGE_NAME } from './pkg-root.js';
2
- export { runCatchingAsync } from './run-catching.js';
2
+ export { runCatchingAsync, toTypedError } from './run-catching.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AACvD,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AACvD,OAAO,EAAC,gBAAgB,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC"}
@@ -1,3 +1,3 @@
1
1
  export { getPkgRoot, PACKAGE_NAME } from './pkg-root.js';
2
- export { runCatchingAsync } from './run-catching.js';
2
+ export { runCatchingAsync, toTypedError } from './run-catching.js';
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AACvD,OAAO,EAAC,gBAAgB,EAAC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AACvD,OAAO,EAAC,gBAAgB,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC"}
@@ -1,3 +1,7 @@
1
1
  /** Shared by NativeSimctl and every `src/commands/*.ts` mixin — maps a raw error surfaced by the addon to a typed one. */
2
2
  export declare function runCatchingAsync<T>(fn: () => Promise<T>): Promise<T>;
3
+ /** `wrapNativeError` always throws — this just gets its thrown value back as a plain return, for
4
+ * a live callback (e.g. a stream/recording's `onError`) that needs to emit or log a typed error
5
+ * rather than raise it. */
6
+ export declare function toTypedError(err: unknown): Error;
3
7
  //# sourceMappingURL=run-catching.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-catching.d.ts","sourceRoot":"","sources":["../../../src/utils/run-catching.ts"],"names":[],"mappings":"AAEA,0HAA0H;AAC1H,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAM1E"}
1
+ {"version":3,"file":"run-catching.d.ts","sourceRoot":"","sources":["../../../src/utils/run-catching.ts"],"names":[],"mappings":"AAEA,0HAA0H;AAC1H,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAM1E;AAED;;2BAE2B;AAC3B,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,CAMhD"}
@@ -8,4 +8,15 @@ export async function runCatchingAsync(fn) {
8
8
  wrapNativeError(err);
9
9
  }
10
10
  }
11
+ /** `wrapNativeError` always throws — this just gets its thrown value back as a plain return, for
12
+ * a live callback (e.g. a stream/recording's `onError`) that needs to emit or log a typed error
13
+ * rather than raise it. */
14
+ export function toTypedError(err) {
15
+ try {
16
+ wrapNativeError(err);
17
+ }
18
+ catch (wrapped) {
19
+ return wrapped;
20
+ }
21
+ }
11
22
  //# sourceMappingURL=run-catching.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-catching.js","sourceRoot":"","sources":["../../../src/utils/run-catching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAE7C,0HAA0H;AAC1H,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAI,EAAoB;IAC5D,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAe,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"run-catching.js","sourceRoot":"","sources":["../../../src/utils/run-catching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAE7C,0HAA0H;AAC1H,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAI,EAAoB;IAC5D,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAe,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;2BAE2B;AAC3B,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,CAAC;QACH,eAAe,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,OAAO,EAAE,CAAC;QACjB,OAAO,OAAgB,CAAC;IAC1B,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appium/coresim",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "description": "Native bindings to CoreSimulator.framework for Apple platform simulator control",
5
5
  "bugs": {
6
6
  "url": "https://github.com/appium/coresim/issues"
@@ -1,24 +1,31 @@
1
1
  import path from 'node:path';
2
2
 
3
+ import {logger} from '@appium/support';
4
+
3
5
  import type {NativeSimctl} from '../native-simctl.js';
4
- import type {VideoRecordingOptions} from '../types.js';
5
- import {runCatchingAsync} from '../utils/index.js';
6
+ import type {NativeVideoRecordingHandle, StopVideoRecordingOptions, VideoRecordingOptions} from '../types.js';
7
+ import {runCatchingAsync, toTypedError} from '../utils/index.js';
6
8
 
7
9
  declare module '../native-simctl.js' {
8
10
  interface NativeSimctl {
9
11
  startVideoRecording(udid: string, outputFile: string, options?: VideoRecordingOptions): Promise<void>;
10
- stopVideoRecording(udid: string): Promise<void>;
12
+ stopVideoRecording(udid: string, options?: StopVideoRecordingOptions): Promise<void>;
11
13
  isVideoRecording(udid: string): Promise<boolean>;
12
14
  }
13
15
  }
14
16
 
17
+ const log = logger.getLogger('CoreSim');
18
+
15
19
  // One device's recording lifecycle: `start` is the in-flight (or already-settled)
16
- // startVideoRecording call, so a concurrent stopVideoRecording can always wait for it to fully
17
- // resolve before racing it natively. `stop`, once set, is the in-flight native stop call shared by
18
- // every concurrent stopVideoRecording for this same recording — see stopVideoRecording for why a
19
- // second one must reuse it rather than issuing its own.
20
+ // startVideoRecording call, resolving to the live native handle — with both `options.audio` and
21
+ // `options.fps` unset, this addresses CoreSimulator's own internally-tracked private recorder (no
22
+ // real local resource, same as before this field existed); with either set, it's a real local
23
+ // resource (this addon's own encoders) with no server-side counterpart, so a handle is the only
24
+ // way to stop it either way. `stop`, once set, is the in-flight native stop call shared by every
25
+ // concurrent stopVideoRecording for this same recording — see stopVideoRecording for why a second
26
+ // one must reuse it rather than issuing its own.
20
27
  interface RecordingState {
21
- readonly start: Promise<void>;
28
+ readonly start: Promise<NativeVideoRecordingHandle>;
22
29
  stop?: Promise<void>;
23
30
  }
24
31
 
@@ -27,17 +34,24 @@ interface RecordingState {
27
34
  const activeRecordings = new Map<string, RecordingState>();
28
35
 
29
36
  /**
30
- * Starts recording the device's display to `outputFile` — the native equivalent of `simctl io
31
- * <udid> recordVideo`. Resolves once the first frame has actually been recorded, so it's always
32
- * safe to call {@link stopVideoRecording} immediately after. Only one recording may be active per
33
- * device at a time; starting a second one while the first is still running rejects. Rejects with
34
- * `NativeSimUnavailableError` if this CoreSimulator predates the private capture API — confirmed
35
- * missing on Xcode 16.4's, present on Xcode 26.5+ (Apple documents no exact version floor).
37
+ * Starts recording the device's display (and, with `options.audio`, its audio too, muxed as a
38
+ * second track) to `outputFile` — the native equivalent of `simctl io <udid> recordVideo` when
39
+ * both `audio` and `fps` are unset. Resolves once the first frame has actually been recorded, so
40
+ * it's always safe to call {@link stopVideoRecording} immediately after. Only one recording may be
41
+ * active per device at a time; starting a second one while the first is still running rejects.
42
+ *
43
+ * Without `audio`/`fps`, rejects with `NativeSimUnavailableError` if this CoreSimulator predates
44
+ * the private capture API — confirmed missing on Xcode 16.4's, present on Xcode 26.5+ (Apple
45
+ * documents no exact version floor). With either set, see {@link VideoRecordingOptions.audio}'s
46
+ * own doc comment for the host-permission requirement that applies specifically to `audio`; a
47
+ * failure *after* this call has already resolved (e.g. the audio tap's guest process set vanishing
48
+ * mid-recording) doesn't reject it — it's logged here instead — call {@link stopVideoRecording} to
49
+ * observe it as a rejection and release the recording's resources.
36
50
  *
37
51
  * @param udid — UDID of the device to record; must be booted
38
52
  * @param outputFile — filesystem path to write the video to; resolved against `process.cwd()` if
39
53
  * relative, since the native layer requires an absolute path
40
- * @param options — `displayId`, `codec`, `mask` — see {@link VideoRecordingOptions}
54
+ * @param options — `displayId`, `codec`, `mask`, `audio`, `fps`, `bitrate` — see {@link VideoRecordingOptions}
41
55
  * @throws {Error} if a recording is already in progress for this device
42
56
  */
43
57
  export async function startVideoRecording(
@@ -46,13 +60,28 @@ export async function startVideoRecording(
46
60
  outputFile: string,
47
61
  options: VideoRecordingOptions = {},
48
62
  ): Promise<void> {
63
+ // Mirrors startVideoStream's identical validation — both reach the same native encoder path,
64
+ // which otherwise silently truncates an out-of-range value instead of rejecting it.
65
+ if (options.fps !== undefined && (!Number.isFinite(options.fps) || options.fps < 1)) {
66
+ throw new RangeError(`fps must be a finite number >= 1, got ${options.fps}`);
67
+ }
68
+ if (
69
+ options.bitrate !== undefined &&
70
+ (!Number.isFinite(options.bitrate) || options.bitrate <= 0 || options.bitrate > 2 ** 31 - 1)
71
+ ) {
72
+ throw new RangeError(`bitrate must be a positive number no greater than ${2 ** 31 - 1}, got ${options.bitrate}`);
73
+ }
49
74
  const key = udid.toLowerCase();
50
75
  if (activeRecordings.has(key)) {
51
76
  throw new Error(`A video recording is already in progress for device '${udid}'`);
52
77
  }
53
78
  const absoluteOutputFile = path.resolve(outputFile);
54
79
  const startPromise = runCatchingAsync(async () =>
55
- (await this._findDevice(udid)).startVideoRecording(absoluteOutputFile, options),
80
+ (await this._findDevice(udid)).startVideoRecording(absoluteOutputFile, options, (err) => {
81
+ // Only ever invoked on the `audio`/`fps` (own-encoder) path — see its own doc comment above.
82
+ // No live consumer to report to (this call already resolved), so logged instead of lost.
83
+ log.error(`Unhandled video recording error for device '${udid}': ${toTypedError(err).stack ?? err}`);
84
+ }),
56
85
  );
57
86
  // Marked before the native call resolves, not after, so a concurrent startVideoRecording for the
58
87
  // same device is rejected immediately instead of racing this one — rolled back below on failure.
@@ -83,34 +112,55 @@ export async function startVideoRecording(
83
112
  * device-lookup error — leaves the recording tracked as still active so a retry can reach the
84
113
  * native call rather than the caller losing the ability to stop it at all.
85
114
  *
115
+ * That retryability is a liability if nothing ever *does* retry — e.g. a best-effort teardown path
116
+ * that must not throw, so it logs a failed stop and moves on — since without `options.force` there
117
+ * is no other way to release the entry, permanently blocking a new `startVideoRecording` for this
118
+ * device. Pass `options.force: true` in that situation: it still attempts the native stop (so the
119
+ * encoder/file gets a chance to finalize cleanly) but releases the entry unconditionally afterward
120
+ * and never rejects, even if that attempt failed — understand that this can leave a native
121
+ * resource dangling if the stop genuinely never lands.
122
+ *
86
123
  * @param udid — UDID of the device to stop recording
124
+ * @param options — `force` (see above)
87
125
  * @throws {Error} if no recording is currently in progress for this device
88
126
  */
89
- export async function stopVideoRecording(this: NativeSimctl, udid: string): Promise<void> {
127
+ export async function stopVideoRecording(
128
+ this: NativeSimctl,
129
+ udid: string,
130
+ options: StopVideoRecordingOptions = {},
131
+ ): Promise<void> {
90
132
  const key = udid.toLowerCase();
91
133
  const state = activeRecordings.get(key);
92
134
  if (!state) {
93
135
  throw new Error(`No video recording is in progress for device '${udid}'`);
94
136
  }
137
+ let handle: NativeVideoRecordingHandle;
95
138
  try {
96
- await state.start;
139
+ handle = await state.start;
97
140
  } catch {
98
141
  // start itself failed — its own catch already cleaned up activeRecordings; nothing to stop.
99
142
  throw new Error(`No video recording is in progress for device '${udid}'`);
100
143
  }
101
- const stopPromise = (state.stop ??= runCatchingAsync(async () =>
102
- (await this._findDevice(udid)).stopVideoRecording(),
103
- ));
144
+ const stopPromise = (state.stop ??= runCatchingAsync(async () => {
145
+ await handle.stop();
146
+ }));
104
147
  try {
105
148
  await stopPromise;
106
149
  } catch (e) {
107
- // Only clear our own attempt, and only if it's still the current one — a future call must be
108
- // able to retry the native stop rather than replaying this same rejection forever, but must
109
- // not clobber a newer attempt another concurrent caller may have already started instead.
150
+ // Only clear our own attempt, and only if it's still the current one — a future (non-forced)
151
+ // call must be able to retry the native stop rather than replaying this same rejection
152
+ // forever, but must not clobber a newer attempt another concurrent caller may have already
153
+ // started instead.
110
154
  if (state.stop === stopPromise) {
111
155
  state.stop = undefined;
112
156
  }
113
- throw e;
157
+ if (!options.force) {
158
+ throw e;
159
+ }
160
+ log.warn(
161
+ `Force-releasing video recording bookkeeping for device '${udid}' despite a failed native stop: ` +
162
+ `${toTypedError(e).stack ?? e}`,
163
+ );
114
164
  }
115
165
  if (activeRecordings.get(key) === state) {
116
166
  activeRecordings.delete(key);
@@ -2,10 +2,9 @@ import {EventEmitter} from 'node:events';
2
2
 
3
3
  import {logger} from '@appium/support';
4
4
 
5
- import {wrapNativeError} from '../errors.js';
6
5
  import type {NativeSimctl} from '../native-simctl.js';
7
6
  import type {NativeVideoStreamHandle, VideoAccessUnit, VideoStreamOptions} from '../types.js';
8
- import {runCatchingAsync} from '../utils/index.js';
7
+ import {runCatchingAsync, toTypedError} from '../utils/index.js';
9
8
 
10
9
  declare module '../native-simctl.js' {
11
10
  interface NativeSimctl {
@@ -20,55 +19,57 @@ const log = logger.getLogger('CoreSim');
20
19
  // backpressure: _handleAccessUnit's emit-equivalent push always returns immediately, regardless of
21
20
  // how slow the actual accessUnits() consumer is, so without a bound of its own this queue could
22
21
  // otherwise grow without limit while a slow consumer falls behind.
23
- const MAX_BUFFERED_UNITS = 60;
22
+ export const MAX_BUFFERED_UNITS = 60;
24
23
 
25
24
  const SINGLE_CONSUMER_ERROR =
26
25
  'VideoStream.accessUnits() supports only one active consumer at a time — a second concurrent call rejects.';
27
26
 
28
- /** `wrapNativeError` always throws — this just gets its thrown value back as a plain return, to emit rather than raise it. */
29
- function toTypedError(err: unknown): Error {
30
- try {
31
- wrapNativeError(err);
32
- } catch (wrapped) {
33
- return wrapped as Error;
34
- }
35
- }
36
-
37
27
  /**
38
28
  * Single-consumer FIFO between native's per-frame callback and `accessUnits()`. Unlike routing
39
29
  * through `EventEmitter`, a unit pushed before any consumer has started iterating is retained
40
30
  * (fixing the encoder's own first-frame/keyframe otherwise being lost to a startup race) rather
41
31
  * than silently dropped.
42
32
  *
43
- * Bounded at `MAX_BUFFERED_UNITS`, but codec-aware about *how* it sheds load once a slow consumer
44
- * falls behind: since frames only reference earlier frames they were encoded against (no
45
- * `AllowFrameReordering`), dropping an arbitrary interframe would orphan every later one from its
33
+ * Bounded at `MAX_BUFFERED_UNITS`, but resync-aware about *how* it sheds load once a slow consumer
34
+ * falls behind: since interframes only reference earlier frames they were encoded against (no
35
+ * `AllowFrameReordering`), dropping an arbitrary one would orphan every later one from its
46
36
  * reference chain, corrupting decode from that point on even though delivery looks unbroken.
47
- * Overflow instead clears the backlog entirely and enters a resync state, discarding every
48
- * further interframe (not buffering them) until the next keyframe — self-decodable on its own —
49
- * lets delivery resume cleanly.
37
+ * Overflow instead clears the backlog entirely and enters a resync state — `dropsDuringResync`
38
+ * decides which further units to discard (not buffer) until `endsResync` sees a self-decodable
39
+ * point to resume clean delivery from. Generic (not hardcoded to video's own reference-chain
40
+ * concern) so `VideoStream` can reuse this same machinery when it's carrying interleaved audio
41
+ * too (`VideoStreamOptions.audio`) — an audio unit is always independently decodable, so it's
42
+ * configured to never be dropped and never itself end a resync; only video interframes are.
50
43
  */
51
- class AccessUnitQueue {
52
- private readonly buffer: VideoAccessUnit[] = [];
53
- private waiter:
54
- | {resolve: (result: IteratorResult<VideoAccessUnit>) => void; reject: (err: unknown) => void}
55
- | undefined;
44
+ export class AccessUnitQueue<T> {
45
+ private readonly buffer: T[] = [];
46
+ private waiter: {resolve: (result: IteratorResult<T>) => void; reject: (err: unknown) => void} | undefined;
56
47
  private ended = false;
57
48
  private error: unknown;
58
49
  private resyncing = false;
59
50
 
60
- /** @param onOverflow — called once when overflow first forces a resync, e.g. to request a fresh keyframe. */
61
- constructor(private readonly onOverflow?: () => void) {}
51
+ constructor(
52
+ private readonly opts: {
53
+ /** Whether `unit` should be discarded (not buffered) while resyncing. */
54
+ dropsDuringResync: (unit: T) => boolean;
55
+ /** Whether `unit` is a self-decodable point resync can resume clean delivery from. */
56
+ endsResync: (unit: T) => boolean;
57
+ /** Called once when overflow first forces a resync, e.g. to request a fresh keyframe. */
58
+ onOverflow?: () => void;
59
+ },
60
+ ) {}
62
61
 
63
- push(unit: VideoAccessUnit): void {
62
+ push(unit: T): void {
64
63
  if (this.ended) {
65
64
  return;
66
65
  }
67
66
  if (this.resyncing) {
68
- if (!unit.isKeyFrame) {
67
+ if (this.opts.dropsDuringResync(unit)) {
69
68
  return; // still waiting for a self-decodable point to resume delivery from
70
69
  }
71
- this.resyncing = false;
70
+ if (this.opts.endsResync(unit)) {
71
+ this.resyncing = false;
72
+ }
72
73
  }
73
74
  if (this.waiter) {
74
75
  const {resolve} = this.waiter;
@@ -80,7 +81,7 @@ class AccessUnitQueue {
80
81
  if (this.buffer.length > MAX_BUFFERED_UNITS) {
81
82
  this.buffer.length = 0;
82
83
  this.resyncing = true;
83
- this.onOverflow?.();
84
+ this.opts.onOverflow?.();
84
85
  }
85
86
  }
86
87
 
@@ -119,7 +120,7 @@ class AccessUnitQueue {
119
120
  * queue never hands out a stale buffered unit — an aborted consumer, or a fresh iterator started
120
121
  * after `stop()`, must see the boundary immediately rather than draining leftovers first.
121
122
  */
122
- next(signal: AbortSignal): Promise<IteratorResult<VideoAccessUnit>> {
123
+ next(signal: AbortSignal): Promise<IteratorResult<T>> {
123
124
  if (signal.aborted) {
124
125
  return Promise.resolve({value: undefined, done: true});
125
126
  }
@@ -151,8 +152,9 @@ class AccessUnitQueue {
151
152
  }
152
153
 
153
154
  /**
154
- * A live video stream from `NativeSimctl.startVideoStream` — encodes the device's display in real
155
- * time via VideoToolbox, unlike `startVideoRecording`, which drives CoreSimulator's own private,
155
+ * A live video stream from `NativeSimctl.startVideoStream` — encodes the device's display (and,
156
+ * with `options.audio`, its audio too — see {@link VideoStreamOptions}) in real time via
157
+ * VideoToolbox/Core Audio, unlike `startVideoRecording`, which drives CoreSimulator's own private,
156
158
  * file-only recorder. Mirrors `appium-ios-remotexpc`'s `ScreenStreamCapture` shape
157
159
  * (`accessUnits()`/`stop()`) for API consistency; the transport is otherwise unrelated.
158
160
  */
@@ -162,8 +164,14 @@ export class VideoStream extends EventEmitter {
162
164
  private stopPromise: Promise<void> | undefined;
163
165
  // Requests a fresh keyframe on resync so delivery can resume immediately rather than waiting
164
166
  // for the next periodic one — `handle` may not be attached yet on a startup-time overflow
165
- // (vanishingly unlikely given MAX_BUFFERED_UNITS), in which case this is just a no-op.
166
- private readonly queue = new AccessUnitQueue(() => this.handle?.requestKeyFrame());
167
+ // (vanishingly unlikely given MAX_BUFFERED_UNITS), in which case this is just a no-op. Only a
168
+ // video keyframe ends/is exempt from resync — an audio unit (when present) is always
169
+ // independently decodable, so it's never dropped and never itself ends a resync.
170
+ private readonly queue = new AccessUnitQueue<VideoAccessUnit>({
171
+ dropsDuringResync: (unit) => unit.track === 'video' && !unit.isKeyFrame,
172
+ endsResync: (unit) => unit.track === 'video' && unit.isKeyFrame,
173
+ onOverflow: () => this.handle?.requestKeyFrame(),
174
+ });
167
175
  private activeConsumers = 0;
168
176
 
169
177
  /** @internal */
@@ -236,13 +244,14 @@ export class VideoStream extends EventEmitter {
236
244
  }
237
245
 
238
246
  /**
239
- * Starts encoding the device's display in real time. Resolves once the encoder has actually
240
- * started; the returned {@link VideoStream}'s `accessUnits()` then yields each frame as it
241
- * arrives. Independent of `startVideoRecording`/`stopVideoRecording` — both, and any number of
242
- * concurrent streams, can run on the same device at once.
247
+ * Starts encoding the device's display (and, with `options.audio`, its audio) in real time.
248
+ * Resolves once the encoder(s) have actually started; the returned {@link VideoStream}'s
249
+ * `accessUnits()` then yields each unit as it arrives. Independent of
250
+ * `startVideoRecording`/`stopVideoRecording` — both, and any number of concurrent streams, can
251
+ * run on the same device at once.
243
252
  *
244
253
  * @param udid — UDID of the device to stream; must be booted
245
- * @param options — `displayId`, `codec`, `fps`, `bitrate` — see {@link VideoStreamOptions}
254
+ * @param options — `displayId`, `codec`, `fps`, `bitrate`, `audio` — see {@link VideoStreamOptions}
246
255
  */
247
256
  export async function startVideoStream(
248
257
  this: NativeSimctl,