ποΈ Framework-agnostic multi-format audio recorder with MP3 and WAV support. Built on top of Kagami/vmsg for MP3 encoding, with custom PCMβWAV encoder.
- π― Multi-format support: MP3 (vmsg WASM), WAV (PCMβWAV)
- π¦ Zero dependencies: No runtime deps, just Web Audio API
- π Modern APIs: Uses AudioWorklet (not deprecated ScriptProcessorNode)
- ποΈ Pitch shift: Built-in pitch adjustment for MP3 format
- π Browser support: Works in all modern browsers (Chrome, Firefox, Safari, Edge)
- π± TypeScript: Full TypeScript support with type definitions
- β‘ Lightweight: MP3 encoder ~73 KB gzipped, WAV no WASM needed
npm install react-ts-audio-recorderimport { MultiRecorder } from "react-ts-audio-recorder";
import vmsgWasm from "react-ts-audio-recorder/assets/vmsg.wasm?url";
const recorder = new MultiRecorder({
format: "mp3", // "mp3" | "wav"
sampleRate: 48000,
wasmURL: vmsgWasm, // Only needed for MP3
});
await recorder.init();
await recorder.startRecording();
// ... recording ...
const blob = await recorder.stopRecording();
recorder.close();import { useState, useRef } from "react";
import { MultiRecorder, type AudioFormat } from "react-ts-audio-recorder";
import vmsgWasm from "react-ts-audio-recorder/assets/vmsg.wasm?url";
function AudioRecorder() {
const [isRecording, setIsRecording] = useState(false);
const recorderRef = useRef<MultiRecorder | null>(null);
const startRecording = async () => {
const recorder = new MultiRecorder({
format: "wav", // or "mp3"
sampleRate: 48000,
wasmURL: vmsgWasm,
});
recorderRef.current = recorder;
await recorder.init();
await recorder.startRecording();
setIsRecording(true);
};
const stopRecording = async () => {
if (!recorderRef.current) return;
const blob = await recorderRef.current.stopRecording();
recorderRef.current.close();
recorderRef.current = null;
setIsRecording(false);
// Use the blob (e.g., create audio URL)
const url = URL.createObjectURL(blob);
console.log("Recorded audio:", url);
};
return (
<div>
<button onClick={isRecording ? stopRecording : startRecording}>
{isRecording ? "Stop" : "Start"} Recording
</button>
</div>
);
}Main class for recording audio in multiple formats.
new MultiRecorder(options: MultiRecorderOptions)| Option | Type | Default | Description |
|---|---|---|---|
format |
"mp3" | "wav" |
Required | Output audio format |
sampleRate |
number |
48000 |
Sample rate in Hz |
wasmURL |
string |
"/vmsg.wasm" |
URL to vmsg.wasm (MP3 only) |
shimURL |
string |
undefined |
WebAssembly polyfill URL (MP3 only) |
pitch |
number |
0 |
Pitch shift [-1, 1] (MP3 only) |
workletURL |
string |
"/pcm-worklet.js" |
PCM worklet URL (WAV only) |
Initialize the recorder. Must be called before startRecording().
await recorder.init();Start recording audio from the microphone.
await recorder.startRecording();Stop recording and return the audio blob.
const blob = await recorder.stopRecording();
// blob.type will be:
// - "audio/mpeg" for MP3
// - "audio/wav" for WAVClean up resources. Always call this when done.
recorder.close();| Format | Encoder | WASM Required | File Size | Quality | Browser Support |
|---|---|---|---|---|---|
| MP3 | vmsg (LAME) | β Yes | Small | Good | All modern browsers |
| WAV | Custom PCMβWAV | β No | Large | Lossless | All modern browsers |
// Import WASM file
import vmsgWasm from "react-ts-audio-recorder/assets/vmsg.wasm?url";
// Import PCM worklet
import pcmWorklet from "react-ts-audio-recorder/assets/pcm-worklet.js?url";
const recorder = new MultiRecorder({
format: "wav",
wasmURL: vmsgWasm,
workletURL: pcmWorklet,
});import { DEFAULT_VMSG_WASM_URL, PCM_WORKLET_URL, loadPCMWorklet } from "react-ts-audio-recorder";
// Use default URLs
const recorder = new MultiRecorder({
format: "mp3",
wasmURL: DEFAULT_VMSG_WASM_URL,
});
// Load worklet manually
const audioContext = new AudioContext();
await loadPCMWorklet(audioContext, PCM_WORKLET_URL);If not using a bundler, copy assets to your public directory:
public/
vmsg.wasm
pcm-worklet.js
Then reference them:
const recorder = new MultiRecorder({
format: "mp3",
wasmURL: "/vmsg.wasm",
workletURL: "/pcm-worklet.js",
});See the full React example in example/vite-demo/:
cd example/vite-demo
npm install
npm run devThe demo includes:
- Format selector (MP3/WAV)
- Real-time recording timer
- Audio preview and download
- Error handling
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Type check
npm run typecheck- MP3: Requires WebAssembly support (all modern browsers)
- WAV: Works everywhere (no WASM needed)
- MP3: Best compression, universal support, requires WASM
- WAV: No compression, largest files, fastest encoding, no WASM needed
This library uses AudioWorklet (modern API) instead of deprecated ScriptProcessorNode for better performance and future compatibility.
MIT Β© 2025 ThangDevAlone
The MP3 encoder and CSS originate from Kagami/vmsg (CC0). Please keep attribution when redistributing.
- Kagami/vmsg - Original MP3 encoder implementation
- Web Audio API - Modern audio processing