Browse API 1 documentation
GroveAPI 1preview

grove.composer.audio

Record a bounded voice clip through Mango's native microphone bridge.

Mango 3.1+View Markdown

Native voice capture for composer-only Sprigs with the microphone.record grant. Not available in settings, Roots, channel/split panes, web dashboards, or subframes. Browser getUserMedia remains denied for every Grove document. Feature-detect grove.composer.audio; older Mango versions do not support it.

js
const audio = grove.composer.audio
const unsubscribe = audio.onUpdate(update => {
  // {state: 'recording', duration: seconds, amplitude: 0...1}
  // {state: 'stopped'}: duration limit or interruption; call stop to collect.
  // {state: 'cancelled'}: capture was discarded (e.g. app backgrounded).
})
await audio.start()
const clip = await audio.stop()
// clip: {data: Uint8Array, duration: seconds, mimeType: 'audio/mp4', filename: 'voice-message.m4a'}
const seconds = Math.floor(clip.duration)
const duration = `${String(Math.floor(seconds / 60)).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}`
grove.composer.upload(clip.data, {filename: clip.filename, caption: `[Voice] (${duration}):`}) // also requires uploads.use
unsubscribe()
  • Call start() only from an explicit Record button. Mango must be active and the composer visible. Apple prompts for microphone consent when needed.
  • start, stop, and cancel return Promises; handle their rejections.
  • Only one recording across Mango’s windows is allowed. Concurrent operations are rejected rather than queued. cancel() discards an active recording.
  • Capture is mono AAC, 24 kHz / 64 kbit/s, at most 180 seconds and 8 MiB.
  • Closing, WebKit failure/reload, grant revocation, or app backgrounding cancels capture. Recordings are temporary and are not restored after a restart.
  • onUpdate returns an unsubscribe function. Treat level events as lossy UI samples, not an audio stream; do not use their count to measure elapsed time.
  • No filesystem paths or provider credentials enter the Sprig. Upload is a separate user action through grove.composer.upload; the normal draft/send confirmation flow is unchanged. The chosen host must support audio uploads.
  • No background recording, camera access, or arbitrary audio-device selection.

See Examples/grove-voice-composer for a dependency-free 420 × 144pt example.

The example sends ordinary IRC text, such as [Voice] (00:12): https://files.example/voice-message.m4a. This readable fallback is a Mango presentation choice, not an IRCv3 standard. It uses no Markdown link or proprietary message tag. Mango detects the URL and obtains duration/waveform from the audio itself, not from the caption; other clients can display the text and open the URL. Bare audio URLs continue to preview normally.