4.9 KiB
4.9 KiB
encode/encode-to
Universal encode entry point — encode an AudioDocument to bytes and
write them to any Destination (file path, WritableStream, or
callback).
(no submodules)
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
Destinationvariants:stringfile path → resolved via dynamicimport('node:fs/promises')forwriteFile. Runtime-gated so the import never appears statically.WritableStream<Uint8Array>→ write via the stream's writer, closes the stream after writing.(chunk: Uint8Array) => voidcallback → single invocation with the full payload.
- Optional
opts.format: "pcm" | "float"andopts.bitDepth: 8 | 16 | 24 | 32for codecs that support multiple sample formats (WAV). - Optional
opts.sampleRateoverride — 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 throwAUDIO_CODECS.STREAM_ERROR. - Optional
opts.registryto inject a pre-configured registry. Defaults to a freshCodecRegistry()— callers that need WAV/AIFF/ CAF or WASM codecs available should pass in the registry fromdecode-source.tsor construct one with the codecs they need. - Zod-validated options — invalid
sampleRate/bitDepth/formatthrowsAUDIO_CODECS.INVALID_SOURCE. - Encoder errors are wrapped — codec-specific failures surface as
AUDIO_CODECS.ENCODE_FAILEDwith the original error oncause. - Invalid destination (not a path/stream/callback) throws
AUDIO_CODECS.INVALID_SOURCE.
Usage: Basic Example
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:
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 validatingsampleRate,bitDepth, andformat.async function encodeTo(doc: AudioDocument, destination: Destination, format: string, opts?: EncodeToOpts): Promise<void>— throwsINVALID_SOURCEfor invalid options or unrecognised destination,STREAM_ERRORfor pre-aborted signals,NOT_SUPPORTEDfor unknown formats,ENCODE_FAILEDfor codec errors.
Implementation Notes
- The file-path destination uses dynamic
import('node:fs/promises')to keep the package universal. Browser callers must use theWritableStreamor callback destination — passing a string path in a browser would fail withINVALID_SOURCEvia the dynamic import failure, which then surfaces asINVALID_SOURCEat the outer boundary. - The
WritableStreampath acquires a writer, writes one chunk, then closes viawriter.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.encodeStreamdirectly instead ofencodeTo. - Codec error wrapping preserves the original via
cause; callers can recover the underlying error via(err as AudioCodecsError).cause. opts.signalis 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 thrownSTREAM_ERRORfrom any subsequentencodeTocall against the same controller.