
Audio recording engine with configurable sample rate, channels, encoding and output formats, reactive state (amplitude/duration), waveform-ready visual components, optional UI and lifecycle-safe controls.
A Kotlin Multiplatform audio recording library for Android and iOS.
StateFlow<RecorderState> with amplitude, duration, statusRecorderView + standalone WaveformView, or bring your ownKRecorder/
├── krecorder-core/ ← Recording engine. No UI dependency.
├── krecorder-ui/ ← Optional Compose Multiplatform UI.
└── sample/ ← Demo app showcasing all features.
| Module | Description |
|---|---|
krecorder-core |
Recording interface + platform implementations. Android: MediaRecorder. iOS: AVAudioRecorder. |
krecorder-ui |
Optional Compose UI: RecorderView (full recorder) + WaveformView (standalone waveform bars). |
sample |
Runnable demo app with config pickers and live recording. |
The sample module demonstrates all library features:
# Android
./gradlew :sample:installDebug
# iOS (via Xcode)
open iosApp/iosApp.xcodeprojval recorder = KRecorder.create(
config = RecorderConfig(
sampleRate = SampleRate.RATE_44100,
channels = Channels.MONO,
encoding = AudioEncoding.AAC,
format = OutputFormat.MP4,
)
)
// Observe state reactively
recorder.state.collect { state ->
println("${state.formattedDuration} | Amplitude: ${state.amplitude}")
}
recorder.start()
recorder.pause()
recorder.resume()
recorder.stop() // file at state.value.outputPath
recorder.release() // free resourcesval recorder = remember { KRecorder.create() }
RecorderView(
recorder = recorder,
onRecordingSaved = { filePath -> },
)WaveformView(
amplitudes = amplitudes, // List<Float> of 0.0–1.0 values
barColor = Color.White,
barWidth = 3.dp,
barSpacing = 2.dp,
height = 200.dp,
)| Option | Values | Default |
|---|---|---|
| Sample Rate |
8000, 16000, 22050, 44100, 48000 Hz |
44100 |
| Channels |
MONO, STEREO
|
MONO |
| Encoding |
AAC, PCM_16BIT, AMR_NB, AMR_WB, OPUS
|
AAC |
| Format |
MP4, THREE_GPP, OGG, WAV
|
MP4 |
| Output Path | Custom path or null (auto temp file) |
null |
StateFlow<RecorderState> fields:
| Field | Type | Description |
|---|---|---|
status |
RecorderStatus |
IDLE / RECORDING / PAUSED / STOPPED / ERROR
|
durationMs |
Long |
Elapsed time in milliseconds |
amplitude |
Float |
Audio level 0.0–1.0, updated ~20fps |
outputPath |
String? |
Output file path |
formattedDuration |
String |
MM:SS.T format |
<uses-permission android:name="android.permission.RECORD_AUDIO" /><key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access to record audio.</string>┌─────────────────────────────────────────┐
│ Your App │
│ ┌────────────┐ ┌───────────────────┐ │
│ │krecorder-ui│ │ Your custom UI │ │
│ │RecorderView│ │ WaveformView │ │
│ └─────┬──────┘ └────────┬──────────┘ │
│ └────────┬─────────┘ │
│ ┌────────┴─────────┐ │
│ │ krecorder-core │ │
│ │ KRecorder + Flow │ │
│ ├────────┬─────────┤ │
│ │Android │ iOS │ │
│ │MediaRec│AVAudioRec │
│ └────────┴─────────┘ │
└─────────────────────────────────────────┘
Apache 2.0
A Kotlin Multiplatform audio recording library for Android and iOS.
StateFlow<RecorderState> with amplitude, duration, statusRecorderView + standalone WaveformView, or bring your ownKRecorder/
├── krecorder-core/ ← Recording engine. No UI dependency.
├── krecorder-ui/ ← Optional Compose Multiplatform UI.
└── sample/ ← Demo app showcasing all features.
| Module | Description |
|---|---|
krecorder-core |
Recording interface + platform implementations. Android: MediaRecorder. iOS: AVAudioRecorder. |
krecorder-ui |
Optional Compose UI: RecorderView (full recorder) + WaveformView (standalone waveform bars). |
sample |
Runnable demo app with config pickers and live recording. |
The sample module demonstrates all library features:
# Android
./gradlew :sample:installDebug
# iOS (via Xcode)
open iosApp/iosApp.xcodeprojval recorder = KRecorder.create(
config = RecorderConfig(
sampleRate = SampleRate.RATE_44100,
channels = Channels.MONO,
encoding = AudioEncoding.AAC,
format = OutputFormat.MP4,
)
)
// Observe state reactively
recorder.state.collect { state ->
println("${state.formattedDuration} | Amplitude: ${state.amplitude}")
}
recorder.start()
recorder.pause()
recorder.resume()
recorder.stop() // file at state.value.outputPath
recorder.release() // free resourcesval recorder = remember { KRecorder.create() }
RecorderView(
recorder = recorder,
onRecordingSaved = { filePath -> },
)WaveformView(
amplitudes = amplitudes, // List<Float> of 0.0–1.0 values
barColor = Color.White,
barWidth = 3.dp,
barSpacing = 2.dp,
height = 200.dp,
)| Option | Values | Default |
|---|---|---|
| Sample Rate |
8000, 16000, 22050, 44100, 48000 Hz |
44100 |
| Channels |
MONO, STEREO
|
MONO |
| Encoding |
AAC, PCM_16BIT, AMR_NB, AMR_WB, OPUS
|
AAC |
| Format |
MP4, THREE_GPP, OGG, WAV
|
MP4 |
| Output Path | Custom path or null (auto temp file) |
null |
StateFlow<RecorderState> fields:
| Field | Type | Description |
|---|---|---|
status |
RecorderStatus |
IDLE / RECORDING / PAUSED / STOPPED / ERROR
|
durationMs |
Long |
Elapsed time in milliseconds |
amplitude |
Float |
Audio level 0.0–1.0, updated ~20fps |
outputPath |
String? |
Output file path |
formattedDuration |
String |
MM:SS.T format |
<uses-permission android:name="android.permission.RECORD_AUDIO" /><key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access to record audio.</string>┌─────────────────────────────────────────┐
│ Your App │
│ ┌────────────┐ ┌───────────────────┐ │
│ │krecorder-ui│ │ Your custom UI │ │
│ │RecorderView│ │ WaveformView │ │
│ └─────┬──────┘ └────────┬──────────┘ │
│ └────────┬─────────┘ │
│ ┌────────┴─────────┐ │
│ │ krecorder-core │ │
│ │ KRecorder + Flow │ │
│ ├────────┬─────────┤ │
│ │Android │ iOS │ │
│ │MediaRec│AVAudioRec │
│ └────────┴─────────┘ │
└─────────────────────────────────────────┘
Apache 2.0