@alpha2-sh/node 0.0.0-stage → 0.1.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/LICENSE.md +21 -0
- package/README.md +82 -2
- package/dist/index.d.ts +814 -0
- package/dist/index.js +1054 -0
- package/dist/protocol.d.ts +64 -0
- package/dist/protocol.js +97 -0
- package/package.json +41 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
import type { AssetCatalog, ConformReport, MediaPurpose, Selection } from "alpha2/assets";
|
|
2
|
+
import type { CapabilityReport } from "alpha2";
|
|
3
|
+
import type { ExportFailure, ExportPhase } from "alpha2/export-failure";
|
|
4
|
+
import type { BuiltinEffectCatalog, EffectDefinition } from "alpha2/effects";
|
|
5
|
+
import type { FrameRate, MediaFingerprint, Project } from "alpha2/project";
|
|
6
|
+
import { type ProgressPhase } from "./protocol.js";
|
|
7
|
+
export { PROTOCOL_VERSION } from "./protocol.js";
|
|
8
|
+
export type { ProgressPhase } from "./protocol.js";
|
|
9
|
+
export type { ExportFailure } from "alpha2/export-failure";
|
|
10
|
+
/** Where to find `alpha2-host`; see {@link resolveHostBinary}. */
|
|
11
|
+
export interface ResolveHostBinaryOptions {
|
|
12
|
+
/** Exact binary path. Takes precedence over every discovery mechanism. */
|
|
13
|
+
readonly hostPath?: string;
|
|
14
|
+
/** Electron's `process.resourcesPath`, injectable for non-Electron callers. */
|
|
15
|
+
readonly resourcesPath?: string;
|
|
16
|
+
/** Base directory for relative explicit paths. Defaults to `process.cwd()`. */
|
|
17
|
+
readonly cwd?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Options of an {@link Alpha2NodeClient}. */
|
|
20
|
+
export interface Alpha2NodeOptions extends ResolveHostBinaryOptions {
|
|
21
|
+
/** Maximum simultaneous sidecars. Defaults to one. */
|
|
22
|
+
readonly concurrency?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Video decode path for every request this client makes. When it is unset the host uses its
|
|
25
|
+
* platform default, which is "auto" on Linux and "software" on macOS and Windows. "auto" uses the
|
|
26
|
+
* GPU decoder where the device and stream support it, and "hardware-required" fails instead of
|
|
27
|
+
* decoding a video frame on the CPU.
|
|
28
|
+
*/
|
|
29
|
+
readonly videoDecode?: VideoDecodeMode;
|
|
30
|
+
}
|
|
31
|
+
/** Video decode path requested from the native host. */
|
|
32
|
+
export type VideoDecodeMode = "software" | "auto" | "hardware-required";
|
|
33
|
+
/**
|
|
34
|
+
* The engine's five quality levels. The engine defines what each one costs (a bitrate that depends
|
|
35
|
+
* on codec, output size and frame rate) and the host resolves it before the encoder opens; an app
|
|
36
|
+
* maps its own presets onto these rather than inventing rates.
|
|
37
|
+
*/
|
|
38
|
+
export type QualityLevel = "very-low" | "low" | "medium" | "high" | "very-high";
|
|
39
|
+
/** Every {@link QualityLevel}, lowest first. */
|
|
40
|
+
export declare const QUALITY_LEVELS: readonly QualityLevel[];
|
|
41
|
+
/** A quality level, or an explicit rate in bits per second. */
|
|
42
|
+
export type VideoQuality = QualityLevel | {
|
|
43
|
+
readonly bitrate: number;
|
|
44
|
+
/** Defaults to `variable`. */
|
|
45
|
+
readonly mode?: "constant" | "variable";
|
|
46
|
+
/**
|
|
47
|
+
* A constant quantizer on the codec's own scale (0-51 for H.264). The encoder runs it where
|
|
48
|
+
* it can and falls back to `bitrate` where it cannot; `videoRateControl.applied` reports
|
|
49
|
+
* which ran.
|
|
50
|
+
*/
|
|
51
|
+
readonly quantizer?: number;
|
|
52
|
+
};
|
|
53
|
+
/** A quality level, or an explicit stereo bitrate in bits per second. */
|
|
54
|
+
export type AudioQuality = QualityLevel | {
|
|
55
|
+
readonly bitrate: number;
|
|
56
|
+
};
|
|
57
|
+
/** The rate an export actually encoded video at, as the host resolved it. */
|
|
58
|
+
export interface ResolvedVideoRateControl {
|
|
59
|
+
readonly bitrate: number;
|
|
60
|
+
readonly mode: "constant" | "variable";
|
|
61
|
+
readonly quantizer: number | null;
|
|
62
|
+
/**
|
|
63
|
+
* What the encoder ran: `quantizer`, or `bitrate` because none was asked for or because the
|
|
64
|
+
* encoder refused it (`quantizerRefused` says why).
|
|
65
|
+
*/
|
|
66
|
+
readonly applied: "quantizer" | "bitrate";
|
|
67
|
+
readonly quantizerRefused: string | null;
|
|
68
|
+
/** The level the request named, or null for an explicit rate. */
|
|
69
|
+
readonly level: QualityLevel | null;
|
|
70
|
+
/**
|
|
71
|
+
* `env-override` means `ALPHA2_EXPORT_VIDEO_BITRATE` was set in the host's environment and won
|
|
72
|
+
* over the request. It is test instrumentation, never a production setting.
|
|
73
|
+
*/
|
|
74
|
+
readonly source: "request" | "env-override";
|
|
75
|
+
}
|
|
76
|
+
/** Whether an export may copy its source's packets; see {@link ExportProjectRequest.strategy}. */
|
|
77
|
+
export type ExportStrategy = "render" | "prefer-copy" | "require-copy";
|
|
78
|
+
/** How an export's encoder receives frames; see {@link ExportProjectRequest.inputPolicy}. */
|
|
79
|
+
export type InputPolicy = "auto" | "gpu-required" | "cpu-readback";
|
|
80
|
+
/** One progress report of an export. */
|
|
81
|
+
export interface ExportProgress {
|
|
82
|
+
/**
|
|
83
|
+
* `frames` while frames are encoded; `finalizing` once every frame is and the output is being
|
|
84
|
+
* flushed and closed. The export is complete only when `exportProject` resolves.
|
|
85
|
+
*/
|
|
86
|
+
readonly phase: ProgressPhase;
|
|
87
|
+
/** Frames encoded so far; at most `total`. */
|
|
88
|
+
readonly completed: number;
|
|
89
|
+
/** Frames in the export. */
|
|
90
|
+
readonly total: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Receives an export's progress. A promise it returns is waited for before the export settles, and
|
|
94
|
+
* its rejection fails the export.
|
|
95
|
+
*/
|
|
96
|
+
export type ExportProgressCallback = (progress: ExportProgress) => void | Promise<void>;
|
|
97
|
+
/** Successful metadata returned by the native host after an export. */
|
|
98
|
+
export interface NativeExportResult {
|
|
99
|
+
readonly renderMs: number;
|
|
100
|
+
readonly frames: number;
|
|
101
|
+
readonly audio: boolean;
|
|
102
|
+
readonly fps: number;
|
|
103
|
+
/**
|
|
104
|
+
* Which output path produced this export. Several `performance` counters are structurally absent
|
|
105
|
+
* on one of them rather than merely zero, so a reader comparing two exports needs this to tell
|
|
106
|
+
* the two kinds of zero apart.
|
|
107
|
+
*/
|
|
108
|
+
readonly videoOutputPath: "readback" | "gpu-resident" | "packet-copy";
|
|
109
|
+
/**
|
|
110
|
+
* Why the export took the readback path: the host has no GPU encode device, the codec or a pinned
|
|
111
|
+
* encoder is not the GPU path's, `inputPolicy` is `cpu-readback`, an old validation layer,
|
|
112
|
+
* `ALPHA2_GPU_ENCODE=0`, an output the encoder refuses, or an in-flight budget too small for it.
|
|
113
|
+
* `null` on the GPU-resident path.
|
|
114
|
+
*/
|
|
115
|
+
readonly gpuOutputPathUnavailable: string | null;
|
|
116
|
+
/** The request's {@link ExportProjectRequest.inputPolicy}. */
|
|
117
|
+
readonly inputPolicy: InputPolicy;
|
|
118
|
+
/** What the export did: rendered and encoded every frame, or copied the source's packets. */
|
|
119
|
+
readonly strategy: "render" | "copy";
|
|
120
|
+
/** The request's {@link ExportProjectRequest.strategy}. */
|
|
121
|
+
readonly requestedStrategy: ExportStrategy;
|
|
122
|
+
/** Why a `prefer-copy` export rendered instead; `null` when it copied or did not ask to. */
|
|
123
|
+
readonly copyIneligible: string | null;
|
|
124
|
+
/**
|
|
125
|
+
* A copy's audio: `copy` when the mix is the source's own audio, untouched, over the whole file,
|
|
126
|
+
* so its packets are copied; `encode` when it is mixed as a render mixes it and encoded to AAC
|
|
127
|
+
* beside the copied video; `null` without audio. Absent on rendered exports.
|
|
128
|
+
*/
|
|
129
|
+
readonly audioStrategy?: "copy" | "encode" | null;
|
|
130
|
+
/** Why a copy's audio was encoded rather than copied. Absent on rendered exports. */
|
|
131
|
+
readonly audioCopyIneligible?: string | null;
|
|
132
|
+
/** Clips a copy joined back to back. Absent on rendered exports. */
|
|
133
|
+
readonly copiedSegments?: number;
|
|
134
|
+
/**
|
|
135
|
+
* How a GPU-resident export fed its encoder without rendering: `yuv-repack` when every frame was
|
|
136
|
+
* a source picture shown as it is (the same clips a copy needs, any codec or frame rate, each
|
|
137
|
+
* source already at the output size, upright with square pixels, tagged BT.709 limited 8-bit
|
|
138
|
+
* 4:2:0), so each decoded picture was copied plane for plane into the encoder's input with no
|
|
139
|
+
* graph and no color conversion (`performance.yuvRepacks`, with `graphPasses` and
|
|
140
|
+
* `sourceConversions` zero). `null` when it rendered, and on a copy.
|
|
141
|
+
*/
|
|
142
|
+
readonly videoTranscode: "yuv-repack" | null;
|
|
143
|
+
/** Why a rendered export did not transcode; `null` when it did, and on a copy. */
|
|
144
|
+
readonly yuvTranscodeIneligible: string | null;
|
|
145
|
+
/**
|
|
146
|
+
* The timeline range the export covered: the requested range widened to the frame grid.
|
|
147
|
+
* `startTicks` is the output's zero for video and audio, and can be up to one frame before the
|
|
148
|
+
* requested start.
|
|
149
|
+
*/
|
|
150
|
+
readonly effectiveRange: {
|
|
151
|
+
readonly startTicks: number;
|
|
152
|
+
readonly endTicks: number;
|
|
153
|
+
};
|
|
154
|
+
/** The color pipeline the export ran. */
|
|
155
|
+
readonly color: {
|
|
156
|
+
readonly workingSpace: "linear_bt709_sdr";
|
|
157
|
+
/**
|
|
158
|
+
* What each intermediate picture was stored in: half float wherever the adapter renders,
|
|
159
|
+
* filters, and copies it, 8-bit elsewhere; the tier does not decide it.
|
|
160
|
+
*/
|
|
161
|
+
readonly intermediateFormat: "rgba16float" | "rgba8unorm";
|
|
162
|
+
/** The project's HDR source policy, and the peak HDR sources were taken to reach. */
|
|
163
|
+
readonly hdrSources: "tone_map" | "reject";
|
|
164
|
+
readonly hdrPeakNits: number;
|
|
165
|
+
readonly output: "bt709_sdr";
|
|
166
|
+
};
|
|
167
|
+
/** What the export's render cache did; `null` when it asked for none. */
|
|
168
|
+
readonly renderCache: RenderCacheReport | null;
|
|
169
|
+
/**
|
|
170
|
+
* What extension providers reported they could not draw as asked (a missing font or image, a
|
|
171
|
+
* feature left out, changed samples, a normalized delay), each once per source in the order first
|
|
172
|
+
* seen; `[]` when none did.
|
|
173
|
+
*/
|
|
174
|
+
readonly providerDiagnostics: readonly ProviderDiagnostic[];
|
|
175
|
+
/** Distinct provider reports past the 256 `providerDiagnostics` keeps. */
|
|
176
|
+
readonly providerDiagnosticsOmitted: number;
|
|
177
|
+
/**
|
|
178
|
+
* What the export's decoders reported about damaged input, per source in source ID order: what a
|
|
179
|
+
* `tolerant` decode policy (`ALPHA2_DECODE_POLICY`) skipped, and silence inserted where a clean
|
|
180
|
+
* stream's timestamps jump; `[]` when they reported nothing.
|
|
181
|
+
*/
|
|
182
|
+
readonly decodeDiagnostics: readonly DecodeDiagnostics[];
|
|
183
|
+
/**
|
|
184
|
+
* What the renderer's result cache did: repeated frames and unchanged clip pictures are found
|
|
185
|
+
* instead of drawn, with the same output.
|
|
186
|
+
*/
|
|
187
|
+
readonly resultCache: {
|
|
188
|
+
readonly budgetBytes: number;
|
|
189
|
+
readonly hits: number;
|
|
190
|
+
readonly misses: number;
|
|
191
|
+
readonly ineligible: number;
|
|
192
|
+
readonly inserts: number;
|
|
193
|
+
readonly evictions: number;
|
|
194
|
+
readonly skippedNodes: number;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* The loudness normalization an export asked for: what the mix measured before it, the gain
|
|
198
|
+
* applied (`applied` is the plan, `null` for a mix silent below -70 LUFS), and what the export
|
|
199
|
+
* put out (`output`, measured after the master limiter). `null` when the request had no
|
|
200
|
+
* `loudness`.
|
|
201
|
+
*/
|
|
202
|
+
readonly loudness: {
|
|
203
|
+
readonly targetLufs: number;
|
|
204
|
+
readonly truePeakCeilingDbtp: number;
|
|
205
|
+
/** The master limiter's linear threshold the plan kept the mix under, `null` without one. */
|
|
206
|
+
readonly limiterThreshold: number | null;
|
|
207
|
+
readonly measured: {
|
|
208
|
+
readonly integratedLufs: number | null;
|
|
209
|
+
readonly loudnessRangeLu: number | null;
|
|
210
|
+
readonly truePeakDbtp: number | null;
|
|
211
|
+
readonly samplePeakDbfs: number | null;
|
|
212
|
+
};
|
|
213
|
+
readonly applied: {
|
|
214
|
+
readonly gainDb: number;
|
|
215
|
+
readonly integratedLufs: number;
|
|
216
|
+
readonly truePeakDbtp: number;
|
|
217
|
+
readonly peakLimited: boolean;
|
|
218
|
+
readonly limiterLimited: boolean;
|
|
219
|
+
} | null;
|
|
220
|
+
/** The exported mix, after the master limiter, before the audio encoder. */
|
|
221
|
+
readonly output: {
|
|
222
|
+
readonly integratedLufs: number | null;
|
|
223
|
+
readonly loudnessRangeLu: number | null;
|
|
224
|
+
readonly truePeakDbtp: number | null;
|
|
225
|
+
readonly samplePeakDbfs: number | null;
|
|
226
|
+
};
|
|
227
|
+
} | null;
|
|
228
|
+
/**
|
|
229
|
+
* The video rate control the encoder was opened with; `null` for a copy, which encodes nothing.
|
|
230
|
+
*/
|
|
231
|
+
readonly videoRateControl: ResolvedVideoRateControl | null;
|
|
232
|
+
/** The audio bitrate, when the export has audio. */
|
|
233
|
+
readonly audioRateControl: {
|
|
234
|
+
readonly bitrate: number;
|
|
235
|
+
readonly level: QualityLevel | null;
|
|
236
|
+
} | null;
|
|
237
|
+
/** Timing and pipeline counters. Their names are diagnostic and may change between versions. */
|
|
238
|
+
readonly performance: ExportPerformance;
|
|
239
|
+
/** The media each source read: its original, or a proxy when the request asked for proxies. */
|
|
240
|
+
readonly media: Readonly<Record<string, Selection>>;
|
|
241
|
+
readonly [metadata: string]: unknown;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* An export's timing and pipeline counters (see the host protocol). Most are numbers, flags or
|
|
245
|
+
* names; the ones that are not are declared. A copy reports a few counters of its own and none of
|
|
246
|
+
* the declared ones.
|
|
247
|
+
*/
|
|
248
|
+
export interface ExportPerformance {
|
|
249
|
+
/** Per reason a source left the hardware decode path, how many times it did. */
|
|
250
|
+
readonly hardwareFallbackReasons?: Readonly<Record<string, number>>;
|
|
251
|
+
/**
|
|
252
|
+
* How many times the encode worker took a command and left each number of frames behind in its
|
|
253
|
+
* channel, indexed by that number.
|
|
254
|
+
*/
|
|
255
|
+
readonly encodeChannelDepthSamples?: readonly number[];
|
|
256
|
+
/** What the GPU-resident path reserved from the in-flight budget; `null` on the readback path. */
|
|
257
|
+
readonly gpuEncodeBudget?: GpuEncodeBudget | null;
|
|
258
|
+
readonly [counter: string]: PerformanceValue | undefined;
|
|
259
|
+
}
|
|
260
|
+
/** A value of {@link ExportPerformance}. */
|
|
261
|
+
export type PerformanceValue = number | boolean | string | null | readonly number[] | Readonly<Record<string, number>> | GpuEncodeBudget;
|
|
262
|
+
/** The device memory the GPU-resident path reserved, in bytes and surfaces. */
|
|
263
|
+
export interface GpuEncodeBudget {
|
|
264
|
+
readonly surfaceBytes: number;
|
|
265
|
+
readonly planeRingBytes: number;
|
|
266
|
+
readonly leaseBound: number;
|
|
267
|
+
readonly retainedSurfaces: number;
|
|
268
|
+
readonly surfaceCeiling: number;
|
|
269
|
+
readonly reservedBytes: number;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* One extension provider report: the source it is about, its `kind` (`missing_font`,
|
|
273
|
+
* `missing_image`, `unreadable_image`, `unsupported_feature`, `unreadable_item`,
|
|
274
|
+
* `normalized_delay`, `non_finite_samples`, `out_of_half_range`, `reduced_precision`), and that
|
|
275
|
+
* kind's fields.
|
|
276
|
+
*/
|
|
277
|
+
export interface ProviderDiagnostic {
|
|
278
|
+
readonly source: string;
|
|
279
|
+
readonly kind: string;
|
|
280
|
+
readonly [field: string]: unknown;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* What one source's decoders reported during an export. Audio samples are at the project's sample
|
|
284
|
+
* rate.
|
|
285
|
+
*/
|
|
286
|
+
export interface DecodeDiagnostics {
|
|
287
|
+
readonly source: string;
|
|
288
|
+
/**
|
|
289
|
+
* Corruption observations: FFmpeg may report one damaged packet at more than one stage, so this
|
|
290
|
+
* is not a count of distinct packets.
|
|
291
|
+
*/
|
|
292
|
+
readonly corruptPackets: number;
|
|
293
|
+
/** Runs of dropped video between healthy frames, an unrecovered tail included. */
|
|
294
|
+
readonly videoGaps: number;
|
|
295
|
+
/** Audio samples decoded as silence in place of damaged input. */
|
|
296
|
+
readonly concealedAudioSamples: number;
|
|
297
|
+
/** Audio samples decoded as silence where a clean stream's timestamps jump. */
|
|
298
|
+
readonly timestampGapSamples: number;
|
|
299
|
+
/** Audio samples dropped because their timestamps repeated samples already decoded. */
|
|
300
|
+
readonly droppedAudioSamples: number;
|
|
301
|
+
}
|
|
302
|
+
/** Where {@link ExportProjectRequest.renderCache} bakes frames. */
|
|
303
|
+
export interface RenderCacheOptions {
|
|
304
|
+
readonly directory: string;
|
|
305
|
+
/** The most bytes the directory holds. Default 4 GiB. */
|
|
306
|
+
readonly quotaBytes?: number;
|
|
307
|
+
/**
|
|
308
|
+
* A frame rendered while the host's cache writer is full: `"skip"` (default) leaves it unbaked so
|
|
309
|
+
* the cache never slows the export; `"wait"` holds the export until it is baked.
|
|
310
|
+
*/
|
|
311
|
+
readonly backlog?: "skip" | "wait";
|
|
312
|
+
}
|
|
313
|
+
/** What an export's render cache did. */
|
|
314
|
+
export type RenderCacheReport = {
|
|
315
|
+
readonly status: "used";
|
|
316
|
+
readonly hits: number;
|
|
317
|
+
readonly writes: number;
|
|
318
|
+
readonly bytesRead: number;
|
|
319
|
+
readonly bytesWritten: number;
|
|
320
|
+
/** Frames a bypassed clip kept out of the cache. */
|
|
321
|
+
readonly bypassedFrames: number;
|
|
322
|
+
/** Frames that failed their checksum, deleted and rendered again. */
|
|
323
|
+
readonly corrupt: number;
|
|
324
|
+
readonly writeErrors: number;
|
|
325
|
+
readonly evictions: number;
|
|
326
|
+
/** Frames not baked because the quota had no room. */
|
|
327
|
+
readonly quotaSkips: number;
|
|
328
|
+
/** Frames not baked because the writer was full (`backlog: "skip"`). */
|
|
329
|
+
readonly busySkips: number;
|
|
330
|
+
readonly quotaBytes: number;
|
|
331
|
+
readonly backlog: "skip" | "wait";
|
|
332
|
+
/**
|
|
333
|
+
* The cache's writer or reader was left stuck in the directory's
|
|
334
|
+
* filesystem; the export rendered every frame it had not taken by
|
|
335
|
+
* then, the writer's counts are what it had done, and the host process
|
|
336
|
+
* uses the directory no more.
|
|
337
|
+
*/
|
|
338
|
+
readonly abandoned: boolean;
|
|
339
|
+
} | {
|
|
340
|
+
readonly status: "unavailable";
|
|
341
|
+
readonly reason: string;
|
|
342
|
+
};
|
|
343
|
+
/** A loudness target for {@link ExportProjectRequest.loudness}. */
|
|
344
|
+
export interface LoudnessTarget {
|
|
345
|
+
/** Integrated loudness, `-60..=0` LUFS; streaming platforms use -14 to -16. */
|
|
346
|
+
readonly targetLufs: number;
|
|
347
|
+
/** True-peak ceiling, `-20..=0` dBTP; EBU R128 uses -1. */
|
|
348
|
+
readonly truePeakCeilingDbtp: number;
|
|
349
|
+
}
|
|
350
|
+
/** A proxy made from a source's original. */
|
|
351
|
+
export interface ProxyFile {
|
|
352
|
+
readonly path: string;
|
|
353
|
+
/** Evidence of the original it was made from, when known. */
|
|
354
|
+
readonly madeFrom?: MediaFingerprint;
|
|
355
|
+
/** The color pipeline baked into it, when it was tone-mapped. */
|
|
356
|
+
readonly colorPipeline?: string;
|
|
357
|
+
}
|
|
358
|
+
/** What {@link Alpha2NodeClient.exportProject} renders, and where it writes it. */
|
|
359
|
+
export interface ExportProjectRequest {
|
|
360
|
+
readonly project: Project;
|
|
361
|
+
/**
|
|
362
|
+
* A file path per source id, for the sources a render reads. The host checks them before it
|
|
363
|
+
* renders and refuses with an {@link Alpha2ConformError} listing what is missing, offline, or not
|
|
364
|
+
* the media the project recorded.
|
|
365
|
+
*/
|
|
366
|
+
readonly assets: Readonly<Record<string, string>>;
|
|
367
|
+
/** Proxies per source id, in order of preference. */
|
|
368
|
+
readonly proxies?: Readonly<Record<string, readonly ProxyFile[]>>;
|
|
369
|
+
/**
|
|
370
|
+
* Each image sequence's frame files in the project's order, per source id; `null` where the
|
|
371
|
+
* sequence has a gap.
|
|
372
|
+
*/
|
|
373
|
+
readonly frames?: Readonly<Record<string, readonly (string | null)[]>>;
|
|
374
|
+
/**
|
|
375
|
+
* Files an SVG source's `<image href>` or a Lottie source's image assets name outside the source,
|
|
376
|
+
* per source id and then per locator as the source writes it
|
|
377
|
+
* (`{ label: { "art/badge.png": "/media/badge.png" } }`): what a browser page registers with
|
|
378
|
+
* `registerResource`. A locator not given draws as missing and is reported as `missing_image`.
|
|
379
|
+
* Resources for a source that is not an SVG or Lottie source of the project are `INVALID_INPUT`.
|
|
380
|
+
*/
|
|
381
|
+
readonly resources?: Readonly<Record<string, Readonly<Record<string, string>>>>;
|
|
382
|
+
/**
|
|
383
|
+
* `original` (the default) reads originals only; `proxies` reads fresh proxies where there are
|
|
384
|
+
* some. The result's `media` says what each source read.
|
|
385
|
+
*/
|
|
386
|
+
readonly media?: "original" | "proxies";
|
|
387
|
+
/** A file path per effect resource id (LUT files and the like). */
|
|
388
|
+
readonly effectAssets?: Readonly<Record<string, string>>;
|
|
389
|
+
/**
|
|
390
|
+
* Font files caption tracks, text generators, and SVG text draw with, in fallback order. A
|
|
391
|
+
* project that shows text fails without them.
|
|
392
|
+
*/
|
|
393
|
+
readonly fonts?: readonly string[];
|
|
394
|
+
/** Definitions of custom effects the project uses beyond the built-in catalog. */
|
|
395
|
+
readonly effects?: readonly EffectDefinition[];
|
|
396
|
+
/** The timeline range to export, in ticks; widened to the frame grid (see `effectiveRange`). */
|
|
397
|
+
readonly startTicks: number;
|
|
398
|
+
readonly endTicks: number;
|
|
399
|
+
/** The output frame rate. */
|
|
400
|
+
readonly frameRate: FrameRate;
|
|
401
|
+
/** Whether the output has an audio track. Defaults to `true`. */
|
|
402
|
+
readonly includeAudio?: boolean;
|
|
403
|
+
/** Defaults to `h264`. */
|
|
404
|
+
readonly videoCodec?: "h264" | "hevc" | "vp9" | "av1" | "mpeg4-part2";
|
|
405
|
+
/**
|
|
406
|
+
* Concrete FFmpeg encoder short name: one of `capabilities.encode.video`, or the GPU path's
|
|
407
|
+
* `capabilities.encode.gpuOutputPath.encoder`. Pinning the GPU path's encoder asks for the
|
|
408
|
+
* GPU-resident path when it takes GPU frames only (`gpuOutputPath.gpuInputOnly`, as `h264_vulkan`
|
|
409
|
+
* does); `h264_videotoolbox` is in both and runs on whichever path `inputPolicy` selects.
|
|
410
|
+
*/
|
|
411
|
+
readonly videoEncoder?: string;
|
|
412
|
+
/**
|
|
413
|
+
* How the encoder receives frames: `auto` (default) takes the GPU-resident path where the host,
|
|
414
|
+
* codec, size, and budget allow it and the readback path otherwise; `gpu-required` fails with
|
|
415
|
+
* `GPU_OUTPUT_UNAVAILABLE` instead of falling back; `cpu-readback` always reads back. The
|
|
416
|
+
* result's `videoOutputPath` says which ran.
|
|
417
|
+
*/
|
|
418
|
+
readonly inputPolicy?: InputPolicy;
|
|
419
|
+
/**
|
|
420
|
+
* `render` (default) renders and encodes every frame.
|
|
421
|
+
*
|
|
422
|
+
* `prefer-copy` copies the sources' compressed packets instead when both hold:
|
|
423
|
+
*
|
|
424
|
+
* - the range is its sources shown untouched: clips that tile it one after another, each with an
|
|
425
|
+
* identity transform and no composition, mask, matte, caption, transition, or retime, none
|
|
426
|
+
* another clip's matte, cut at IDR pictures and encoded alike;
|
|
427
|
+
* - its packets under the range decode on their own into exactly those frames: an MP4/MOV H.264
|
|
428
|
+
* or HEVC source already at the output size, tagged BT.709 limited 8-bit 4:2:0, neither
|
|
429
|
+
* mirrored nor shown with non-square pixels (the container's declared pixel aspect ratio, else
|
|
430
|
+
* the codec's) nor declaring non-square pixels in the codec, on the export's frame grid,
|
|
431
|
+
* starting at an IDR picture.
|
|
432
|
+
*
|
|
433
|
+
* A copy's audio, if any, is copied when it is the only sound the render hears and the source's
|
|
434
|
+
* own, untouched, over the whole file; otherwise it is mixed as a render mixes it (silence
|
|
435
|
+
* included) and encoded to AAC beside the copied video. `videoQuality` does not apply to a copy,
|
|
436
|
+
* which keeps the source's encoding. When the range does not qualify, `prefer-copy` renders and
|
|
437
|
+
* says why in `copyIneligible`; `require-copy` fails with `COPY_INELIGIBLE` instead.
|
|
438
|
+
*/
|
|
439
|
+
readonly strategy?: ExportStrategy;
|
|
440
|
+
/** Output video quality. Defaults to `high`. */
|
|
441
|
+
readonly videoQuality?: VideoQuality;
|
|
442
|
+
/** Defaults to `aac`. */
|
|
443
|
+
readonly audioCodec?: "aac";
|
|
444
|
+
/** Output audio quality. Defaults to `high`. */
|
|
445
|
+
readonly audioQuality?: AudioQuality;
|
|
446
|
+
/**
|
|
447
|
+
* Normalizes the export's audio to an integrated loudness (ITU-R BS.1770-4, EBU R128), keeping
|
|
448
|
+
* its true peak at or below a ceiling. Needs `includeAudio` and a project that uses an audible
|
|
449
|
+
* source; the host refuses it otherwise with `INVALID_INPUT`. The host measures the mix in a
|
|
450
|
+
* first pass.
|
|
451
|
+
*/
|
|
452
|
+
readonly loudness?: LoudnessTarget;
|
|
453
|
+
/**
|
|
454
|
+
* A directory to bake the export's frames into and find them in: a later export of the same
|
|
455
|
+
* snapshot (the same host build, GPU, project, files, and effects) takes each baked frame instead
|
|
456
|
+
* of rendering it, and writes the same file. `quotaBytes` (default 4 GiB) bounds the directory;
|
|
457
|
+
* the least recently used frames go first, pinned clips' frames last. Frames are baked on the
|
|
458
|
+
* readback path only, on a writer thread beside the export; `backlog` says whether a frame the
|
|
459
|
+
* writer has no room for is skipped or waited for. The result's `renderCache` says what happened.
|
|
460
|
+
*/
|
|
461
|
+
readonly renderCache?: RenderCacheOptions;
|
|
462
|
+
/**
|
|
463
|
+
* Byte budgets for this export, replacing the host's environment settings
|
|
464
|
+
* (`ALPHA2_EXPORT_IN_FLIGHT_BYTES` and the rest) and defaults field by field. Each bounds memory
|
|
465
|
+
* the host reserves before it allocates; an export whose least working set does not fit fails
|
|
466
|
+
* with `RESOURCE_LIMIT` before it renders. The result's `memoryPolicy` reports what applied and
|
|
467
|
+
* where each value came from.
|
|
468
|
+
*/
|
|
469
|
+
readonly memory?: ExportMemoryBudget;
|
|
470
|
+
/** Overrides the client's decode mode for this export. */
|
|
471
|
+
readonly videoDecode?: VideoDecodeMode;
|
|
472
|
+
/** The MP4 file to write. */
|
|
473
|
+
readonly output: string;
|
|
474
|
+
/**
|
|
475
|
+
* Cancels the export: the host removes its partial file and exits, and the promise rejects with
|
|
476
|
+
* `Alpha2AbortError` once it has.
|
|
477
|
+
*/
|
|
478
|
+
readonly signal?: AbortSignal;
|
|
479
|
+
/**
|
|
480
|
+
* Receives each progress report. A throw, or a rejection of the promise it returns, fails the
|
|
481
|
+
* export with `PROGRESS_CALLBACK_FAILED` and ends its host; the export settles only after every
|
|
482
|
+
* promise it returned has.
|
|
483
|
+
*/
|
|
484
|
+
readonly onProgress?: ExportProgressCallback;
|
|
485
|
+
/**
|
|
486
|
+
* Receives native timing and pipeline metrics after a successful export. The export resolves
|
|
487
|
+
* after the promise it returns does; a throw or a rejection rejects the export with that error.
|
|
488
|
+
*/
|
|
489
|
+
readonly onResult?: (result: NativeExportResult) => void | Promise<void>;
|
|
490
|
+
}
|
|
491
|
+
/** The byte budgets an export runs within. See `memoryPolicy` in the host protocol. */
|
|
492
|
+
export interface ExportMemoryBudget {
|
|
493
|
+
/** Rendered frames between the GPU and the encoder. Default 256 MiB. */
|
|
494
|
+
readonly inFlightBytes?: number;
|
|
495
|
+
/** Decoded source frames waiting to be rendered. Default 256 MiB. */
|
|
496
|
+
readonly decodeQueueBytes?: number;
|
|
497
|
+
/** Frames a reversed clip keeps decoded. Default 256 MiB. */
|
|
498
|
+
readonly reverseCacheBytes?: number;
|
|
499
|
+
/** Decoded audio kept around the mix window. Default 256 MiB. */
|
|
500
|
+
readonly audioWindowBytes?: number;
|
|
501
|
+
/**
|
|
502
|
+
* What the open extension-provider sources (SVG, animated images, Lottie, OpenEXR, image
|
|
503
|
+
* sequences) hold together; past it the host closes the ones the last two frames did not show and
|
|
504
|
+
* opens them again when shown. Default 512 MiB.
|
|
505
|
+
*/
|
|
506
|
+
readonly providerSourceBytes?: number;
|
|
507
|
+
/**
|
|
508
|
+
* A fraction in (0, 1] every budget is scaled by once resolved: how a retry asks for less in
|
|
509
|
+
* flight.
|
|
510
|
+
*/
|
|
511
|
+
readonly scale?: number;
|
|
512
|
+
}
|
|
513
|
+
/** One encoder a native host can feed. */
|
|
514
|
+
export interface EncodeCapability {
|
|
515
|
+
/** The codec id, such as `h264` or `aac`. */
|
|
516
|
+
readonly id: string;
|
|
517
|
+
/** The FFmpeg encoder short name, as `videoEncoder` takes it. */
|
|
518
|
+
readonly encoder: string;
|
|
519
|
+
/**
|
|
520
|
+
* How the linked runtime declares this encoder executes, corrected for the encoders the pinned
|
|
521
|
+
* runtime misdeclares (`h264_videotoolbox` is `hardware`). `hybrid` is a MediaFoundation
|
|
522
|
+
* encoder, which is a software transform unless the host is configured to ask for a hardware one.
|
|
523
|
+
*/
|
|
524
|
+
readonly encoderClass?: "software" | "hardware" | "hybrid";
|
|
525
|
+
readonly hardwareAccelerated?: boolean;
|
|
526
|
+
readonly preferred?: boolean;
|
|
527
|
+
/** Smallest output the encoder accepts, in pixels; `null` when it reports none. */
|
|
528
|
+
readonly minimumWidth?: number | null;
|
|
529
|
+
readonly minimumHeight?: number | null;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* The GPU-resident output path, which the encoder list cannot describe.
|
|
533
|
+
*
|
|
534
|
+
* `capabilities.encode.video` lists the encoders the host's software sinks can feed. On Linux the
|
|
535
|
+
* GPU path's encoder (`h264_vulkan`) takes hardware frames and nothing else, so it is not in that
|
|
536
|
+
* list; on macOS it is `h264_videotoolbox`, which is. This says whether the path exists on this
|
|
537
|
+
* host and what it accepts, so a caller can tell before exporting whether its output will be
|
|
538
|
+
* GPU-resident: the codec must be the one named here, no other encoder may be pinned (pinning a
|
|
539
|
+
* `gpuInputOnly` encoder asks for this path), and the output size must be even and within the
|
|
540
|
+
* reported extents. Under `inputPolicy: "auto"` an export outside them still succeeds on the
|
|
541
|
+
* readback path; under `gpu-required` it fails with `GPU_OUTPUT_UNAVAILABLE`. Every export reports
|
|
542
|
+
* the path it took as `videoOutputPath`.
|
|
543
|
+
*/
|
|
544
|
+
export interface GpuOutputPathCapability {
|
|
545
|
+
readonly available: boolean;
|
|
546
|
+
/** Why the path is unavailable, or null when it is available. */
|
|
547
|
+
readonly reason: string | null;
|
|
548
|
+
/** The native API the encoder runs on: `vulkan` or `videotoolbox`. */
|
|
549
|
+
readonly backend: string | null;
|
|
550
|
+
readonly encoder: string | null;
|
|
551
|
+
readonly videoCodec: string | null;
|
|
552
|
+
/** The surface layout the encoder takes: `nv12`. */
|
|
553
|
+
readonly inputLayout: string | null;
|
|
554
|
+
/**
|
|
555
|
+
* How a packed frame reaches the encoder: `gpu-copy` renders into the backend's planes and copies
|
|
556
|
+
* them on the GPU; `direct-target` renders into the encoder's own surface.
|
|
557
|
+
*/
|
|
558
|
+
readonly inputHandoff: string | null;
|
|
559
|
+
/** Whether the encoder takes GPU frames only, so that pinning it asks for this path. */
|
|
560
|
+
readonly gpuInputOnly: boolean | null;
|
|
561
|
+
/** Whether the encoder runs on the renderer's own device. */
|
|
562
|
+
readonly sharesRendererDevice: boolean | null;
|
|
563
|
+
/** Smallest output the device's encoder accepts, in pixels. */
|
|
564
|
+
readonly minimumWidth: number | null;
|
|
565
|
+
readonly minimumHeight: number | null;
|
|
566
|
+
readonly maximumWidth: number | null;
|
|
567
|
+
readonly maximumHeight: number | null;
|
|
568
|
+
/**
|
|
569
|
+
* Granularity the output is aligned up to before the extents apply. A 158x62 output is accepted
|
|
570
|
+
* where 64x48 is not, because the first aligns up to the minimum coded extent and the second does
|
|
571
|
+
* not.
|
|
572
|
+
*/
|
|
573
|
+
readonly widthAlignment: number | null;
|
|
574
|
+
readonly heightAlignment: number | null;
|
|
575
|
+
/**
|
|
576
|
+
* The device's H.264 encode reference limits. B pictures need a non-zero
|
|
577
|
+
* `maxBPictureL0References` or `maxL1References`; absent when the path is unavailable, and null
|
|
578
|
+
* when the encoder does not report them (VideoToolbox).
|
|
579
|
+
*/
|
|
580
|
+
readonly maxPPictureL0References?: number | null;
|
|
581
|
+
readonly maxBPictureL0References?: number | null;
|
|
582
|
+
readonly maxL1References?: number | null;
|
|
583
|
+
/** Rate-control modes the device reports: `cbr`, `vbr`, `disabled` (constant QP). */
|
|
584
|
+
readonly rateControlModes?: readonly ("cbr" | "vbr" | "disabled")[];
|
|
585
|
+
/**
|
|
586
|
+
* Plane-texture pairs the renderer packs into besides the encoder's surfaces; 0 for
|
|
587
|
+
* `direct-target`.
|
|
588
|
+
*/
|
|
589
|
+
readonly planeRingSlots: number | null;
|
|
590
|
+
/**
|
|
591
|
+
* Surfaces the handoff and the encoder still hold after the host lets go; the in-flight byte
|
|
592
|
+
* budget pays for them too.
|
|
593
|
+
*/
|
|
594
|
+
readonly retainedSurfaces: number | null;
|
|
595
|
+
readonly requiresEvenDimensions: boolean;
|
|
596
|
+
/**
|
|
597
|
+
* Every codec the path takes on this device, each with its own limits; the fields above describe
|
|
598
|
+
* the first. One entry on Linux and macOS; on Windows each of H.264, HEVC and AV1 the device
|
|
599
|
+
* encodes. Empty when the path is unavailable.
|
|
600
|
+
*/
|
|
601
|
+
readonly codecs?: readonly GpuOutputCodec[];
|
|
602
|
+
}
|
|
603
|
+
/** What the GPU-resident path's encoder takes for one codec. */
|
|
604
|
+
export interface GpuOutputCodec {
|
|
605
|
+
readonly videoCodec: string;
|
|
606
|
+
readonly encoder: string;
|
|
607
|
+
readonly minimumWidth: number;
|
|
608
|
+
readonly minimumHeight: number;
|
|
609
|
+
readonly maximumWidth: number;
|
|
610
|
+
readonly maximumHeight: number;
|
|
611
|
+
readonly widthAlignment: number;
|
|
612
|
+
readonly heightAlignment: number;
|
|
613
|
+
readonly maxPPictureL0References: number | null;
|
|
614
|
+
readonly maxBPictureL0References: number | null;
|
|
615
|
+
readonly maxL1References: number | null;
|
|
616
|
+
readonly rateControlModes: readonly string[];
|
|
617
|
+
}
|
|
618
|
+
/** One codec's hardware decode registration in the linked FFmpeg build. */
|
|
619
|
+
export interface DecodeCodecCapability {
|
|
620
|
+
readonly id: string;
|
|
621
|
+
readonly decoder: string | null;
|
|
622
|
+
/**
|
|
623
|
+
* Whether the decoder advertises this platform's hardware configuration. Registration only: a
|
|
624
|
+
* device, profile, and surface format are still decided per stream, and every export reports the
|
|
625
|
+
* path its frames took.
|
|
626
|
+
*/
|
|
627
|
+
readonly hardwareConfig: boolean;
|
|
628
|
+
/**
|
|
629
|
+
* The decoder a software session opens for the codec, or `null` when only a hardware session
|
|
630
|
+
* decodes it (AV1 on a runtime built without libdav1d; the pinned FFmpeg SDK decodes it with
|
|
631
|
+
* `libdav1d`). A source with such a stream is `unsupported` on a host that cannot decode it in
|
|
632
|
+
* hardware.
|
|
633
|
+
*/
|
|
634
|
+
readonly softwareDecoder: string | null;
|
|
635
|
+
}
|
|
636
|
+
/** What a native host encodes. */
|
|
637
|
+
export interface HostEncodeCapabilities {
|
|
638
|
+
readonly container: "mp4";
|
|
639
|
+
/** Encoders the host's software sinks can feed. */
|
|
640
|
+
readonly video: readonly EncodeCapability[];
|
|
641
|
+
readonly audio: readonly EncodeCapability[];
|
|
642
|
+
readonly gpuOutputPath: GpuOutputPathCapability;
|
|
643
|
+
}
|
|
644
|
+
/** How a native host decodes video. */
|
|
645
|
+
export interface HostDecodeCapabilities {
|
|
646
|
+
readonly mode: VideoDecodeMode;
|
|
647
|
+
readonly backend: "vulkan" | "videotoolbox" | "d3d12va" | "none";
|
|
648
|
+
/** Whether a shared decode context was created for this host process. */
|
|
649
|
+
readonly deviceReady: boolean;
|
|
650
|
+
/**
|
|
651
|
+
* Why `auto` could not set up hardware decode at the host's start and decodes in software;
|
|
652
|
+
* `null` otherwise.
|
|
653
|
+
*/
|
|
654
|
+
readonly hardwareUnavailable: string | null;
|
|
655
|
+
/** Whether the device can present 10-bit decoded planes. */
|
|
656
|
+
readonly tenBit: boolean;
|
|
657
|
+
/** Codecs the decode device itself enabled, where the backend reports them. */
|
|
658
|
+
readonly deviceCodecs: readonly string[] | null;
|
|
659
|
+
readonly codecs: readonly DecodeCodecCapability[];
|
|
660
|
+
}
|
|
661
|
+
/** What {@link Alpha2NodeClient.getCapabilities} reports about the host. */
|
|
662
|
+
export interface HostCapabilities {
|
|
663
|
+
readonly status: "ready";
|
|
664
|
+
/** What the host can do, in the report every alpha2 runtime gives. */
|
|
665
|
+
readonly capabilities: CapabilityReport<HostDecodeCapabilities, HostEncodeCapabilities>;
|
|
666
|
+
readonly effectCatalog: BuiltinEffectCatalog;
|
|
667
|
+
readonly [diagnostic: string]: unknown;
|
|
668
|
+
}
|
|
669
|
+
/** What a host error carries besides its code and message. */
|
|
670
|
+
export interface Alpha2HostErrorOptions extends ErrorOptions {
|
|
671
|
+
/**
|
|
672
|
+
* The host's report of a failed export. Without one, the error's code classifies it. See
|
|
673
|
+
* `alpha2/export-failure`.
|
|
674
|
+
*/
|
|
675
|
+
readonly failure?: ExportFailure;
|
|
676
|
+
/** The export step the error came from, for a failure classified here. Default `prepare`. */
|
|
677
|
+
readonly phase?: ExportPhase;
|
|
678
|
+
/** The last part of the host's standard error, at most {@link STDERR_TAIL_BYTES}. */
|
|
679
|
+
readonly stderr?: string;
|
|
680
|
+
/** How the host process ended, when it ended before answering. */
|
|
681
|
+
readonly exitCode?: number | null;
|
|
682
|
+
readonly signal?: string | null;
|
|
683
|
+
}
|
|
684
|
+
/** Bytes of the host's standard error an error keeps. */
|
|
685
|
+
export declare const STDERR_TAIL_BYTES = 16384;
|
|
686
|
+
/**
|
|
687
|
+
* Every error this client rejects with. Its `failure` classifies it for a retry policy
|
|
688
|
+
* (`alpha2/export-retry`): the host's own report when the host sent one, and otherwise the class
|
|
689
|
+
* its code is evidence of (`failureForCode`), as the host would have classified the same code, so a
|
|
690
|
+
* refusal made here or before an export started is as final as the host's.
|
|
691
|
+
*/
|
|
692
|
+
export declare class Alpha2HostError extends Error {
|
|
693
|
+
/** A machine-readable code, such as `HOST_NOT_FOUND`, `INVALID_INPUT` or `DECODE_STALLED`. */
|
|
694
|
+
readonly code: string;
|
|
695
|
+
readonly failure: ExportFailure;
|
|
696
|
+
readonly stderr?: string;
|
|
697
|
+
readonly exitCode?: number | null;
|
|
698
|
+
readonly signal?: string | null;
|
|
699
|
+
constructor(code: string, message: string, options?: Alpha2HostErrorOptions);
|
|
700
|
+
}
|
|
701
|
+
/** An export refused before it rendered: the project's media is not ready. */
|
|
702
|
+
export declare class Alpha2ConformError extends Alpha2HostError {
|
|
703
|
+
/** What each source would read and what blocks it. */
|
|
704
|
+
readonly report: ConformReport;
|
|
705
|
+
constructor(message: string, report: ConformReport, options?: Alpha2HostErrorOptions);
|
|
706
|
+
}
|
|
707
|
+
/** What {@link Alpha2NodeClient.getCapabilities} takes. */
|
|
708
|
+
export interface CapabilitiesOptions {
|
|
709
|
+
/** Withdraws this call; see {@link Alpha2NodeClient.getCapabilities}. */
|
|
710
|
+
readonly signal?: AbortSignal;
|
|
711
|
+
/** The decode mode to report for, in place of the client's. */
|
|
712
|
+
readonly videoDecode?: VideoDecodeMode;
|
|
713
|
+
}
|
|
714
|
+
/** What {@link Alpha2NodeClient.conform} asks. */
|
|
715
|
+
export interface ConformRequest {
|
|
716
|
+
readonly project: Project;
|
|
717
|
+
/** As {@link ExportProjectRequest.assets}, {@link ExportProjectRequest.proxies} and `frames`. */
|
|
718
|
+
readonly assets?: Readonly<Record<string, string>>;
|
|
719
|
+
readonly proxies?: Readonly<Record<string, readonly ProxyFile[]>>;
|
|
720
|
+
readonly frames?: Readonly<Record<string, readonly (string | null)[]>>;
|
|
721
|
+
/** Defaults to `export_original`. */
|
|
722
|
+
readonly purpose?: MediaPurpose;
|
|
723
|
+
readonly signal?: AbortSignal;
|
|
724
|
+
}
|
|
725
|
+
/** What the host found, and what the purpose would read. */
|
|
726
|
+
export interface ConformResult {
|
|
727
|
+
readonly catalog: AssetCatalog;
|
|
728
|
+
readonly report: ConformReport;
|
|
729
|
+
}
|
|
730
|
+
/** The host could not create its GPU device (`GPU_INIT_FAILED`). */
|
|
731
|
+
export declare class Alpha2GpuInitializationError extends Alpha2HostError {
|
|
732
|
+
constructor(message: string, options?: Alpha2HostErrorOptions);
|
|
733
|
+
}
|
|
734
|
+
/** The project failed validation before a host started (`INVALID_INPUT`); `problems` lists why. */
|
|
735
|
+
export declare class Alpha2ProjectValidationError extends Alpha2HostError {
|
|
736
|
+
readonly problems: readonly string[];
|
|
737
|
+
constructor(problems: readonly string[]);
|
|
738
|
+
}
|
|
739
|
+
/** The request's `signal` aborted it (`ABORTED`). */
|
|
740
|
+
export declare class Alpha2AbortError extends Alpha2HostError {
|
|
741
|
+
constructor();
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* The file name `alpha2-host` has on `platform`: Windows executables carry `.exe`, and nothing
|
|
745
|
+
* there adds it to a path that lacks it.
|
|
746
|
+
*/
|
|
747
|
+
export declare function hostExecutableName(platform?: NodeJS.Platform): string;
|
|
748
|
+
/**
|
|
749
|
+
* Locates `alpha2-host` without loading Electron. The package does not ship the binary: it comes
|
|
750
|
+
* in the platform's native archive on https://github.com/alpha2-sh/alpha2/releases, as
|
|
751
|
+
* `bin/alpha2-host` beside the `lib/` it loads. Native archives and Electron applications should
|
|
752
|
+
* keep `bin/` and `lib/` together and unpack both from ASAR. Resolution order is explicit path,
|
|
753
|
+
* `ALPHA2_HOST_PATH`, Electron resources (`bin/`, then the directory itself), this package's own
|
|
754
|
+
* `bin/`, then `PATH`.
|
|
755
|
+
*
|
|
756
|
+
* Throws an {@link Alpha2HostError}: `INVALID_INPUT` for an empty `hostPath`, `HOST_NOT_FOUND` when
|
|
757
|
+
* an explicit path is not a file or no candidate exists; the latter message names the native
|
|
758
|
+
* archive. An empty `ALPHA2_HOST_PATH` is unset.
|
|
759
|
+
*/
|
|
760
|
+
export declare function resolveHostBinary(options?: ResolveHostBinaryOptions): string;
|
|
761
|
+
/**
|
|
762
|
+
* Runs requests on `alpha2-host` sidecar processes, one process per request, at most
|
|
763
|
+
* `concurrency` at a time; further requests wait for a slot. Every rejection is an
|
|
764
|
+
* {@link Alpha2HostError}.
|
|
765
|
+
*/
|
|
766
|
+
export declare class Alpha2NodeClient {
|
|
767
|
+
#private;
|
|
768
|
+
/**
|
|
769
|
+
* Resolves the host binary now. Throws a `RangeError` for a `concurrency` that is not a positive
|
|
770
|
+
* integer, and an {@link Alpha2HostError} when `videoDecode` is not a mode (`INVALID_INPUT`) or
|
|
771
|
+
* the binary cannot be found.
|
|
772
|
+
*/
|
|
773
|
+
constructor(options?: Alpha2NodeOptions);
|
|
774
|
+
/**
|
|
775
|
+
* What the host can decode, render and encode, for the client's decode mode or
|
|
776
|
+
* `options.videoDecode`. The first call for a mode starts a host, in a slot like any request;
|
|
777
|
+
* calls made while it runs share it, and its report answers every later call for that mode on
|
|
778
|
+
* this client, since the same binary and mode report the same. A probe that fails is not kept:
|
|
779
|
+
* the next call starts another.
|
|
780
|
+
*
|
|
781
|
+
* `options.signal` withdraws this call (`Alpha2AbortError`); the probe goes on while another call
|
|
782
|
+
* still waits for it, and is withdrawn, from its slot or its host, when none does.
|
|
783
|
+
*/
|
|
784
|
+
getCapabilities(options?: CapabilitiesOptions): Promise<HostCapabilities>;
|
|
785
|
+
/**
|
|
786
|
+
* Which media a purpose would read for each source, and what blocks it, without rendering. The
|
|
787
|
+
* host hashes an original only when the project recorded a hash to compare. Rejects with an
|
|
788
|
+
* {@link Alpha2ProjectValidationError} for an invalid project.
|
|
789
|
+
*/
|
|
790
|
+
conform(request: ConformRequest): Promise<ConformResult>;
|
|
791
|
+
/**
|
|
792
|
+
* Renders and encodes `request.project` to `request.output` and resolves with that path.
|
|
793
|
+
*
|
|
794
|
+
* Rejects with an {@link Alpha2ProjectValidationError} or an `INVALID_INPUT` error before a host
|
|
795
|
+
* starts when the project or request is invalid, an {@link Alpha2ConformError} when the media is
|
|
796
|
+
* not ready, an {@link Alpha2AbortError} when `signal` aborts, and an {@link Alpha2HostError}
|
|
797
|
+
* otherwise. Under the `auto` decode mode, an export whose hardware decoder stalls
|
|
798
|
+
* (`DECODE_STALLED`) runs once more decoding in software; its progress starts over. When that
|
|
799
|
+
* run fails too, its error is the export's, with the stall as its `cause` and in
|
|
800
|
+
* `failure.diagnostics.decodeStall`.
|
|
801
|
+
*/
|
|
802
|
+
exportProject(request: ExportProjectRequest): Promise<string>;
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* {@link Alpha2NodeClient.getCapabilities} on a client shared by every module-level call with the
|
|
806
|
+
* same `concurrency` and resolved binary, for `options.videoDecode`.
|
|
807
|
+
*/
|
|
808
|
+
export declare function getCapabilities(options?: Alpha2NodeOptions & CapabilitiesOptions): Promise<HostCapabilities>;
|
|
809
|
+
/**
|
|
810
|
+
* {@link Alpha2NodeClient.exportProject} on a client shared by every module-level call with the
|
|
811
|
+
* same `concurrency` and resolved binary, so `concurrency` holds across calls whatever decode mode
|
|
812
|
+
* each asks for. `options.videoDecode` applies where the request names none.
|
|
813
|
+
*/
|
|
814
|
+
export declare function exportProject(request: ExportProjectRequest, options?: Alpha2NodeOptions): Promise<string>;
|