Component

Vue Camera Input Component

<DomCameraInput>

Select a webcam and check a private local preview before joining a call. Emits a video-only MediaStream and releases the camera when stopped.

Live example

Your pre-meeting check

Before you join

Check your camera and microphone. Turn on either independently.

Camera

Off

Your camera preview

Camera is off

Microphone

Off

Microphone is off

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

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

<template>
	<div class="w-full space-y-5">
		<div class="space-y-1">
			<h3 class="text-xl font-semibold tracking-tight text-canvas-fg">Before you join</h3>
			<p class="text-sm leading-relaxed text-muted-fg">Check your camera and microphone. Turn on either independently.</p>
		</div>
		<div class="grid items-start gap-4 xl:grid-cols-2">
			<DomCameraInput :constraints="{ width: { ideal: 1280 }, facingMode: 'user' }" />
			<DomAudioInput />
		</div>
		<p class="text-xs text-muted-fg">Your preview stays on this device. Nothing is recorded or sent.</p>
	</div>
</template>

A preview that stays local

The camera requests video only. A mirrored, muted, inline preview works beside an independently controlled microphone. Set :mirror="false" for a rear-facing camera. Mirroring changes the preview only; the emitted stream keeps the camera’s original image. If autoplay is blocked, a Show camera preview button lets the viewer start playback.

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
deviceIdstringstring''Camera device ID, or empty for system default. Supports v-model:deviceId.
constraintsobjectRecord<string, unknown>Optional video MediaTrackConstraints such as facingMode or ideal width. Applied at start or selection.
mirrorbooleanbooleantrueMirror only the local preview for a front-facing camera. The emitted stream is unchanged.
labelstringstring'Camera'Setup heading and camera picker label.

Auto-generated from Camera input.props and inline _edit hints.

Events

NamePayloadDescription
@stream(stream
stream: MediaStream | null;
: MediaStream | null)
Video-only local stream or null when released. Cameras are released before switching for mobile compatibility.
@update:deviceId(deviceId
deviceId: string;
: string)
Committed camera selection. Supports v-model:deviceId.
@state(state
state: 'idle' | 'requesting' | 'active' | 'error';
: 'idle' | 'requesting' | 'active' | 'error')
Local camera capture state.
@error({ name, message })Camera access or device failure.

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