Skip to main content
Version: Next

AudioRecorder

AudioRecorder is a primary interface for capturing audio. It supports three main modes of operations:

  • File recording: Writing audio data directly to the filesystem.
  • Data callback: Emitting raw audio buffers, that can be used in either further processing or streamed.
  • Graph processing: Connect the recorder with either AudioContext or OfflineAudioContext for further more advanced and/or realtime processing.

Configuration

To access microphone you need to make sure your app has required permission configuration - check getting started permission section for more information.

Additionally to be able to record audio while application is in the background, you need to enable background mode on iOS and configure foreground service on android.

In an Expo application you can do so through react-native-audio-api expo plugin, e.g.

{
"plugins": [
[
"react-native-audio-api",
{
"iosBackgroundMode": true,
"iosMicrophonePermission": "[YOUR_APP_NAME] requires access to the microphone to record audio.",
"androidPermissions" : [
"android.permission.RECORD_AUDIO",
"android.permission.FOREGROUND_SERVICE",
"android.permission.FOREGROUND_SERVICE_MICROPHONE",
],
"androidForegroundService": true,
"androidFSTypes": ["microphone"]
}
]
]
}

For more configuration options, check out the Expo plugin section.

Examples

import React, { useState } from 'react';
import { View, Pressable, Text } from 'react-native';
import { AudioRecorder, AudioManager } from 'react-native-audio-api';

AudioManager.setAudioSessionOptions({
iosCategory: 'record',
iosMode: 'default',
iosOptions: [],
});

const audioRecorder = new AudioRecorder();

// Enables recording to file with default configuration
audioRecorder.enableFileOutput();

const MyRecorder: React.FC = () => {
const [isRecording, setIsRecording] = useState(false);

const onStart = async () => {
if (isRecording) {
return;
}

// Make sure the permissions are granted
const permissions = await AudioManager.requestRecordingPermissions();

if (permissions !== 'Granted') {
console.warn('Permissions are not granted');
return;
}

// Activate audio session
try {
await AudioManager.setAudioSessionActivity(true);
} catch (error) {
console.warn('Could not activate the audio session', error);
return;
}

const result = await audioRecorder.start();
if (result.status === 'error') {
console.warn(result.message);
return;
}

console.log('Recording started');
setIsRecording(true);
};

const onStop = async () => {
if (!isRecording) {
return;
}

const result = await audioRecorder.stop();
console.log(result);
setIsRecording(false);
await AudioManager.setAudioSessionActivity(false);
};

return (
<View>
<Pressable onPress={isRecording ? onStop : onStart}>
<Text>{isRecording ? 'Stop' : 'Record'}</Text>
</Pressable>
</View>
);
};

export default MyRecorder;

Constructor

constructor(options?: AudioRecorderOptions)

Creates a new AudioRecorder instance, optionally configuring the platform capture chain - see AudioRecorderOptions.

info

It is preferred to create only a single instance of AudioRecorder for the best performance, memory, and battery consumption. While an idle recorder has minimal impact, switching between separate recorder instances might have a noticeable impact on the device.

import { AudioRecorder } from 'react-native-audio-api';

const audioRecorder = new AudioRecorder();

Full-duplex voice apps (playing audio while recording) need platform echo cancellation on both platforms, otherwise the speaker output leaks back into the microphone:

const audioRecorder = new AudioRecorder({
androidInputPreset: 'voiceCommunication',
iosVoiceProcessing: true,
});

Properties

NameTypeDescription
optionsAudioRecorderFileOptions | nullActive file-output configuration after enableFileOutput(), or null when file output is disabled.
inputLatencynumberReturns the estimated full input latency in seconds (from analog input to app delivery). Mirrors AudioContext.outputLatency semantics. Calculated using underlying platform properties (AVAudioSession on iOS; Oboe timestamps/burst sizes on Android). Value may change when the audio route changes. Returns 0 when idle.

Methods

start

Starts the stream from the system audio input device.

ParameterTypeDescription
options
Optional
AudioRecorderStartOptionsOptional recording start configuration.
Returns Promise<Result<{}>>.
const result = await audioRecorder.start({
fileNameOverride: `my_audio_${mySessionId}`,
});

