Component

Vue Audio Controls Component

<DomAudioControls>

Click to talk becomes a compact microphone control: stop, live waveform, mute, and input selection. Ready for voice AI, calls, and collaboration.

Live example

From one click to a live input

Voice sessionLocal preview

Start with your voice.

One click to choose your mic and check your audio.

Microphone off

Your audio stays on this device. Nothing is recorded or sent.

Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { ref } from 'vue';
import { DomAudioControls } from '@getdom/studio';

const active = ref(false);
const muted = ref(false);
/** Receives the locally owned stream; pass it to your transport at this boundary. */
function receiveStream(stream) { active.value = Boolean(stream); }
</script>

<template>
	<div data-theme="dark" class="w-full overflow-hidden rounded-3xl border border-border bg-canvas text-canvas-fg">
		<div class="flex items-center justify-between gap-3 border-b border-border px-5 py-4">
			<span class="text-xs font-medium tracking-wide">Voice session</span>
			<span class="flex items-center gap-2 text-xs text-muted-fg"><span class="size-1.5 rounded-full" :class="active && !muted ? 'bg-success' : 'bg-muted-fg/50'" />Local preview</span>
		</div>
		<div class="flex min-h-72 flex-col items-center justify-center gap-7 px-3 py-10 text-center sm:px-8">
			<div class="space-y-2">
				<p class="text-xl font-semibold tracking-tight">{{ active ? muted ? 'Take a moment.' : 'You have the mic.' : 'Start with your voice.' }}</p>
				<p class="text-sm text-muted-fg">{{ active ? muted ? 'Unmute whenever you’re ready.' : 'Speak and watch your input respond.' : 'One click to choose your mic and check your audio.' }}</p>
			</div>
			<DomAudioControls v-model:muted="muted" @stream="receiveStream" />
		</div>
		<p class="border-t border-border px-5 py-4 text-center text-xs text-muted-fg">Your audio stays on this device. Nothing is recorded or sent.</p>
	</div>
</template>

A small control for real conversations

Click to talk

The button asks for microphone access. Once active, it becomes a compact group with Stop, the waveform, Mute, and microphone selection. The waveform stays flat when the input is quiet.

Connect it to your app

Listen for @stream to receive a MediaStream. A new stream means the input changed; null means it stopped. Your app owns transport, AI processing, recording, and remote connection status.

Media input

Built to work together

Capture ownership. Audio input, Audio controls, and Camera input each own one capture session. Use one microphone capture component per session, then pass its stream to any extra visualisers. Stop, unmount, and page exit release owned tracks. Mute disables audio tracks but retains the microphone until Stop.

Device changes. Microphones switch only after the replacement opens successfully; failure keeps the previous stream. Cameras release the previous device first so phones can change cameras. Replace the input in your transport whenever @stream fires. Device removal or revoked access produces an error with an explicit retry.

Browser access. Open on HTTPS or localhost. Capture starts after a user action; device names may stay hidden until permission is granted. Embedded pages also need microphone/camera permission in the iframe and the parent’s Permissions Policy. Browser media permissions.

Programmatic control. Capture components expose start(): Promise<MediaStream | null>, stop(), stream, and state through a template ref. Call start() from a user gesture. Constraints apply on the next start or device switch. These components do not establish an AI or meeting connection.

Reference

Props

Control props

NameTypeTSDefaultDescription
labelstringstring'Click to talk'Button label before microphone capture starts.
deviceIdstringstring''Input device ID, or empty for system default. Supports v-model:deviceId.
mutedbooleanbooleanfalseMute the capture track while keeping its device open. Supports v-model:muted.
constraintsobjectRecord<string, unknown>Optional audio MediaTrackConstraints applied at start/selection. deviceId is controlled separately.

Auto-generated from Audio controls.props and inline _edit hints.

Events

NamePayloadDescription
@stream(stream
stream: MediaStream | null;
: MediaStream | null)
Initial/replacement microphone stream, or null on stop. This component releases its owned tracks.
@update:deviceId(deviceId
deviceId: string;
: string)
Committed input selection, with v-model:deviceId support.
@update:muted(muted
muted: boolean;
: boolean)
Microphone mute state, with v-model:muted support.
@state(state
state: 'idle' | 'requesting' | 'active' | 'error';
: 'idle' | 'requesting' | 'active' | 'error')
Local capture lifecycle, independent of your remote connection.
@error({ name, message })Permission, missing device, or capture failure.

Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.

Keyboard

  • TabMove between stop, mute, and microphone settings.
  • Enter / SpaceActivate the focused control.
  • EscapeDismiss microphone settings and return to the trigger.