What is ogg-opus-decoder?
The ogg-opus-decoder npm package is a JavaScript library that allows you to decode Ogg Opus audio files. It is useful for applications that need to handle audio streaming or playback in the browser or in Node.js environments.
What are ogg-opus-decoder's main functionalities?
Decoding Ogg Opus Files
This feature allows you to decode an Ogg Opus file and output the raw PCM data. The code sample demonstrates how to set up a stream to read an Ogg Opus file, decode it, and write the decoded PCM data to an output file.
const { OggOpusDecoder } = require('ogg-opus-decoder');
const fs = require('fs');
const decoder = new OggOpusDecoder();
const input = fs.createReadStream('path/to/your/file.ogg');
const output = fs.createWriteStream('path/to/output/file.pcm');
input.pipe(decoder).pipe(output);
Streaming Decoded Audio
This feature allows you to stream decoded audio directly to a speaker. The code sample demonstrates how to read an Ogg Opus file, decode it, and stream the audio to a speaker for playback.
const { OggOpusDecoder } = require('ogg-opus-decoder');
const fs = require('fs');
const Speaker = require('speaker');
const decoder = new OggOpusDecoder();
const input = fs.createReadStream('path/to/your/file.ogg');
const speaker = new Speaker({
channels: 2, // 2 channels (stereo)
bitDepth: 16, // 16-bit samples
sampleRate: 48000 // 48,000 Hz sample rate
});
input.pipe(decoder).pipe(speaker);
Other packages similar to ogg-opus-decoder
node-opus
node-opus is a Node.js native binding to libopus, which allows for encoding and decoding of Opus audio streams. Unlike ogg-opus-decoder, node-opus provides more low-level control over the encoding and decoding process, making it suitable for applications that need to handle Opus audio streams directly.
opusscript
opusscript is a pure JavaScript implementation of the Opus codec. It can be used in both Node.js and browser environments. While it offers similar functionality to ogg-opus-decoder, it is not as performant as native bindings like node-opus or ogg-opus-decoder due to being implemented in JavaScript.
web-audio-api
web-audio-api is a high-level API for processing and synthesizing audio in web applications. It provides a wide range of audio processing capabilities, including decoding audio files. While it is more general-purpose compared to ogg-opus-decoder, it can be used to achieve similar results for decoding and playing back audio.
ogg-opus-decoder
ogg-opus-decoder
is a Web Assembly Ogg Opus audio decoder.
- 115.1 KiB minified bundle size
- Built in Web Worker support
- Based on
libopusfile
See the homepage of this repository for more Web Assembly audio decoders like this one.
Installing
-
Install from NPM.
Run npm i mpg123-decoder
import { OggOpusDecoder } from 'ogg-opus-decoder';
const decoder = new OggOpusDecoder();
-
Or download the build and include it as a script.
<script src="ogg-opus-decoder.min.js"></script>
<script>
const decoder = new OggOpusDecoder();
</script>
Usage
-
Create a new instance and wait for the WASM to finish compiling. Decoding can be done on the main thread synchronously, or in a webworker asynchronously.
Main thread synchronous decoding
import { OggOpusDecoder } from 'ogg-opus-decoder';
const decoder = new OggOpusDecoder();
await decoder.ready;
Web Worker asynchronous decoding
import { OggOpusDecoderWebWorker } from 'ogg-opus-decoder';
const decoder = new OggOpusDecoderWebWorker();
await decoder.ready;
-
Begin decoding Ogg Opus data.
const {channelData, samplesDecoded, sampleRate} = decoder.decode(oggOpusData);
- NOTE: When decoding chained Ogg files (i.e. streaming) the first two Ogg packets of the next chain must be present when decoding. Errors will be returned by libopusfile if these initial Ogg packets are incomplete.
-
When done decoding, reset the decoder to decode a new stream, or free up the memory being used by the WASM module if you have no more audio to decode.
decoder.reset();
decoder.free();
API
Decoded audio is always returned in the below structure.
{
channelData: [
leftAudio,
rightAudio
],
samplesDecoded: 1234,
sampleRate: 48000
}
Each Float32Array within channelData
can be used directly in the WebAudio API for playback.
OggOpusDecoder
Class that decodes Ogg Opus data synchronously on the main thread.
Getters
decoder.ready
async
- Returns a promise that is resolved when the WASM is compiled and ready to use.
Methods
decoder.decode(oggOpusData)
opusFrame
Uint8Array containing Ogg Opus data.- Returns decoded audio.
decoder.reset()
async
- Resets the decoder so that a new stream of Ogg Opus data can be decoded.
decoder.free()
- De-allocates the memory used by the decoder.
- After calling
free()
, the current instance is made unusable, and a new instance will need to be created to decode additional Ogg Opus data.
OggOpusDecoderWebWorker
Class that decodes Ogg Opus data asynchronously within a web worker. Decoding is performed in a separate, non-blocking thread. Each new instance spawns a new worker allowing you to run multiple workers for concurrent decoding of multiple streams.
Getters
decoder.ready
async
- Returns a promise that is resolved when the WASM is compiled and ready to use.
Methods
decoder.decode(oggOpusData)
*Async
opusFrame
Uint8Array containing Ogg Opus data.- Returns a promise that resolves with the decoded audio.
decoder.reset()
async
- Resets the decoder so that a new stream of Ogg Opus data can be decoded.
decoder.free()
async
- De-allocates the memory used by the decoder and terminates the web worker.
- After calling
free()
, the current instance is made unusable, and a new instance will need to be created to decode additional Ogg Opus data.
Properly using the Web Worker interface
OggOpusDecoderWebWorker
uses async functions to send operations to the web worker without blocking the main thread. To fully take advantage of the concurrency provided by web workers, your code should avoid using await
on decode operations where it will block the main thread.
Each method call on a OggOpusDecoderWebWorker
instance will queue up an operation to the web worker. Operations will complete within the web worker thread one at a time and in the same order in which the methods were called.
-
Good Main thread is not blocked during each decode operation. The example playAudio
function is called when each decode operation completes. Also, the next decode operation can begin while playAudio
is doing work on the main thread.
const playAudio = ({ channelData, samplesDecoded, sampleRate }) => {
}
decoder.decodeFrame(data1).then(playAudio);
decoder.decodeFrame(data2).then(playAudio);
decoder.decodeFrame(data3).then(playAudio);
-
Bad Main thread is being blocked by await
during each decode operation. Synchronous code is halted while decoding completes, negating the benefits of using a webworker.
const decoded1 = await decoder.decodeFrame(data1);
playAudio(decoded1);
const decoded2 = await decoder.decodeFrame(data2);
playAudio(decoded2);
const decoded3 = await decoder.decodeFrame(data3);
playAudio(decoded3);