native-recorder-nodejs
v1.0.8
Published
Cross-platform (Win/Mac) Native Audio SDK for Node.js
Maintainers
Readme
Native Recorder for Node.js
High-performance, low-latency native audio recording SDK for Node.js. Supports both microphone input and system audio capture (loopback) on Windows and macOS.
Features
- Microphone Recording - Capture audio from any input device
- System Audio Capture - Record what's playing on your computer (loopback)
- Cross-Platform - Windows (WASAPI) and macOS (AVFoundation + ScreenCaptureKit)
- High Performance - Native C++ implementation with minimal latency
- Prebuilt Binaries - No compilation required for most platforms
- Type Safe - Full TypeScript support
Platform Support
| Platform | Architecture | Input (Mic) | Output (System Audio) | | ------------- | ------------ | ----------- | ----------------------- | | Windows 10/11 | x64 | Supported | Supported (per-device) | | Windows 10/11 | ia32 | Supported | Supported (per-device) | | macOS 13.0+ | arm64 | Supported | Supported (system-wide) | | macOS 13.0+ | x64 | Supported | Supported (system-wide) |
Platform Differences
| Feature | Windows | macOS | | -------------- | --------------------- | ------------------------------ | | Input Devices | Multiple (WASAPI) | Multiple (AVFoundation) | | Output Devices | Multiple (per-device) | Single "System Audio" device | | Permissions | None required | Microphone + Screen Recording | | Min OS Version | Windows 10+ | macOS 13.0+ (for system audio) |
Installation
npm install native-recorder-nodejsPrebuilt binaries are available for most platforms. If a prebuild is not available, the package will compile from source (requires CMake and a C++ compiler).
Quick Start
import { AudioRecorder, SYSTEM_AUDIO_DEVICE_ID } from 'native-recorder-nodejs';
import * as fs from 'fs';
const recorder = new AudioRecorder();
// List available devices
const inputs = AudioRecorder.getDevices('input');
const outputs = AudioRecorder.getDevices('output');
console.log('Microphones:', inputs);
console.log('Output devices:', outputs);
// Record from default microphone
const mic = inputs.find(d => d.isDefault);
if (mic) {
const output = fs.createWriteStream('recording.raw');
recorder.on('data', (buffer) => {
output.write(buffer);
});
recorder.on('error', (error) => {
console.error('Recording error:', error);
});
await recorder.start({
deviceType: 'input',
deviceId: mic.id
});
// Record for 5 seconds
setTimeout(async () => {
await recorder.stop();
output.end();
console.log('Recording saved!');
}, 5000);
}Record System Audio
// Get system audio device
const outputs = AudioRecorder.getDevices('output');
const systemAudio = outputs.find(d => d.id === SYSTEM_AUDIO_DEVICE_ID)
|| outputs.find(d => d.isDefault);
if (systemAudio) {
await recorder.start({
deviceType: 'output',
deviceId: systemAudio.id
});
}API Reference
AudioRecorder
The main class for controlling audio recording.
Constructor
const recorder = new AudioRecorder();Instance Methods
start(config: RecordingConfig): Promise<void>
Starts recording from the specified device.
interface RecordingConfig {
deviceType: 'input' | 'output'; // Required
deviceId: string; // Required
}
await recorder.start({
deviceType: 'input',
deviceId: 'device-uuid'
});stop(): Promise<void>
Stops the recording session.
await recorder.stop();Static Methods
getDevices(type?: DeviceType): AudioDevice[]
Lists available audio devices.
interface AudioDevice {
id: string; // Unique identifier
name: string; // Human-readable name
type: 'input' | 'output';
isDefault: boolean;
}
const allDevices = AudioRecorder.getDevices();
const microphones = AudioRecorder.getDevices('input');
const outputs = AudioRecorder.getDevices('output');getDeviceFormat(deviceId: string): AudioFormat
Gets the audio format of a device.
interface AudioFormat {
sampleRate: number; // e.g., 48000
channels: number; // 1 (mono) or 2 (stereo)
bitDepth: number; // Output bit depth (16)
rawBitDepth: number; // Native device bit depth
}
const format = AudioRecorder.getDeviceFormat(device.id);checkPermission(): PermissionStatus
Checks current permission status.
interface PermissionStatus {
mic: boolean; // Microphone permission
system: boolean; // System audio permission
}
const status = AudioRecorder.checkPermission();requestPermission(type: 'mic' | 'system'): boolean
Requests permission for recording.
const granted = AudioRecorder.requestPermission('mic');
const systemGranted = AudioRecorder.requestPermission('system');Events
'data'
Emitted when audio data is available.
recorder.on('data', (buffer: Buffer) => {
// Raw PCM 16-bit LE audio data
});'error'
Emitted when an error occurs.
recorder.on('error', (error: Error) => {
console.error(error.message);
});Constants
// Special device ID for system-wide audio capture on macOS
export const SYSTEM_AUDIO_DEVICE_ID = 'system';Audio Format
The output is always:
- Format: Raw PCM
- Bit Depth: 16-bit signed integer
- Endianness: Little Endian
- Sample Rate: 48kHz on macOS (fixed), native device rate on Windows (commonly 44.1kHz or 48kHz)
- Channels: Stereo on macOS (fixed), preserved from source on Windows
Playing Raw Audio
You can play the recorded raw audio using FFplay:
ffplay -f s16le -ar 48000 -ch_layout stereo recording.rawOr convert to WAV using FFmpeg:
ffmpeg -f s16le -ar 48000 -ac 2 -i recording.raw output.wavPermissions (macOS)
On macOS, you need to grant permissions:
- Microphone - Required for input device recording
- Screen Recording - Required for system audio capture
The SDK will automatically prompt for permissions when needed, or you can request them programmatically:
const permissions = AudioRecorder.checkPermission();
if (!permissions.mic) {
AudioRecorder.requestPermission('mic');
}
if (!permissions.system) {
AudioRecorder.requestPermission('system');
}Error Handling
| Error Code | Description |
| ---------------------- | ------------------------------------------ |
| DEVICE_NOT_FOUND | Specified device ID does not exist |
| DEVICE_TYPE_MISMATCH | Device ID doesn't match the specified type |
| PERMISSION_DENIED | Missing required system permission |
| ALREADY_RECORDING | Recording session already active |
| DEVICE_DISCONNECTED | Device was disconnected during recording |
Building from Source
Prerequisites
- Node.js 16+
- CMake 3.15+
- C++17 compiler
- Windows: Visual Studio 2019+ or MSVC Build Tools
- macOS: Xcode Command Line Tools
Build Commands
# Install dependencies
npm install
# Build native module
npm run build:native
# Build TypeScript
npm run build:ts
# Build everything
npm run build
# Run tests
npm testPublishing
# Build prebuilt binaries for current platform
npm run prebuild
# Upload prebuilts to GitHub Release (requires GITHUB_TOKEN)
npm run prebuild:upload
# Publish to npm (prebuilts should be uploaded first)
npm publishCI/CD with GitHub Actions
The project uses GitHub Actions for automated builds and releases. The workflow is triggered by:
| Trigger | Action |
| ------------------------------ | ------------------------------------------------------ |
| Push to main | Build and test on all platforms |
| Pull Request to main | Build and test on all platforms |
| Push tag v* (e.g., v1.0.0) | Build, test, publish to npm, and create GitHub Release |
To release a new version:
# 1. Update version in package.json
npm version patch # or minor, major
# 2. Push the tag to trigger the release workflow
git push origin main --tagsThe CI will automatically:
- Build native modules for all platforms (macOS arm64/x64, Windows x64/ia32)
- Run tests on each platform
- Publish the package to npm with prebuilt binaries
- Create a GitHub Release with the native binaries attached
Note: Ensure
NPM_TOKENis configured in repository secrets for npm publishing.
Architecture
┌─────────────────────────────────────────────────┐
│ Node.js Application │
├─────────────────────────────────────────────────┤
│ TypeScript Wrapper │
├─────────────────────────────────────────────────┤
│ N-API Binding Layer │
├────────────────────┬────────────────────────────┤
│ Windows │ macOS │
│ (WASAPI) │ (AVFoundation + │
│ │ ScreenCaptureKit) │
└────────────────────┴────────────────────────────┘For detailed architecture documentation, see docs/architecture.md.
For complete API documentation, see docs/api.md.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE for details.
Acknowledgments
- node-addon-api - N-API C++ wrapper
- cmake-js - CMake build system for Node.js addons