console.log(result.status);

stop

Stops the input stream and cleans up each input access method.

For details on the returned file information, see FileInfo.

Returns Promise<Result<FileInfo>>.
const result = await audioRecorder.stop();

if (result.status === 'success') {
const { paths, duration, size } = result;
} else if (result.status === 'error') {
console.error(result.message);
}

pause

Pauses the recording. This is useful when recording to file is active, but you do not want to finalize the file.

audioRecorder.pause();

resume

Resumes the recording if it was previously paused; otherwise does nothing.

audioRecorder.resume();

isRecording

Returns true if the recorder is in an active recording state.

Returns boolean.
const isRecording = audioRecorder.isRecording();

isPaused

Returns true if the recorder is in a paused state.

Returns boolean.
const isPaused = audioRecorder.isPaused();

getCurrentDuration

Returns the current recording duration when file output is enabled.

Returns number.
const duration = audioRecorder.getCurrentDuration();

enableFileOutput

Configures and enables file output with the given options and stream properties. By default, the recorder writes to the cache directory using a high-quality M4A file.

For further information, see AudioRecorderFileOptions.

ParameterTypeDescription
options
Optional
AudioRecorderFileOptionsFile output configuration.
Returns Result<{}>.
audioRecorder.enableFileOutput();

disableFileOutput

Disables file output and finalizes the currently recorded file if the recorder is active.

audioRecorder.disableFileOutput();

onAudioReady

Registers a callback that receives raw audio buffers during an active recording session.

The callback is periodically invoked with audio buffers that match the preferred configuration provided in options. These parameters guide how audio data is chunked and delivered, though the exact values may vary depending on device capabilities.

For further information, see AudioRecorderCallbackOptions and OnAudioReadyEventType.

ParameterTypeDescription
optionsAudioRecorderCallbackOptionsPreferred callback buffer configuration.
callback(event: OnAudioReadyEventType) => voidFunction invoked when a new audio buffer is available.
Returns Result<void>.
const sampleRate = 16000;

audioRecorder.onAudioReady(
{
sampleRate,
bufferLength: 0.1 * sampleRate, // 0.1s of data
channelCount: 1,
},
({ buffer, numFrames, when }) => {
// do something with the data
}
);

clearOnAudioReady

Removes the audio data callback and flushes any remaining buffered data through onAudioReady.

audioRecorder.clearOnAudioReady();

connect

Routes captured audio into an audio graph by creating a recorder adapter with BaseAudioContext.createRecorderAdapter(), connecting the recorder to it, and wiring it to destination.

ParameterTypeDescription
contextBaseAudioContextAudio context used to create the recorder adapter.
destinationAudioNodeDestination node in the audio graph.

Returns AudioNode.

audioRecorder.connect(audioContext, audioContext.destination);

disconnect

Disconnects AudioRecorder from the audio graph.

audioRecorder.disconnect();

onError

Sets an error callback for internal errors that might happen during file writing, callback invocation, or adapter access.

For details, see OnRecorderErrorEventType.

ParameterTypeDescription
callback(error: OnRecorderErrorEventType) => voidError handler invoked when recording fails.
audioRecorder.onError((error) => {
console.log(error);
});

clearOnError

Removes the error callback.

audioRecorder.clearOnError();

Types

AudioRecorderOptions

interface AudioRecorderOptions {
androidInputPreset?: AndroidInputPreset;
iosVoiceProcessing?: boolean;
}
ParameterTypeDefaultDescription
androidInputPreset
Optional
Android
AndroidInputPreset'voiceRecognition'Preprocessing chain applied to the capture stream. The platform default, voiceRecognition, applies no acoustic echo cancellation - use voiceCommunication to engage the platform AEC/NS chain.
iosVoiceProcessing
Optional
iOS
booleanfalseRuns the capture chain through Apple's voice-processing I/O: acoustic echo cancellation, noise suppression and automatic gain control.

Both options are applied when the capture stream is created and cannot be changed afterwards - create a new recorder to switch configuration. Each option is ignored on the other platform.

caution

