decibri-web is a browser-based microphone capture library. It uses the Web Audio API and AudioWorklet to capture raw PCM audio chunks in real-time. Same API as decibri for Node.js, different runtime. Zero dependencies, 6.4KB ESM bundle.
| Package | Environment | Backend |
|---|---|---|
| decibri | Node.js | Native C++ (PortAudio) |
| decibri-web | Browser | Web Audio API |
Or via CDN:
<script src="https://unpkg.com/decibri-web/dist/index.global.js"></script>
Capture microphone audio and log the chunk size:
import { Decibri } from 'decibri-web';
const mic = new Decibri({ sampleRate: 16000 });
mic.on('data', (chunk) => {
console.log(`Received ${chunk.length} samples`);
});
await mic.start();
start() must be called from a user gesture (click/tap) in Safari. Each chunk contains 100 ms of audio by default (1,600 frames at 16 kHz).
Microphone access requires HTTPS (or localhost). The browser will show a permission prompt when start() is called.
start() rejects with Error('Microphone permission denied')'error' event also fires with the same errorDecibri.devices() may be empty before permission is grantedmic.stop();
stop() releases all resources: MediaStream tracks are stopped, AudioContext is closed, all nodes are disconnected, references are nulled. Safe for React/Vue component unmount cycles. Safe to call multiple times or before start().
To restart after stopping:
await mic.start(); // creates a fresh audio pipeline
// Start first to trigger permission, then enumerate with labels
await mic.start();
const devices = await Decibri.devices();
console.log(devices);
// [{ deviceId: 'abc123', label: 'Built-in Microphone', groupId: 'g1' }, ...]
// Use a specific device
const usbMic = new Decibri({ device: devices[1].deviceId });
await usbMic.start();
// Int16 PCM (default) - ready for most STT engines
const mic = new Decibri({ format: 'int16' });
mic.on('data', (chunk) => {
// chunk is an Int16Array
});
// Float32 - native browser format, no conversion
const mic2 = new Decibri({ format: 'float32' });
mic2.on('data', (chunk) => {
// chunk is a Float32Array
});
Enable the built-in VAD to receive 'speech' and 'silence' events based on RMS energy thresholding:
const mic = new Decibri({
sampleRate: 16000,
vad: true,
vadThreshold: 0.01,
vadHoldoff: 300,
});
mic.on('speech', () => console.log('Speaking...'));
mic.on('silence', () => console.log('Silence'));
await mic.start();
const ws = new WebSocket('wss://your-server.com/audio');
const mic = new Decibri({ sampleRate: 16000, format: 'int16' });
mic.on('data', (chunk) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(chunk.buffer);
}
});
document.getElementById('start').onclick = () => mic.start();
document.getElementById('stop').onclick = () => mic.stop();
Requires HTTPS (or localhost) for microphone access.
| Browser | Minimum Version |
|---|---|
| Chrome | 66+ |
| Firefox | 76+ |
| Safari | 14.1+ (requires user gesture) |
| Edge | 79+ |
| iOS Safari | 14.5+ |
| Android Chrome | 66+ |
By default, decibri-web loads its AudioWorklet processor via an inline Blob URL. If your Content Security Policy blocks blob: URLs:
const mic = new Decibri({
workletUrl: '/static/decibri-worklet.js',
});
Copy node_modules/decibri-web/dist/worklet.js to your static assets directory and pass the URL.