Thin Flutter wrapper around opus_dart and opus_flutter. Encodes
fixed-size PCM16LE frames to Opus packets and decodes them back.
ForgeEncoder/ForgeDecoder, a minimal encode/decode API overopus_dart'sSimpleOpusEncoder/SimpleOpusDecoder- Input-size validation on encode with a clear error message
- Packet-loss concealment and forward-error-correction support on decode
- PCM16LE ⇄
Int16Listconversion helpers with explicit endianness
Load libopus once, before constructing any encoder or decoder:
await ForgeInit.ensure();Safe to call from more than one place — the actual native library load only happens once, and every call after that awaits the same future.
Supported formats:
- Sample rates: 8000, 12000, 16000, 24000, 48000 Hz
- Channels: 1 or 2
final encoder = ForgeEncoder(
sampleRate: 48000,
channels: 2,
samplesPerChannel: 960, // 20ms at 48kHz
);
final opusPacket = encoder.encode(pcmFrame); // pcmFrame: PCM16LE, interleaved
encoder.dispose(); // releases native memory when donepcmFrame needs to be exactly samplesPerChannel * channels * 2 bytes
(encoder.expectedInputBytes) — frames straight from framer's
PcmFramer, configured with a matching frame size, work well here.
samplesPerChannel has to correspond to one of Opus's supported frame
durations at the given sample rate (2.5/5/10/20/40/60 ms).
application (defaults to Application.audio) tunes the encoder for its
content: audio for music/general audio, voip for speech, or
restrictedLowdelay when latency matters more than quality.
final decoder = ForgeDecoder(sampleRate: 48000, channels: 2);
final pcmFrame = decoder.decode(opusPacket); // PCM16LE bytes out
decoder.dispose();sampleRate/channels need to match what the encoder on the sending side
used — Opus packets don't carry that information themselves.
Pass null instead of a packet to signal a lost one; Opus's built-in
packet loss concealment synthesizes a plausible continuation instead of a
gap. Pass fec: true on the next packet to recover a previous lost one
from embedded forward-error-correction data, if the encoder had FEC turned
on.
pcm16leBytesToSamples / samplesToPcm16leBytes (also exported from
forge.dart) convert between raw interleaved PCM16LE bytes and the
Int16List samples opus_dart's encode/decode calls expect, with an
explicit little-endian read/write.