Voice processing changes the hardware input format and engages a shared platform processing unit, so the resolved sample rate and channel count of the recorded audio may differ from the raw microphone format.

AndroidInputPreset

type AndroidInputPreset =
| 'generic'
| 'camcorder'
| 'voiceRecognition'
| 'voiceCommunication'
| 'unprocessed'
| 'voicePerformance';

Names of Oboe's InputPreset values, which select the preprocessing chain the capture stream is opened with.

AudioRecorderStartOptions

interface AudioRecorderStartOptions {
fileNameOverride?: string;
}
ParameterTypeDescription
fileNameOverride
Optional
stringCustom file name used when recording to file.

AudioRecorderCallbackOptions

interface AudioRecorderCallbackOptions {
sampleRate: number;
bufferLength: number;
channelCount: number;
}
  • sampleRate - The desired sample rate (in Hz) for audio buffers delivered to the recording callback. Common values include 44100 or 48000 Hz. The actual sample rate may differ depending on hardware and system capabilities.

  • bufferLength - The preferred size of each audio buffer, expressed as the number of samples per channel. Smaller buffers reduce latency but increase CPU load, while larger buffers improve efficiency at the cost of higher latency.

  • channelCount - The desired number of audio channels per buffer. Typically 1 for mono or 2 for stereo recordings.

OnRecorderErrorEventType

interface OnRecorderErrorEventType {
message: string;
}

OnAudioReadyEventType

Represents the data payload received by the audio recorder callback each time a new audio buffer becomes available during recording.

interface OnAudioReadyEventType {
buffer: AudioBuffer;
numFrames: number;
when: number;
}
  • buffer - The audio buffer containing the recorded PCM data. This buffer includes one or more channels of floating-point samples in the range of -1.0 to 1.0.
  • numFrames - The number of audio frames contained in this buffer. A frame represents a single sample across all channels.
  • when - The timestamp (in seconds) indicating when this buffer was captured, relative to the start of the recording session.

File handling

AudioRecorderFileOptions

interface AudioRecorderFileOptions {
channelCount?: number;
rotateIntervalBytes?: number;

format?: FileFormat;
preset?: FilePresetType;

directory?: FileDirectory;
subDirectory?: string;
fileNamePrefix?: string;
androidFlushIntervalMs?: number;
}
  • channelCount - The desired channel count in the resulting file. not all file formats supports all possible channel counts.
  • rotateIntervalBytes - The threshold size (in bytes) at which the recorder will start writing to a new file. If set to 0 (default), file output rotation is disabled. When active, new files are named with the original prefix appended with a timestamp. You can join the rotated files after recording with concatAudioFiles.
    • Use a large enough value for your format. Very small thresholds rotate often, which increases the chance of audible gaps or muffled joins after concatenation — especially for M4A, where each segment is a separate AAC encode.
    • Practical starting points: ≥ 1 MB for WAV, ≥ 200 KB for M4A (adjust upward if you still hear artifacts at segment boundaries).
    • This option controls segment file size, not RAM usage. For crash-resilience tuning on Android, use androidFlushIntervalMs instead.
  • format - The desired extension and file format of the recorder file. Check: FileFormat below.
  • preset - The desired recorder file properties, you can use either one of built-in properties or tweak low-level parameters yourself. Check FilePresetType for more details.
  • directory - Either FileDirectory.Cache or FileDirectory.Document (default: FileDirectory.Cache). Determines the system directory that the file will be saved to.
  • subDirectory - If configured it will create the recording inside requested directory (default: undefined).
  • fileNamePrefix - Prefix of the recording files without the unique ID (default: recording).
  • androidFlushIntervalMs - How often the recorder should force the system to write data to the device storage (default: 500).
    • Lower values are good for crash-resilience and are more memory friendly.
    • Higher values are more battery - and storage-efficient.

FileFormat

Describes desired file extension as well as codecs, containers (and muxers!) used to encode the file.

enum FileFormat {
Wav,
Caf,
M4A,
Flac,
}
Android + FFmpeg

On Android, encoded file output for M4A, FLAC, and CAF uses FFmpeg. When FFmpeg is disabled in the build, only WAV recording to file is supported. iOS uses system AVFoundation for all listed formats. See Runtime flags.

