Helper functions for working with audio in React Native Sherpa-ONNX. These utilities handle TTS audio output, file conversion, Android Storage Access Framework (SAF), and sharing.
Import Paths:
- TTS audio helpers:
import { saveAudioToFile, shareAudioFile } from 'react-native-sherpa-onnx/tts'
- Audio conversion:
import { convertAudioToFormat } from 'react-native-sherpa-onnx/audio'
File Operations
saveAudioToFile()
Save generated TTS audio to a WAV file.
function saveAudioToFile(
audio: GeneratedAudio,
filePath: string
): Promise<string>
Generated audio object from generateSpeech() or generateSpeechWithTimestamps()Properties:
samples: Float32Array of audio samples
sampleRate: Sample rate in Hz (e.g., 22050, 24000)
Absolute path where the WAV file should be saved
The absolute path of the saved file
Example:
import { createTTS, saveAudioToFile } from 'react-native-sherpa-onnx';
import { DocumentDirectoryPath } from '@dr.pogodin/react-native-fs';
const tts = await createTTS({
modelPath: { type: 'asset', path: 'models/vits-piper-en' },
modelType: 'vits',
});
const audio = await tts.generateSpeech('Hello, world!');
const outputPath = `${DocumentDirectoryPath}/output.wav`;
const savedPath = await saveAudioToFile(audio, outputPath);
console.log('Audio saved to:', savedPath);
saveAudioToContentUri()
Save generated TTS audio to a WAV file via Android Storage Access Framework (SAF).
function saveAudioToContentUri(
audio: GeneratedAudio,
directoryUri: string,
filename: string
): Promise<string>
Generated audio object from generateSpeech()
SAF directory content URI (obtained from react-native-document-picker or react-native-fs)
Filename for the WAV file (e.g., "speech.wav")
Content URI of the saved file
This function is Android-only. Use saveAudioToFile() on iOS or when working with app-internal storage.
Example:
import { createTTS, saveAudioToContentUri } from 'react-native-sherpa-onnx';
import DocumentPicker from 'react-native-document-picker';
// Let user pick a directory
const result = await DocumentPicker.pickDirectory();
if (!result) return;
const tts = await createTTS({
modelPath: { type: 'asset', path: 'models/vits-piper-en' },
modelType: 'vits',
});
const audio = await tts.generateSpeech('Hello, Android!');
const uri = await saveAudioToContentUri(
audio,
result.uri,
'output.wav'
);
console.log('Audio saved to content URI:', uri);
copyContentUriToCache()
Copy a file from an Android SAF content URI to app cache for local playback.
function copyContentUriToCache(
fileUri: string,
filename: string
): Promise<string>
SAF content URI of the source file
Filename for the cached copy
Absolute path of the cached file
This function is Android-only. Use this when you need to play audio from a content URI with media players that don’t support content URIs.
Example:
import { saveAudioToContentUri, copyContentUriToCache } from 'react-native-sherpa-onnx';
import Sound from 'react-native-sound';
const tts = await createTTS({ modelPath: { type: 'asset', path: 'models/vits-piper-en' } });
const audio = await tts.generateSpeech('Test audio');
// Save to user-selected directory
const contentUri = await saveAudioToContentUri(audio, directoryUri, 'test.wav');
// Copy to cache for playback
const cachePath = await copyContentUriToCache(contentUri, 'test.wav');
// Play the cached file
const sound = new Sound(cachePath, '', (error) => {
if (!error) sound.play();
});
saveTextToContentUri()
Save a text file via Android Storage Access Framework (SAF).
function saveTextToContentUri(
text: string,
directoryUri: string,
filename: string,
mimeType?: string
): Promise<string>
SAF directory content URI
Filename for the text file (e.g., "transcript.txt")
mimeType
string
default:"'text/plain'"
MIME type of the text file
Content URI of the saved file
This function is Android-only. Useful for saving transcripts or subtitles alongside audio files.
Example:
import { saveTextToContentUri } from 'react-native-sherpa-onnx/tts';
import DocumentPicker from 'react-native-document-picker';
// Let user pick a directory
const result = await DocumentPicker.pickDirectory();
if (!result) return;
const transcript = "This is the transcript of the audio.";
const uri = await saveTextToContentUri(
transcript,
result.uri,
'transcript.txt',
'text/plain'
);
console.log('Transcript saved to:', uri);
Sharing
shareAudioFile()
Share a TTS audio file using the system share sheet.
function shareAudioFile(
fileUri: string,
mimeType?: string
): Promise<void>
File path or content URI to share
- iOS: Absolute file path
- Android: File path or content URI (e.g., from
saveAudioToContentUri())
mimeType
string
default:"'audio/wav'"
MIME type of the audio file
Resolves when the share sheet is dismissed
Example:
import { createTTS, saveAudioToFile, shareAudioFile } from 'react-native-sherpa-onnx';
import { DocumentDirectoryPath } from '@dr.pogodin/react-native-fs';
const tts = await createTTS({
modelPath: { type: 'asset', path: 'models/vits-piper-en' },
modelType: 'vits',
});
const audio = await tts.generateSpeech('Share this audio');
const filePath = `${DocumentDirectoryPath}/share-audio.wav`;
await saveAudioToFile(audio, filePath);
// Share via system share sheet
await shareAudioFile(filePath);
Android SAF Example:
import { saveAudioToContentUri, shareAudioFile } from 'react-native-sherpa-onnx';
const audio = await tts.generateSpeech('Share via content URI');
const contentUri = await saveAudioToContentUri(audio, directoryUri, 'share.wav');
// Share content URI (Android only)
await shareAudioFile(contentUri, 'audio/wav');
Audio Conversion
Convert audio files between different formats (requires FFmpeg on Android).
function convertAudioToFormat(
inputPath: string,
outputPath: string,
format: string,
outputSampleRateHz?: number
): Promise<void>
Absolute path to the input audio file
Absolute path for the output file
Output format: "mp3", "flac", "wav", etc.
Sample rate for output (MP3: 32000, 44100, or 48000; WAV: always 16000 mono for sherpa-onnx)
This function requires FFmpeg prebuilts on Android. See Disable FFmpeg if you need to reduce app size.
Example:
import { convertAudioToFormat } from 'react-native-sherpa-onnx/audio';
import { DocumentDirectoryPath } from '@dr.pogodin/react-native-fs';
const inputPath = `${DocumentDirectoryPath}/recording.m4a`;
const outputPath = `${DocumentDirectoryPath}/recording.mp3`;
await convertAudioToFormat(inputPath, outputPath, 'mp3', 44100);
console.log('Converted to MP3');
convertAudioToWav16k()
Convert any audio file to WAV format (16 kHz, mono, 16-bit PCM) suitable for STT.
function convertAudioToWav16k(
inputPath: string,
outputPath: string
): Promise<void>
Absolute path to the input audio file (any format supported by FFmpeg)
Absolute path for the output WAV file
This function requires FFmpeg prebuilts on Android.
Use this function to prepare audio files for speech-to-text. Sherpa-ONNX expects 16 kHz mono audio for optimal STT performance.
Example:
import { convertAudioToWav16k } from 'react-native-sherpa-onnx/audio';
import { createSTT } from 'react-native-sherpa-onnx/stt';
import { DocumentDirectoryPath } from '@dr.pogodin/react-native-fs';
// Convert various audio formats to STT-compatible WAV
const inputPath = `${DocumentDirectoryPath}/recording.mp3`;
const wavPath = `${DocumentDirectoryPath}/recording.wav`;
await convertAudioToWav16k(inputPath, wavPath);
// Now transcribe
const stt = await createSTT({
modelPath: { type: 'asset', path: 'models/whisper-tiny' },
modelType: 'whisper',
});
const result = await stt.transcribeFile(wavPath);
console.log('Transcription:', result.text);
Use Cases:
- Prepare audio for STT (convert MP3, M4A, FLAC → WAV 16kHz)
- Normalize audio sample rates before transcription
- Convert recorded audio to STT-compatible format
Type Definitions
GeneratedAudio
Generated audio data structure:
type GeneratedAudio = {
samples: Float32Array; // Audio samples in floating-point format
sampleRate: number; // Sample rate in Hz (e.g., 22050, 24000)
};
GeneratedAudioWithTimestamps
Extended audio data with word/phoneme timestamps:
type GeneratedAudioWithTimestamps = {
samples: Float32Array;
sampleRate: number;
timestamps: TtsSubtitleItem[]; // Word/phoneme timing information
};
type TtsSubtitleItem = {
text: string; // Word or phoneme text
start: number; // Start time in seconds
end: number; // End time in seconds
};
iOS
- Use
saveAudioToFile() with paths from DocumentDirectoryPath or CachesDirectoryPath
saveAudioToContentUri() is not available
copyContentUriToCache() is not available
shareAudioFile() uses UIActivityViewController
Android
saveAudioToFile() works with internal storage paths
saveAudioToContentUri() enables saving to external storage via SAF (SD card, Downloads, etc.)
copyContentUriToCache() bridges content URIs to file paths
shareAudioFile() supports both file paths and content URIs via Intent.ACTION_SEND
Best Practices
-
Use appropriate storage based on use case:
- Internal storage (
saveAudioToFile): Temporary audio, app-only access
- SAF (
saveAudioToContentUri): User-selected location, persistent storage
-
Handle platform differences:
import { Platform } from 'react-native';
if (Platform.OS === 'android') {
// Use SAF for external storage
await saveAudioToContentUri(audio, directoryUri, 'audio.wav');
} else {
// Use file path on iOS
await saveAudioToFile(audio, `${DocumentDirectoryPath}/audio.wav`);
}
-
Clean up temporary files:
import { unlink } from '@dr.pogodin/react-native-fs';
const tempPath = `${CachesDirectoryPath}/temp.wav`;
await saveAudioToFile(audio, tempPath);
await shareAudioFile(tempPath);
// Clean up after sharing
await unlink(tempPath);
-
Validate file paths:
import { exists } from '@dr.pogodin/react-native-fs';
const path = await saveAudioToFile(audio, outputPath);
const fileExists = await exists(path);
if (!fileExists) {
throw new Error('Failed to save audio file');
}
-
Use descriptive filenames:
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `tts-output-${timestamp}.wav`;
await saveAudioToFile(audio, `${DocumentDirectoryPath}/${filename}`);
Error Handling
try {
const audio = await tts.generateSpeech('Hello');
const path = await saveAudioToFile(
audio,
`${DocumentDirectoryPath}/output.wav`
);
console.log('Success:', path);
} catch (error) {
if (error.message.includes('No such file or directory')) {
console.error('Invalid file path');
} else if (error.message.includes('Permission denied')) {
console.error('Storage permission required');
} else {
console.error('Failed to save audio:', error);
}
}