@alpha2-sh/node 0.0.0 → 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/README.md CHANGED
@@ -1,3 +1,83 @@
1
1
  # @alpha2-sh/node
2
2
 
3
- Placeholder that reserves the name. The first release is 0.1.0, from https://github.com/alpha2-sh/alpha2.
3
+ A Node.js client for `alpha2-host`, the native alpha2 renderer: it exports alpha2 projects to MP4 files from Node.js or an Electron main process, with FFmpeg for decoding and encoding and the GPU for rendering.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @alpha2-sh/node
9
+ ```
10
+
11
+ The package does not include `alpha2-host`. Download the native archive for the platform from the [GitHub Releases page](https://github.com/alpha2-sh/alpha2/releases) and keep its `bin/` and `lib/` directories together; [native archives](https://github.com/alpha2-sh/alpha2/blob/main/docs/native.md) describes them. The client looks for `alpha2-host` (`alpha2-host.exe` on Windows) in this order:
12
+
13
+ 1. the `hostPath` option;
14
+ 2. the `ALPHA2_HOST_PATH` environment variable (a relative path is relative to the `cwd` option, else the working directory);
15
+ 3. in Electron, `process.resourcesPath/bin/`, then `process.resourcesPath/`;
16
+ 4. this package's own `bin/` directory;
17
+ 5. the directories on `PATH`.
18
+
19
+ When none has it, the client throws an `Alpha2HostError` with code `HOST_NOT_FOUND`.
20
+
21
+ Node.js 20 or later.
22
+
23
+ ## Export a project
24
+
25
+ ```js
26
+ import { Alpha2NodeClient } from "@alpha2-sh/node";
27
+
28
+ const client = new Alpha2NodeClient({ hostPath: "/opt/alpha2/bin/alpha2-host" });
29
+ const output = await client.exportProject({
30
+ project, // an alpha2 project document
31
+ assets: { "image-1": "/media/image.png" }, // the file of each source
32
+ startTicks: 0,
33
+ endTicks: 120_000, // ticks: 120,000 a second
34
+ frameRate: { num: 30, den: 1 },
35
+ videoQuality: "high",
36
+ output: "/exports/tutorial.mp4",
37
+ onProgress: ({ phase, completed, total }) => console.log(phase, completed, total),
38
+ });
39
+ ```
40
+
41
+ Each export runs in its own `alpha2-host` process. The project is checked with `validateProject` from `alpha2/project` before a process starts; an invalid one is refused with an `Alpha2ProjectValidationError` listing the problems. The output must not exist yet: the host writes `<stem>.alpha2-partial.<ext>` beside it and renames it into place when it is complete. `exportProject` resolves with the output path once the file is complete; `onResult` receives what the host reports about the export (frames, encoder, rate control, timing, which media each source read).
42
+
43
+ The request's fields are typed and described in `ExportProjectRequest`; the [host protocol](https://github.com/alpha2-sh/alpha2/blob/main/docs/host-protocol.md) lists them with their defaults. Among them: `videoCodec` (`h264` by default; `hevc`, `vp9`, `av1`, `mpeg4-part2`), `videoQuality` and `audioQuality` (a level, `very-low` to `very-high`, `high` by default, which the host turns into a rate for the codec, size and frame rate, or an explicit bitrate), `includeAudio`, `loudness`, `fonts`, `effectAssets`, `proxies` with `media: "proxies"`, `renderCache` and `memory`.
44
+
45
+ ## Capabilities
46
+
47
+ `client.getCapabilities()` reports what the host can decode and encode. An export without `videoCodec` gets H.264, and a host that cannot encode it refuses the export instead of writing another codec. A host encodes H.264 either with an encoder listed in `encode.video` or through its GPU-resident path, `encode.gpuOutputPath`, whose encoder takes frames on the GPU only (on Linux, `h264_vulkan`) and so is not in `encode.video`:
48
+
49
+ ```js
50
+ const { encode } = (await client.getCapabilities()).capabilities;
51
+ const h264 =
52
+ encode.video.some((encoder) => encoder.id === "h264") ||
53
+ (encode.gpuOutputPath.codecs ?? []).some((codec) => codec.videoCodec === "h264");
54
+ ```
55
+
56
+ The first `getCapabilities` call for a decode mode starts a host; calls made while it runs share it, and its answer serves later calls for that mode.
57
+
58
+ `videoDecode` (`software`, `auto`, `hardware-required`) chooses how the host decodes video, as a client option or per export; by default the host decides, `auto` on Linux and `software` on macOS and Windows. Under `auto`, an export whose hardware decoder stalls runs once more decoding in software.
59
+
60
+ ## Errors
61
+
62
+ Every rejection is an `Alpha2HostError` with a `code`, the protocol's error codes and the client's own (`HOST_NOT_FOUND`, `HOST_EXITED`, `HOST_LOAD_FAILED`, `ABORTED`, and others). Its `failure` classifies it for a retry policy (`alpha2/export-failure`, `alpha2/export-retry`): the step and frame it failed at, and whether it is evidence of a lost device, running out of memory or bad input. `stderr` holds the end of the host's standard error. Subclasses:
63
+
64
+ - `Alpha2ProjectValidationError`: the project is invalid (`problems`).
65
+ - `Alpha2ConformError`: the media is not ready, so nothing was rendered (`report` says, per source, what is missing, offline or not the media the project recorded). `client.conform({ project, assets })` asks the same question without exporting.
66
+ - `Alpha2GpuInitializationError`: the host could not create its GPU device.
67
+ - `Alpha2AbortError`: the request's `signal` aborted it.
68
+
69
+ ## Cancelling
70
+
71
+ `signal` (an `AbortSignal`) cancels an export. The host stops, removes its partial file and exits, and `exportProject` rejects with `Alpha2AbortError` once the process is gone. On Windows the client ends the host process at once, which leaves the partial file; the next export to the same `output` takes it over.
72
+
73
+ ## Concurrency
74
+
75
+ `concurrency` (default 1) is how many host processes a client runs at once, and so how many exports share the GPU; more requests wait for a slot. The module-level `exportProject(request, options)` and `getCapabilities(options)` share one client per host binary and `concurrency`.
76
+
77
+ ## Electron
78
+
79
+ Ship the archive's `bin/` and `lib/` outside the ASAR archive, for example as `bin/` and `lib/` in the application's resources directory (`process.resourcesPath`), where the client finds the host in an Electron main process. A host path inside `app.asar` is read from `app.asar.unpacked` instead.
80
+
81
+ ## License
82
+
83
+ MIT, copyright Alpha2 contributors. The native archive's FFmpeg is under the LGPL; see [native archives](https://github.com/alpha2-sh/alpha2/blob/main/docs/native.md).