FileInfo

interface FileInfo {
paths: string[];
size: number;
duration: number;
}
  • paths - Paths to the recorded audio files. When file rotation is disabled it has only one entry, otherwise list of paths to recorder files is returned.
  • size - The file size (in MB).
  • duration - The recording duration (in seconds).

FilePresetType

Describes the audio format that is used during writing to file as well as encoded final file properties. You can use one of predefined presets, or fully customize the result file, but be aware that the properties aren't limited to only valid configurations, you may find property pairs that will result in error result during recording start (or when enabling the file output during active input session)!

Built-in file presets

For convenience we have provided a set of most basic file configurations that should cover most of the cases (or at least we hope they will, please raise an issue if you find something lacking or misconfigured!).

Usage
import { AudioRecorder, FileFormat, FilePreset } from 'react-native-audio-api';

const audioRecorder = new AudioRecorder();

audioRecorder.enableFileOutput({
format: FileFormat.M4A,
preset: FilePreset.High,
});
Preset
Description
Lossless

Writes audio data directly to file without encoding, preserving the maximum audio quality supported by the device. This results in large file sizes, particularly for longer recordings. Available only when using WAV or CAF file formats.

audioRecorder.enableFileOutput({
format: FileFormat.Caf,
preset: FilePreset.Lossless,
});
High Quality

Uses high-fidelity audio parameters with efficient encoding to deliver near-lossless perceptual quality while producing smaller files than fully uncompressed recordings. Suitable for music and high-quality voice capture.

audioRecorder.enableFileOutput({
format: FileFormat.Flac,
preset: FilePreset.High,
});
Medium Quality

Uses balanced audio parameters that provide good perceptual quality while keeping file sizes moderate. Intended for everyday recording scenarios such as voice notes, podcasts, and general in-app audio, where efficiency and compatibility outweigh maximum fidelity.

audioRecorder.enableFileOutput({
format: FileFormat.M4A,
preset: FilePreset.Medium,
});
Low Quality

Uses reduced audio parameters to minimize file size and processing overhead. Designed for cases where speech intelligibility is sufficient and audio fidelity is not critical, such as quick voice notes, background recording, or diagnostic capture.

audioRecorder.enableFileOutput({
format: FileFormat.M4A,
preset: FilePreset.Low,
});

Preset customization

In addition to the predefined presets, you may supply a custom FilePresetType to fine-tune how audio data is written and encoded. This allows you to optimize for specific use cases such as speech-only recording, reduced storage footprint, or faster encoding.

export interface FilePresetType {
bitRate: number;
sampleRate: number;
bitDepth: BitDepth;
iosQuality: IOSAudioQuality;
flacCompressionLevel: FlacCompressionLevel;
}
Property
Description
bitRate

Defines the target bitrate for lossy encoders (for example AAC or M4A). Higher values generally improve perceptual quality at the cost of larger file sizes. This value may be ignored when using lossless formats.

Use caseBitrate (bps)Notes
Very low quality / telemetry32000Bare minimum for speech intelligibility
Low quality voice notes48000Optimized for small files and fast encoding
Standard speech / podcasts6400096000Good balance of clarity and size
Medium quality general audio128000Common default for consumer audio
High quality music / voice160000192000Near-transparent for most listeners
Very high quality256000320000Large files, minimal perceptual loss
sampleRate

Specifies the sampling frequency used during recording. Higher sample rates capture a wider frequency range but increase processing and storage requirements.

bitDepth

Controls the PCM bit depth of the recorded audio. Higher bit depths increase dynamic range and precision, primarily affecting uncompressed or lossless output formats.

iosQuality

Maps the preset to the closest matching quality level provided by iOS native audio APIs, ensuring consistent behavior across Apple devices.

enum IOSAudioQuality {
Min,
Low,
Medium,
High,
Max,
}
flacCompressionLevel

Determines the compression level used when encoding FLAC files. Higher levels reduce file size at the cost of increased CPU usage, without affecting audio quality.

enum FlacCompressionLevel {
L0,
L1,
L2,
L3,
L4,
L5,
L6,
L7,
L8,
}