Back to Components

Circle Audio Record

Audio Recorder
23 days ago

About

Circle Voice Recorder

A reusable voice recording UI built on top of expo-audio to be used in your projects easily.

SimpleVoiceRecorder

SimpleVoiceRecorder is a tap-to-record screen UI for a demo showcasing the voice recording functionality.

  • Big orange circular button
  • Idle state: microphone icon
  • Recording state: 5 metering “bars” that animate from the center up/down (based on mic input)
  • Tap to start / tap to stop

Dependencies

  • expo-audio
  • expo-haptics (tap feedback)
  • react-native-reanimated (smooth bar animation)
  • @expo/vector-icons (mic icon)

Props

ts
interface SimpleVoiceRecorderProps { onRecordingComplete?: (uri: string | null) => void; title?: string; tip?: string; }
  • onRecordingComplete: Called after the user stops recording. Receives the recorded file uri.
  • title: Optional title text shown at the top.
  • tip: Optional subtitle/tip text.

Usage

tsx
import React from 'react'; import { View, StyleSheet } from 'react-native'; import { SimpleVoiceRecorder } from '../components/voice-recording'; export default function Screen() { return ( <View style={styles.container}> <SimpleVoiceRecorder title="Braindump tasks with your voice" tip="Tip: You can mention the time for your task or if it's a routine ;)" onRecordingComplete={(uri) => { console.log('Recording URI:', uri); }} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff' }, });

Playback (debug)

To quickly play back the returned uri, you can use expo-audio’s player hooks:

tsx
import { useAudioPlayer, useAudioPlayerStatus } from 'expo-audio'; function DebugPlayer({ uri }: { uri: string }) { const player = useAudioPlayer(uri); const status = useAudioPlayerStatus(player); return ( <> <Button title={status.playing ? 'Pause' : 'Play'} onPress={() => (status.playing ? player.pause() : player.play())} /> <Text>{status.currentTime} / {status.duration}</Text> </> ); }

Metering + Sensitivity

Metering is enabled in useVoiceRecording() via:

  • audioRecorder.prepareToRecordAsync({ ..., isMeteringEnabled: true })

Wave animation is driven by useWaveform() which polls audioRecorder.getStatus() at the interval defined in:

  • components/voice-recording/constants.tsWAVEFORM_CONFIG

Useful knobs:

  • SILENCE_THRESHOLD: Lower (more negative) = more sensitive to quiet input. Higher = less sensitive.
  • UPDATE_INTERVAL: Lower = more frequent polling (smoother, more CPU).

Notes

  • On first use, the system will prompt for microphone permissions.

Posted by

E

eren

@eren