Files
2026-05-27 23:47:53 +01:00

2.6 KiB

encode-pipeline.ts

(no submodules)

Purpose

This module owns the pure logic of the encode pipeline: validating the requested format against the supported set before the worker is touched, interleaving per-channel PCM into a single Float32Array, projecting that into ffmpeg's f32le wire format, building the format-specific ffmpeg command for each of wav / mp3 / ogg / opus / flac / aac / webm, and dispatching the call through the supplied WorkerHost. All MEMFS lifecycle is owned by the host.

Features

  • interleave and float32ToBytes produce the exact wire layout ffmpeg expects for -f f32le.
  • buildCommand returns the ffmpeg argument list per supported format, honouring caller-supplied bitrate (mp3, opus, aac, webm) and quality (ogg).
  • assertSupported throws UNSUPPORTED_CODEC synchronously, before any worker message is posted — required by the spec.
  • runEncode drives the full pipeline through WorkerHost.submitFfmpeg.

Usage: Basic

import { runEncode } from "@suaveplan/audio-codec-ffmpeg-wasm/encode/encode-pipeline";

const bytes = await runEncode({
    host,
    channelData: [leftFloats, rightFloats],
    format: "mp3",
    sampleRate: 44_100,
    bitrate: 256_000,
});

Usage: Advanced

import {
    runEncode,
    interleave,
    buildCommand,
} from "@suaveplan/audio-codec-ffmpeg-wasm/encode/encode-pipeline";

// Inspect the command ffmpeg will be asked to run
const cmd = buildCommand("opus", 48_000, 1, 96_000);
console.log(cmd.args);

const interleaved = interleave([mono]);
const result = await runEncode({
    host,
    channelData: [mono],
    format: "opus",
    sampleRate: 48_000,
    bitrate: 96_000,
    signal: controller.signal,
    timeoutMs: 60_000,
});

API Reference

  • interleave(channelData): Float32Array.
  • float32ToBytes(samples): Uint8Array.
  • buildCommand(format, sampleRate, channels, bitrate?, quality?): FormatCommand.
  • runEncode(opts: EncodePipelineOptions): Promise<Uint8Array>.

Implementation Notes

assertSupported is intentionally written as a TypeScript asserts function so its throw branch narrows the format type for the rest of the function — no extra runtime branch is needed. Format-specific defaults (192 kbps for MP3/AAC, 96 kbps for Opus/WebM, q=5 for Vorbis) are chosen to match the ffmpeg.wasm reference build's documented sweet spots; callers always override via bitrate/quality for production use. The interleaved Float32Array is wrapped in a Uint8Array view without an extra copy so the worker postMessage boundary takes one transferable buffer instead of two.