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

2.7 KiB

codecs/opus

Lazy Opus codec — wrapper over @audio/decode-opus WASM module loaded on first use.

Purpose

Opus is the modern open-source lossy audio codec that supersedes both Vorbis (for general-purpose use) and Speex (for voice). It encodes voice and music at low bitrates with quality that frequently beats MP3 and AAC, and is the default target for WebRTC voice traffic. The package treats Opus as the canonical lossy encode target.

The codec is implemented as a thin wrapper over @audio/decode-opus loaded via dynamic import(). Implementation delegates to createWasmCodec for the lazy-load, error-wrapping, and missing-module behaviour shared by every WASM wrapper.

Features

  • name === "opus", extensions ["opus"], MIME types ["audio/opus"].
  • canDecode(bytes) — magic-byte sniff for OggS at byte 0 (Opus payloads are typically Ogg-encapsulated); rejects buffers shorter than 4 bytes.
  • Decode + encode both supported.
  • Streaming factory absent — single-pass full-buffer codec.

Usage: Basic Example

import { OpusCodec } from "@suaveplan/audio-codecs/codecs/opus";

const decoded = await OpusCodec.decode(opusBytes);
const reEncoded = await OpusCodec.encode(decoded.channelData);

Usage: Advanced Example

Pipeline: decode WAV → re-encode as Opus for transport:

import { CodecRegistry, OpusCodec, WavCodec } from "@suaveplan/audio-codecs";

const registry = new CodecRegistry({ codecs: [WavCodec, OpusCodec] });

const wavDoc = await registry.decode(wavBytes);
const opusBytes = await registry.encode(wavDoc, "opus");
// Send opusBytes over a low-bandwidth transport.

API Reference

  • OpusCodec: AudioCodec — frozen constant.
  • canDecode(bytes), decode(bytes, opts?), encode(channelData, opts?) — see wasm-base.md.

Implementation Notes

  • The OggS magic shared with Vorbis and FLAC-in-Ogg means detect-then-dispatch may pick the wrong codec when multiple Ogg-family codecs are registered. Register Opus before Vorbis if you expect Opus content to dominate; otherwise pass format: "opus" as a hint to decode to bypass detection.
  • The first decode/encode call lazily loads @audio/decode-opus; subsequent calls reuse the memoised module.
  • Missing @audio/decode-opus → AUDIO_CODECS.NOT_SUPPORTED.
  • Streaming Opus (chunked decode at 20 ms frame boundaries) is not exposed by this wrapper — adding it requires a per-frame parser and the @audio/stream-opus companion module which is a future extension.
  • The codec accepts the standard EncodeOpts shape but Opus' real encoder tuning (bitrate, complexity, signal type) is module-specific and lives in the @audio/decode-opus options surface.