useDevices is the single hook for everything about a user’s media devices: the lists of cameras, microphones, and speakers, which one is selected, the permission state, and helpers to switch devices. Toggling tracks on and off is a separate, imperative action on the call object.
Read available devices
useDevices returns cameras, microphones, and speakers arrays, plus the currently selected device for each:
device (the browser MediaDeviceInfo), a selected boolean, and a state of 'granted' or 'in-use'.
Build a device picker
UsesetCamera, setMicrophone, and setSpeaker (each takes a deviceId) to switch devices:
refreshDevices() to re-enumerate.
Handle permission and device state
camState and micState describe access at a glance. They start as 'idle' before any access is requested, move to 'pending' while the browser prompt is open, then settle on 'granted' or 'blocked':
hasCamError and hasMicError are true whenever the corresponding state is an error state ('blocked', 'in-use', 'not-found', and similar), so you can branch on one value instead of enumerating them.
States stay
'idle' for rooms configured with start_audio_off: true and start_video_off: true, because no device access has been requested yet. Access is requested when you turn a track on.Toggle camera and mic
Turning tracks on and off is not part ofuseDevices. It is an imperative action, so use useDaily and call setLocalVideo() / setLocalAudio(). Read the current on/off state reactively from the local participant’s track:
video.isOff to setLocalVideo reads as “set video to whatever off currently is not,” i.e. toggle it.
Apply background blur and other input processors
useInputSettings wraps the input-processing pipeline. Use it to enable background blur, virtual backgrounds, or noise cancellation:
Next steps
Permissions
Control what each participant is allowed to send.
Rendering media
Show the camera you just selected.