first commit
This commit is contained in:
128
docs/media/audio/audio-codecs/src/encode/encode-to.md
Normal file
128
docs/media/audio/audio-codecs/src/encode/encode-to.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# `encode/encode-to`
|
||||
|
||||
Universal encode entry point — encode an `AudioDocument` to bytes and
|
||||
write them to any `Destination` (file path, WritableStream, or
|
||||
callback).
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`encodeTo` is the top-level public-facing encode API. Callers do not
|
||||
need to wire codec dispatch + destination plumbing manually — they
|
||||
pass in a document, a format name, and a destination handle, and the
|
||||
function takes care of routing through `CodecRegistry.encode` and
|
||||
then writing the resulting bytes to the destination via the
|
||||
appropriate platform call.
|
||||
|
||||
## Features
|
||||
|
||||
- Accepts three `Destination` variants:
|
||||
- `string` file path → resolved via dynamic
|
||||
`import('node:fs/promises')` for `writeFile`. Runtime-gated so
|
||||
the import never appears statically.
|
||||
- `WritableStream<Uint8Array>` → write via the stream's writer,
|
||||
closes the stream after writing.
|
||||
- `(chunk: Uint8Array) => void` callback → single invocation with
|
||||
the full payload.
|
||||
- Optional `opts.format: "pcm" | "float"` and `opts.bitDepth: 8 | 16
|
||||
| 24 | 32` for codecs that support multiple sample formats (WAV).
|
||||
- Optional `opts.sampleRate` override — used when the encode pipeline
|
||||
needs to retarget a different rate than the document's natural
|
||||
rate.
|
||||
- Optional `opts.signal` (AbortSignal) — checked before encode
|
||||
dispatch. Pre-aborted signals throw `AUDIO_CODECS.STREAM_ERROR`.
|
||||
- Optional `opts.registry` to inject a pre-configured registry.
|
||||
Defaults to a fresh `CodecRegistry()` — callers that need WAV/AIFF/
|
||||
CAF or WASM codecs available should pass in the registry from
|
||||
`decode-source.ts` or construct one with the codecs they need.
|
||||
- Zod-validated options — invalid `sampleRate`/`bitDepth`/`format`
|
||||
throws `AUDIO_CODECS.INVALID_SOURCE`.
|
||||
- Encoder errors are wrapped — codec-specific failures surface as
|
||||
`AUDIO_CODECS.ENCODE_FAILED` with the original error on `cause`.
|
||||
- Invalid destination (not a path/stream/callback) throws
|
||||
`AUDIO_CODECS.INVALID_SOURCE`.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { CodecRegistry, encodeTo, WavCodec } from "@suaveplan/audio-codecs";
|
||||
|
||||
const registry = new CodecRegistry({ codecs: [WavCodec] });
|
||||
|
||||
await encodeTo(doc, "/tmp/out.wav", "wav", {
|
||||
registry,
|
||||
bitDepth: 16,
|
||||
format: "pcm",
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
Encode to a streaming destination (e.g. an HTTP response body) with
|
||||
abort cancellation:
|
||||
|
||||
```ts
|
||||
import { CodecRegistry, encodeTo, WavCodec } from "@suaveplan/audio-codecs";
|
||||
|
||||
const registry = new CodecRegistry({ codecs: [WavCodec] });
|
||||
const ctrl = new AbortController();
|
||||
|
||||
const responseStream = new WritableStream<Uint8Array>({
|
||||
write(chunk) {
|
||||
sendOverWebSocket(chunk);
|
||||
},
|
||||
});
|
||||
|
||||
await encodeTo(doc, responseStream, "wav", {
|
||||
registry,
|
||||
bitDepth: 24,
|
||||
format: "pcm",
|
||||
signal: ctrl.signal,
|
||||
});
|
||||
|
||||
// Or write via callback for fine-grained control:
|
||||
let captured: Uint8Array | undefined;
|
||||
await encodeTo(doc, (chunk) => { captured = chunk; }, "wav", { registry });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `type Destination = string | WritableStream<Uint8Array> | ((chunk: Uint8Array) => void)`
|
||||
- `interface EncodeToOpts { sampleRate?, bitDepth?, format?, signal?, registry? }`
|
||||
- `const EncodeToOptsSchema` — Zod schema validating
|
||||
`sampleRate`, `bitDepth`, and `format`.
|
||||
- `async function encodeTo(doc: AudioDocument, destination: Destination,
|
||||
format: string, opts?: EncodeToOpts): Promise<void>` — throws
|
||||
`INVALID_SOURCE` for invalid options or unrecognised destination,
|
||||
`STREAM_ERROR` for pre-aborted signals, `NOT_SUPPORTED` for unknown
|
||||
formats, `ENCODE_FAILED` for codec errors.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The file-path destination uses dynamic `import('node:fs/promises')`
|
||||
to keep the package universal. Browser callers must use the
|
||||
`WritableStream` or callback destination — passing a string path
|
||||
in a browser would fail with `INVALID_SOURCE` via the dynamic
|
||||
import failure, which then surfaces as `INVALID_SOURCE` at the
|
||||
outer boundary.
|
||||
- The `WritableStream` path acquires a writer, writes one chunk, then
|
||||
closes via `writer.close()`. Callers that need to keep the stream
|
||||
open for additional writes should use a callback destination
|
||||
instead — the closed-after-one-write semantics matches the
|
||||
single-payload encode model.
|
||||
- The callback destination receives the full encoded buffer in one
|
||||
invocation. For per-chunk encode (where bytes arrive as encoding
|
||||
progresses), use `CodecRegistry.encodeStream` directly instead of
|
||||
`encodeTo`.
|
||||
- Codec error wrapping preserves the original via `cause`; callers
|
||||
can recover the underlying error via
|
||||
`(err as AudioCodecsError).cause`.
|
||||
- `opts.signal` is checked only before dispatch — codec internal
|
||||
abort during encode requires the codec to honour the signal,
|
||||
which most current codecs (WAV native, WASM wrappers) do not.
|
||||
Mid-encode cancellation will not interrupt the codec call but
|
||||
will surface as a thrown `STREAM_ERROR` from any subsequent
|
||||
`encodeTo` call against the same controller.
|
||||
Reference in New Issue
Block a user