@audio/ encode-opus
Status calibrated
npm1.3.2licenseMIT
Encode PCM audio samples to Ogg Opus (libopus WASM)
Overview
- Install
- Updated
- Family
- encode, 14 packages under it
- Tags
- read & write
Encode PCM audio samples to Ogg Opus format.
libopus WASM (single-file module, no side files — loads from any CDN, Node, workers and AudioWorklets) with a built-in Ogg muxer.
import opus from '@audio/encode-opus';
const encoder = await opus({ sampleRate: 48000, channels: 1, bitrate: 96 });
const chunk = encoder.encode(channelData); // → Uint8Array (Ogg pages)
const tail = encoder.flush(); // → Uint8Array (remaining + EOS)
// concatenate chunk + tail for complete Ogg Opus file
Options
| Option | Default | Description |
|---|---|---|
sampleRate |
— | Input sample rate (required). Resampled to 48kHz internally. |
channels |
1 |
1 (mono) or 2 (stereo) |
bitrate |
64 |
Target bitrate in kbps |
application |
'audio' |
'audio', 'voip', or 'lowdelay' |
complexity |
10 |
libopus encoder effort, 0-10 |
meta |
— | VorbisComment tags (title, artist, …) written into OpusTags |
Opus always encodes at 48kHz. Other rates are resampled to it as one stream (polyphase FIR, its phase and history carried across chunks): any chunking encodes as one chunk does, sample for sample, on time.
Streaming
const encoder = await opus({ sampleRate: 44100, channels: 1, bitrate: 128 });
const a = encoder.encode(chunk1); // → Uint8Array (Ogg pages with headers)
const b = encoder.encode(chunk2); // → Uint8Array (Ogg audio pages)
const c = encoder.flush(); // → Uint8Array (final page + EOS)
// complete Ogg Opus = concat(a, b, c)
encoder.free();
License
MIT
Raw packets
Container muxers build on the packet encoder directly (@audio/encode-webm does):
import { createOpusEncoder, createResampler, toOpusRate, FRAME } from '@audio/encode-opus/core'
let enc = await createOpusEncoder({ channels: 2, bitrate: 96 })
enc.lookahead // encoder delay in 48 kHz samples: Ogg pre-skip / Matroska CodecDelay
let pcm = toOpusRate(channelData, 44100) // a whole signal → interleaved 48 kHz float
let packet = enc.encode(pcm.subarray(0, FRAME * 2))
enc.free()
let rs = createResampler(44100, 2) // a chunked one: one stream
rs.write(chunk) // planar chunk → interleaved 48 kHz, what is ready
rs.flush() // the rest: round(n · 48000 / 44100) in all