Voice input
A microphone button that records with getUserMedia and MediaRecorder, shows a live level meter, and hands you the audio as a Blob. Handles the permission prompt and a refusal.
Press to record
Usage
use hydroxy_leptos::voice_input::VoiceInput;
use leptos::prelude::*;
pub fn demo() -> AnyView {
let (clip, set_clip) = signal(None::<String>);
view! {
<div style="display: grid; gap: var(--space-6); max-width: 480px;">
<VoiceInput
max_seconds=60
on_recorded=move |blob: web_sys::Blob| {
// Play it back through an object URL. Upload the Blob instead in a real app.
if let Ok(url) = web_sys::Url::create_object_url_with_blob(&blob) {
set_clip.set(Some(url));
}
}
/>
{move || {
clip.get()
.map(|url| {
view! { <audio controls=true src=url style="width: 100%;"></audio> }
})
}}
</div>
}
.into_any()
}use dioxus::prelude::*;
use hydroxy_dioxus::voice_input::{RecordedAudio, VoiceInput};
#[component]
pub fn VoiceInputDemo() -> Element {
let mut clip = use_signal(|| None::<RecordedAudio>);
rsx! {
div { style: "display: grid; gap: var(--space-6); max-width: 480px;",
VoiceInput { max_seconds: 60, on_recorded: move |audio| clip.set(Some(audio)) }
if let Some(audio) = clip() {
// The audio arrives as an object URL. Fetch it for the bytes in a real app.
audio { controls: true, src: "{audio.url}", style: "width: 100%;" }
p { style: "margin: 0; font: var(--text-sm); color: var(--text-2);",
"{audio.size} bytes of {audio.mime_type}, {audio.duration_ms} ms"
}
}
}
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
VoiceInput | root | Wraps everything. data-state is idle, requesting, recording, denied or failed |
(inside) | button | Round toggle with aria-pressed and a label that follows the state |
(inside) | meter | Five bars driven by an AnalyserNode. Decorative |
(inside) | bar | One meter bar, scaled by the input level |
(inside) | status | role=status text: prompt, elapsed time, or why recording is blocked |
Keyboard
| Key | Does |
|---|---|
Enter / Space | Start recording, or stop while recording |
Props
| Prop | Type | Notes |
|---|---|---|
max_seconds | Option<u32> | Stop on its own after this long |
disabled | bool | Block recording |
on_recorded | Callback<Blob> | The audio in the browser's native format (webm or mp4). Dioxus passes a RecordedAudio with an object URL, size and type instead |
on_phase_change | Callback<VoiceInputPhase> | Called when the recorder moves between idle, requesting, recording, denied and failed |