# Camera and microphone Enable media, show previews and switch input devices. ## Imports ```tsx import { MediaLoader, useLocalMedia, useLocalParticipant, useMediaTrack, useTracks, useRoom } from '@relayrtc/react' ``` ## Enable capture Get the local participant from [useLocalParticipant](/reference/sdk/client/react/hooks/useLocalParticipant). Wait until the room is connected. ```tsx const local = useLocalParticipant() const { room } = useRoom() await local?.camera.enable({ width: { ideal: 1280 }, height: { ideal: 720 }, frameRate: { ideal: 30 }, }) await local?.microphone.enable({ echoCancellation: true, noiseSuppression: true, autoGainControl: true, }) ``` Use these calls in an event handler and catch rejected promises. Browser constraints are requests; device support determines the actual capture. ## Show your preview ```tsx const { camera } = useLocalMedia() const preview = useMediaTrack(camera?.track, { paused: camera?.muted }) return (
Camera is off
``` `RemoteCamera` is your component using [useMediaTrack](/reference/sdk/client/react/hooks/useMediaTrack). > **Mute and camera-off behave differently** > `camera.mute()` pauses the local sender. Remote publication pause/resume is not implemented by the current server, so mute alone can leave a frozen remote frame. Use disable/enable for camera-off controls. ## Microphone mute ```ts local?.microphone.mute() local?.microphone.unmute() ``` Mute keeps the capture device open and stops sending its media. Use `microphone.disable()` to release capture. ## Device selection ```ts if (room) { const devices = await room.devices.enumerate() const firstCamera = devices.cameras[0] if (firstCamera) await local?.camera.switchDevice(firstCamera.deviceId) } ``` Device labels can be empty before permission is granted. See the complete [camera settings](/reference/sdk/client/react/media/camera), [microphone settings](/reference/sdk/client/react/media/microphone) and [device API](/reference/sdk/client/react/media/devices).