Files
skills/docs/media/audio/audio-codecs/src/encode/encode-to.md
2026-05-29 08:20:56 +01:00

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 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

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 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.