Skip to main content
Version: Next

Managing devices

The Fishjam SDK provides functions for dynamically controlling media device streams. This includes selecting desired cameras and microphones, turning them on and off, as well as muting and unmuting microphones.

Selecting Camera and Microphone

To select the desired camera or microphone, use the selectCamera and selectMicrophone functions.
Lists of the available devices are available via the cameraDevices and microphoneDevices properties.

To select the desired camera or microphone, use selectCamera() and selectMicrophone() functions.
Lists of the available devices are available via the cameraDevices and microphoneDevices properties.

Usage Example

import React from "react"; import { useCamera } from "@fishjam-cloud/react-client"; export function CameraControl() { const { cameraDevices, selectCamera } = useCamera(); return ( <ul> {cameraDevices.map(({ deviceId, label }) => ( <li key={deviceId}> <button onClick={() => selectCamera(deviceId)}>{label}</button> </li> ))} </ul> ); }
Testing on iOS Simulator

The iOS Simulator has no camera. SimCam solves this by injecting a virtual feed (your Mac's camera or a video file), so you can test without a physical device. See Camera on iOS Simulator.

Turning Camera On and Off

Use the toggleCamera() method to control the physical operational state of the camera.

  • Turning the camera off: This action stops the camera device, disables the media stream, and pauses streaming. The webcam indicator light will shut down.
  • Turning the camera on: This action starts the camera and resumes streaming, allowing other participants to see video after a brief initialization period.

Usage Example

import React from "react"; import { useCamera } from "@fishjam-cloud/react-client"; export function CameraControl() { const { toggleCamera } = useCamera(); return <button onClick={() => toggleCamera()}>Toggle Camera Device</button>; }

Turning Microphone On and Off

Use the toggleMicrophone() method to toggle the microphone's physical operational state. The function interacts with a physical device, so it might take a noticeable amount of time.

Turning the microphone off: This action turns the microphone off, disables the media stream, and pauses any audio transmission.

Turning the microphone on: This action turns the microphone on and resumes audio streaming.

Muting and Unmuting Microphone (Web only)

note

This feature is only available on Web. On mobile, use toggleMicrophone or stopMicrophone to disable audio transmission.

Use toggleMicrophoneMute() to manage the audio stream's operational status without affecting the microphone's hardware state.

Muting and unmuting is faster than turning the microphone on/off, but a muted device still uses resources. This is useful, as it is common to mute and unmute during a meeting. Unmuting needs to be quick to capture the first word of a sentence.

  • Muting the microphone: This action disables the media stream and stops audio transmission while keeping the microphone active.
  • Unmuting the microphone: This action enables the media stream, allowing immediate transmission of sounds.

Usage Example

import React from "react"; import { useMicrophone } from "@fishjam-cloud/react-client"; export function MicrophoneControl() { const { toggleMicrophone, toggleMicrophoneMute } = useMicrophone(); return ( <div> <button onClick={() => toggleMicrophone()}> Toggle Microphone Device </button> <button onClick={() => toggleMicrophoneMute()}> Toggle Microphone Mute </button> </div> ); }

Audio processing: noise cancellation and auto gain control

When capturing a microphone, the browser (Web) or OS (Mobile) applies audio processing — echo cancellation, noise suppression (noise cancellation) and auto gain control — to make speech clearer. These are enabled by default and are the right choice for most voice and meeting use cases.

Turn them off only when you need the raw, unprocessed signal — for example capturing music or an instrument, or running your own audio processing — since these filters can distort non-speech audio.

On Web, audio processing follows the browser's defaults (noise suppression, auto gain control and echo cancellation are on by default). To set them explicitly, pass constraints to FishjamProvider. The audio field accepts standard MediaTrackConstraints.

import React from "react"; import { FishjamProvider } from "@fishjam-cloud/react-client"; export function App({ fishjamId }: { fishjamId: string }) { return ( <FishjamProvider fishjamId={fishjamId} constraints={{ audio: { echoCancellation: true, noiseSuppression: true, // noise cancellation autoGainControl: true, }, }} > {/* your app */} </FishjamProvider> ); }

To capture raw audio (for example, music), set echoCancellation, noiseSuppression, and autoGainControl to false instead.

note

These constraints are applied when FishjamProvider creates the microphone track. selectMicrophone and startMicrophone reuse the same constraints — they don't accept per-call overrides.

Managing Permissions (Mobile only)

The SDK provides built-in hooks for querying and requesting device permissions: useCameraPermissions and useMicrophonePermissions from @fishjam-cloud/react-native-client.

Both hooks return a [query, request] tuple:

  • query() — checks the current permission status without prompting the user
  • request() — triggers the native permission dialog and returns the resulting status

The returned PermissionStatus is one of: 'granted', 'denied', or 'prompt'.

info

Requesting permissions manually is optional — initializeDevices() will automatically prompt for any permissions that haven't been granted yet. However, you must always call initializeDevices() to set up camera and microphone devices.

Usage Example

import React, { useEffect } from "react"; import { useCameraPermissions, useMicrophonePermissions, useInitializeDevices, } from "@fishjam-cloud/react-native-client"; function RoomScreen() { const [queryCamera, requestCamera] = useCameraPermissions(); const [queryMicrophone, requestMicrophone] = useMicrophonePermissions(); const { initializeDevices } = useInitializeDevices(); useEffect(() => { const setup = async () => { let cam = await queryCamera(); let mic = await queryMicrophone(); if (cam !== "granted") cam = await requestCamera(); if (mic !== "granted") mic = await requestMicrophone(); if (cam === "granted" && mic === "granted") { await initializeDevices(); } }; setup(); }, [ queryCamera, requestCamera, queryMicrophone, requestMicrophone, initializeDevices, ]); }