### Install Project Dependencies
Source: https://github.com/videosdk-live/videosdk-rtc-react-sdk-example/blob/main/README.md
Install all the necessary packages for the React SDK example application using npm.
```bash
npm install
```
--------------------------------
### Clone Video SDK React Example Repository
Source: https://github.com/videosdk-live/videosdk-rtc-react-sdk-example/blob/main/README.md
Use this command to clone the sample application repository from GitHub.
```bash
git clone https://github.com/videosdk-live/videosdk-rtc-react-sdk-example.git
```
--------------------------------
### Copy Environment File
Source: https://github.com/videosdk-live/videosdk-rtc-react-sdk-example/blob/main/README.md
Copy the example environment file to create your own configuration file. This is a necessary step before configuring your API keys and tokens.
```bash
cp .env.example .env
```
--------------------------------
### Launch the Video SDK React App
Source: https://github.com/videosdk-live/videosdk-rtc-react-sdk-example/blob/main/README.md
Start the development server to run the sample application. This command compiles the code and launches the app in your default browser.
```bash
npm run start
```
--------------------------------
### Get VideoSDK Auth Token
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Fetches an authentication token from environment variables or an external auth server. Ensure only one configuration source is provided.
```javascript
const API_BASE_URL = "https://api.videosdk.live";
const VIDEOSDK_TOKEN = process.env.REACT_APP_VIDEOSDK_TOKEN;
const API_AUTH_URL = process.env.REACT_APP_AUTH_URL;
export const getToken = async () => {
if (VIDEOSDK_TOKEN && API_AUTH_URL) {
console.error("Error: Provide only ONE PARAMETER - either Token or Auth API");
} else if (VIDEOSDK_TOKEN) {
return VIDEOSDK_TOKEN;
} else if (API_AUTH_URL) {
const res = await fetch(`${API_AUTH_URL}/get-token`, { method: "GET" });
const { token } = await res.json();
return token;
} else {
console.error("Error: ", Error("Please add a token or Auth Server URL"));
}
};
// Usage:
const token = await getToken();
// Returns: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
--------------------------------
### useMediaDevice()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Enumerate and monitor input/output devices. Provides methods to list cameras, microphones, and speakers, check browser permissions, and request them if not yet granted.
```APIDOC
## useMediaDevice()
### Description
Provides methods to list cameras, microphones, and speakers, check browser permissions, and request them if not yet granted.
### Methods
- `checkPermissions()`: Asynchronously checks the current browser permissions for audio and video.
- `requestPermission(mediaType)`: Asynchronously requests permission for a specified media type (audio or video).
- `getCameras()`: Asynchronously retrieves a list of available camera devices.
- `getMicrophones()`: Asynchronously retrieves a list of available microphone devices.
- `getPlaybackDevices()`: Asynchronously retrieves a list of available speaker (playback) devices.
### Events
- `onDeviceChanged`: A callback function that fires when an audio or video device is plugged in or unplugged.
### Usage Example
```javascript
// Check existing permissions:
const permissions = await checkPermissions();
const cameraAllowed = permissions.get(Constants.permission.VIDEO);
const micAllowed = permissions.get(Constants.permission.AUDIO);
// Request if not granted:
if (!micAllowed) {
const result = await requestPermission(Constants.permission.AUDIO);
const isAudioAllowed = result.get(Constants.permission.AUDIO);
}
// List all available cameras:
const cameras = await getCameras();
// cameras: [{ deviceId: "abc123", label: "FaceTime HD Camera", kind: "videoinput" }, ...]
// List all microphones:
const mics = await getMicrophones();
// mics: [{ deviceId: "def456", label: "Built-in Microphone", kind: "audioinput" }, ...]
// List all speakers:
const speakers = await getPlaybackDevices();
// speakers: [{ deviceId: "ghi789", label: "Built-in Output", kind: "audiooutput" }, ...]
```
```
--------------------------------
### createMeeting({ token })
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Creates a new meeting room by calling the VideoSDK REST API. It returns the `meetingId` upon successful creation or an error object if the creation fails.
```APIDOC
## createMeeting({ token })
### Description
Calls the VideoSDK REST API (`POST /v2/rooms`) to create a new meeting room and returns its `meetingId`. Handles API errors gracefully.
### Parameters
#### Request Body Parameters
- **token** (string) - Required - The authentication token for the VideoSDK API.
### Request Example
```javascript
const token = await getToken();
const { meetingId, err } = await createMeeting({ token });
if (meetingId) {
console.log("Created meeting:", meetingId); // e.g. "abc-1234-xyz"
} else {
console.error("Failed to create meeting:", err);
}
```
### Response
#### Success Response
- **meetingId** (string) - The unique identifier for the newly created meeting room.
- **err** (null) - Indicates no error occurred.
#### Error Response
- **meetingId** (null) - Indicates no meeting ID was generated.
- **err** (object) - An object containing error details from the API.
### Equivalent curl
```bash
curl -X POST https://api.videosdk.live/v2/rooms \
-H "Authorization: YOUR_TOKEN" \
-H "Content-Type: application/json"
```
### Source Code (src/api.js)
```javascript
const API_BASE_URL = "https://api.videosdk.live";
export const createMeeting = async ({ token }) => {
const url = `${API_BASE_URL}/v2/rooms`;
const options = {
method: "POST",
headers: { Authorization: token, "Content-Type": "application/json" },
};
const response = await fetch(url, options);
const data = await response.json();
if (data.roomId) {
return { meetingId: data.roomId, err: null };
} else {
return { meetingId: null, err: data.error };
}
};
```
```
--------------------------------
### Configure .env File with Video SDK Token
Source: https://github.com/videosdk-live/videosdk-rtc-react-sdk-example/blob/main/README.md
Update the .env file with your temporary Video SDK token. This token is required for authentication and is generated from your Video SDK account.
```env
REACT_APP_VIDEOSDK_TOKEN="YOUR_TEMPORARY_TOKEN"
```
--------------------------------
### Initialize Meeting with MeetingProvider
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Use MeetingProvider as the root component to wrap your meeting UI. Configure meeting settings like ID, participant name, and media states. It provides meeting context to all child hooks.
```jsx
import { MeetingProvider } from "@videosdk.live/react-sdk";
import { MeetingContainer } from "./meeting/MeetingContainer";
function App() {
const [token, setToken] = useState("");
const [meetingId, setMeetingId] = useState("");
const [participantName, setParticipantName] = useState("");
const [micOn, setMicOn] = useState(false);
const [webcamOn, setWebcamOn] = useState(false);
const [customAudioStream, setCustomAudioStream] = useState(null);
const [customVideoStream, setCustomVideoStream] = useState(null);
return (
{
setToken(""); setMeetingId(""); setWebcamOn(false); setMicOn(false);
}}
setIsMeetingLeft={setIsMeetingLeft}
/>
);
}
```
--------------------------------
### Manage Media Devices with useMediaDevice
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Use this hook to enumerate and monitor input/output devices like cameras, microphones, and speakers. It also handles browser permission checks and requests.
```javascript
import { Constants, useMediaDevice } from "@videosdk.live/react-sdk";
const {
checkPermissions, // async () => Map<"audio"|"video", boolean>
requestPermission, // async (mediaType) => Map
getCameras, // async () => MediaDeviceInfo[]
getMicrophones, // async () => MediaDeviceInfo[]
getPlaybackDevices, // async () => MediaDeviceInfo[] (speakers)
} = useMediaDevice({
onDeviceChanged: () => {
// Fires when a device is plugged/unplugged
getCameraDevices();
getAudioDevices();
},
});
// Check existing permissions:
const permissions = await checkPermissions();
const cameraAllowed = permissions.get(Constants.permission.VIDEO); // true/false/null
const micAllowed = permissions.get(Constants.permission.AUDIO);
// Request if not granted:
if (!micAllowed) {
const result = await requestPermission(Constants.permission.AUDIO);
const isAudioAllowed = result.get(Constants.permission.AUDIO); // true | false
}
// List all available cameras:
const cameras = await getCameras();
// cameras: [{ deviceId: "abc123", label: "FaceTime HD Camera", kind: "videoinput" }, ...]
// List all microphones:
const mics = await getMicrophones();
// mics: [{ deviceId: "def456", label: "Built-in Microphone", kind: "audioinput" }, ...]
// List all speakers:
const speakers = await getPlaybackDevices();
// speakers: [{ deviceId: "ghi789", label: "Built-in Output", kind: "audiooutput" }, ...]
```
--------------------------------
### useMediaStream()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Create custom media tracks. Custom hook wrapping `createCameraVideoTrack` and `createMicrophoneAudioTrack` from the SDK. Used to obtain optimized `MediaStream` objects before entering the meeting, which are then passed as `customCameraVideoTrack` / `customMicrophoneAudioTrack` to `MeetingProvider`.
```APIDOC
## useMediaStream()
### Description
Creates custom media tracks for video and audio. This hook wraps `createCameraVideoTrack` and `createMicrophoneAudioTrack` to provide optimized `MediaStream` objects that can be passed to `MeetingProvider`.
### Methods
- `getVideoTrack({ webcamId, encoderConfig })`: Asynchronously creates a video track using the specified camera ID and encoder configuration.
- `webcamId` (string): The ID of the camera device to use.
- `encoderConfig` (string, optional): The desired encoder configuration (e.g., "h540p_w960p"). Defaults to "h540p_w960p".
- `getAudioTrack({ micId })`: Asynchronously creates an audio track using the specified microphone ID.
- `micId` (string): The ID of the microphone device to use.
### Usage Example
```javascript
const { getVideoTrack, getAudioTrack } = useMediaStream();
const videoStream = await getVideoTrack({ webcamId: "abc123" });
const audioStream = await getAudioTrack({ micId: "def456" });
// Pass to MeetingProvider:
setCustomVideoStream(videoStream);
setCustomAudioStream(audioStream);
```
```
--------------------------------
### Create Custom Media Tracks with useMediaStream
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
This hook simplifies creating custom media streams for video and audio tracks using `createCameraVideoTrack` and `createMicrophoneAudioTrack`. These streams can be passed to `MeetingProvider` as custom tracks.
```javascript
import { createCameraVideoTrack, createMicrophoneAudioTrack } from "@videosdk.live/react-sdk";
const useMediaStream = () => {
const getVideoTrack = async ({ webcamId, encoderConfig }) => {
try {
const track = await createCameraVideoTrack({
cameraId: webcamId,
encoderConfig: encoderConfig || "h540p_w960p", // 960x540 @ 30fps
optimizationMode: "motion", // "motion" | "text" | "detail"
multiStream: false,
});
return track; // MediaStream with one video track
} catch (error) {
return null;
}
};
const getAudioTrack = async ({ micId }) => {
try {
const track = await createMicrophoneAudioTrack({ microphoneId: micId });
return track; // MediaStream with one audio track
} catch (error) {
return null;
}
};
return { getVideoTrack, getAudioTrack };
};
// Usage (inside JoiningScreen / BottomBar):
const { getVideoTrack, getAudioTrack } = useMediaStream();
const videoStream = await getVideoTrack({ webcamId: "abc123" });
const audioStream = await getAudioTrack({ micId: "def456" });
// Pass to MeetingProvider:
setCustomVideoStream(videoStream);
setCustomAudioStream(audioStream);
```
--------------------------------
### Create VideoSDK Meeting Room
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Creates a new meeting room using the VideoSDK REST API. Handles potential API errors and returns the meeting ID. Requires a valid auth token.
```javascript
export const createMeeting = async ({ token }) => {
const url = `${API_BASE_URL}/v2/rooms`;
const options = {
method: "POST",
headers: { Authorization: token, "Content-Type": "application/json" },
};
const response = await fetch(url, options);
const data = await response.json();
if (data.roomId) {
return { meetingId: data.roomId, err: null };
} else {
return { meetingId: null, err: data.error };
}
};
// Usage:
const token = await getToken();
const { meetingId, err } = await createMeeting({ token });
if (meetingId) {
console.log("Created meeting:", meetingId); // e.g. "abc-1234-xyz"
} else {
console.error("Failed to create meeting:", err);
}
// Equivalent curl:
// curl -X POST https://api.videosdk.live/v2/rooms \
// -H "Authorization: YOUR_TOKEN" \
// -H "Content-Type: application/json"
```
--------------------------------
### useMeeting()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
The core meeting hook for accessing meeting state and actions. It allows toggling media, leaving the meeting, managing recording, screen sharing, and subscribing to meeting-level events.
```APIDOC
## useMeeting()
### Description
Core hook for accessing meeting state and actions. Use this hook to toggle media, leave the meeting, manage recording, screen sharing, and subscribe to meeting-level events.
### Returns
An object containing meeting state and actions:
- **isMeetingJoined** (boolean) - True once the SDK has fully connected.
- **localParticipant** (object) - The local participant's data.
- **participants** (Map) - A map of all participants in the meeting.
- **presenterId** (string | null) - The ID of the participant currently screen sharing.
- **localMicOn** (boolean) - Whether the local participant's microphone is on.
- **localWebcamOn** (boolean) - Whether the local participant's webcam is on.
- **localScreenShareOn** (boolean) - Whether the local participant is screen sharing.
- **recordingState** (Constants.recordingEvents.*) - The current state of the meeting recording.
- **meetingId** (string) - The ID of the current meeting.
### Actions
- **toggleMic** () => void - Toggles the local participant's microphone.
- **toggleWebcam** (track?) => void - Toggles the local participant's webcam. Optionally accepts a track.
- **toggleScreenShare** () => void - Toggles screen sharing.
- **changeMic** (deviceId) => void - Changes the microphone device.
- **changeWebcam** (deviceId) => void - Changes the webcam device.
- **startRecording** () => void - Starts the meeting recording.
- **stopRecording** () => void - Stops the meeting recording.
- **leave** () => void - Leaves the meeting.
### Callbacks
- **onParticipantJoined**: (participant) => void - Called when a new participant joins the meeting.
- **onMeetingLeft**: () => void - Called when the local participant leaves the meeting.
- **onRecordingStateChanged**: ({ status }) => void - Called when the recording state changes.
- **onError**: ({ code, message }) => void - Called when an error occurs.
- **onMeetingStateChanged**: ({ state }) => void - Called when the meeting state changes.
```
--------------------------------
### getToken()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Retrieves a VideoSDK authentication token. It prioritizes the REACT_APP_VIDEOSDK_TOKEN environment variable. If not found, it fetches a token from an external auth server specified by REACT_APP_AUTH_URL.
```APIDOC
## getToken()
### Description
Fetches a VideoSDK authentication token either from the `REACT_APP_VIDEOSDK_TOKEN` environment variable or from an external auth server at `REACT_APP_AUTH_URL`. Exactly one source must be configured.
### Usage
```javascript
const token = await getToken();
// Returns: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
### Source Code (src/api.js)
```javascript
const API_BASE_URL = "https://api.videosdk.live";
const VIDEOSDK_TOKEN = process.env.REACT_APP_VIDEOSDK_TOKEN;
const API_AUTH_URL = process.env.REACT_APP_AUTH_URL;
export const getToken = async () => {
if (VIDEOSDK_TOKEN && API_AUTH_URL) {
console.error("Error: Provide only ONE PARAMETER - either Token or Auth API");
} else if (VIDEOSDK_TOKEN) {
return VIDEOSDK_TOKEN;
} else if (API_AUTH_URL) {
const res = await fetch(`${API_AUTH_URL}/get-token`, { method: "GET" });
const { token } = await res.json();
return token;
} else {
console.error("Error: ", Error("Please add a token or Auth Server URL"));
}
};
```
```
--------------------------------
### MeetingAppContext / useMeetingAppContext()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
React context and hook for accessing and managing application-level shared state, such as selected audio/video devices, sidebar visibility, raised hands, and PiP mode, across different components without prop drilling.
```APIDOC
## MeetingAppContext / useMeetingAppContext()
### Description
React context providing shared UI state (selected devices, sidebar mode, raised hands, PiP mode, permissions) to all components without prop drilling. The `useMeetingAppContext` hook provides easy access to this context.
### Usage
```jsx
import { useMeetingAppContext } from "@videosdk.live/react-sdk";
const MyComponent = () => {
const { sideBarMode, setSideBarMode, selectedMic } = useMeetingAppContext();
const openChat = () => {
setSideBarMode("CHAT");
};
return (
);
};
```
### Context Values
- `selectedMic` (object): Details of the selected microphone.
- `setSelectedMic` (function): Function to set the selected microphone.
- `selectedWebcam` (object): Details of the selected webcam.
- `setSelectedWebcam` (function): Function to set the selected webcam.
- `selectedSpeaker` (object): Details of the selected speaker device.
- `setSelectedSpeaker` (function): Function to set the selected speaker device.
- `raisedHandsParticipants` (array): List of participants who have raised their hands.
- `setRaisedHandsParticipants` (function): Function to update the list of raised hands.
- `sideBarMode` (string | null): Current mode of the sidebar (e.g., "CHAT", "PARTICIPANTS", null).
- `setSideBarMode` (function): Function to set the sidebar mode.
- `pipMode` (boolean): Indicates if Picture-in-Picture mode is active.
- `setPipMode` (function): Function to toggle PiP mode.
- `useRaisedHandParticipants` (function): Hook to manage participant raised hand events.
```
--------------------------------
### Responsive Participant Grid with ParticipantGrid
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Component that renders participant tiles in a dynamic grid. The column count automatically adjusts based on the number of participants, screen share status, and viewport size. Use this to display multiple participants efficiently.
```jsx
import { MemoizedParticipantGrid } from "./ParticipantGrid";
// In meeting/components/ParticipantView.js:
function ParticipantView({ isPresenting }) {
const { participants } = useMeeting();
const [participantsData, setParticipantsData] = useState([]);
useEffect(() => {
// Debounce 500ms to avoid rapid re-renders on join/leave
const timeout = setTimeout(() => {
setParticipantsData(Array.from(participants.keys()));
}, 500);
return () => clearTimeout(timeout);
}, [participants]);
return (
);
}
```
```plaintext
// Grid column logic (from ParticipantGrid.js):
// isPresenting / isMobile: 1–3 columns (1 col if <4p, 2 if <9p, else 3)
// Desktop without presenter: 2–4 columns (2 col if <5p, 3 if <7p, 4 if <9p, ...)
// Memoized: only re-renders when participantIds array or isPresenting changes
```
--------------------------------
###
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
The root SDK component that wraps the entire meeting UI and provides meeting context to all child hooks. It is configured with meeting ID, participant name, media state, and custom tracks.
```APIDOC
##
### Description
Initializes and provides a meeting session. This is the root SDK component that wraps the entire meeting UI and provides meeting context to all child hooks. It is configured with the meeting ID, participant name, media state, and custom tracks.
### Props
- **config** (object) - Configuration object for the meeting.
- **meetingId** (string) - Room ID from createMeeting/validateMeeting.
- **micEnabled** (boolean) - Start with mic on/off.
- **webcamEnabled** (boolean) - Start with webcam on/off.
- **name** (string) - Display name. Defaults to "Guest".
- **multiStream** (boolean) - Enables simulcast video layers.
- **customCameraVideoTrack** (MediaStreamTrack) - Pre-built video track from useMediaStream.
- **customMicrophoneAudioTrack** (MediaStreamTrack) - Pre-built audio track from useMediaStream.
- **token** (string) - Authentication token for the meeting.
- **reinitialiseMeetingOnConfigChange** (boolean) - Whether to reinitialize the meeting when configuration changes.
- **joinWithoutUserInteraction** (boolean) - Whether to join the meeting without user interaction.
```
--------------------------------
### Core Meeting Hook: useMeeting
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
The useMeeting hook provides access to meeting state and actions like toggling media, leaving, recording, and screen sharing. It also allows subscribing to meeting-level events.
```js
import { Constants, useMeeting } from "@videosdk.live/react-sdk";
const { isMeetingJoined, localParticipant, participants, presenterId, localMicOn, localWebcamOn, localScreenShareOn, recordingState, meetingId, toggleMic, toggleWebcam, toggleScreenShare, changeMic, changeWebcam, startRecording, stopRecording, leave } = useMeeting({
onParticipantJoined: (participant) => {
participant.setQuality("high"); // Force high quality for new participants
},
onMeetingLeft: () => {
// Clean up selected devices in context
setSelectedMic({ id: null, label: null });
},
onRecordingStateChanged: ({ status }) => {
if (status === Constants.recordingEvents.RECORDING_STARTED) {
toast("Meeting recording is started");
}
},
onError: ({ code, message }) => {
const joiningErrCodes = [4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009, 4010];
const isJoiningError = joiningErrCodes.includes(code);
new Audio("https://static.videosdk.live/prebuilt/notification_err.mp3").play();
setMeetingError({ code, message: isJoiningError ? "Unable to join meeting!" : message });
},
onMeetingStateChanged: ({ state }) => {
console.log("Meeting state:", state); // CONNECTING | CONNECTED | FAILED | ...
},
});
```
--------------------------------
### useParticipant Hook for Participant Media and Stats
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Use this hook to subscribe to a single participant's media streams, check their media status, and retrieve real-time WebRTC quality statistics. It provides access to webcam and mic status, display name, and media streams.
```javascript
import { useParticipant, VideoPlayer } from "@videosdk.live/react-sdk";
function ParticipantVideoSection({ participantId }) {
const {
webcamOn,
micOn,
displayName,
isLocal,
isActiveSpeaker,
micStream,
webcamStream,
screenShareStream,
getVideoStats,
getAudioStats,
getShareStats,
mode,
} = useParticipant(participantId);
return webcamOn ? (
) : (
{displayName?.charAt(0).toUpperCase()}
);
}
// Retrieve WebRTC stats every 500ms:
const statsIntervalId = setInterval(async () => {
const videoStats = await getVideoStats();
}, 500);
```
--------------------------------
### validateMeeting({ roomId, token })
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Validates an existing meeting room by calling the VideoSDK API. It confirms if a room ID is valid and active, returning the `meetingId` on success or an error message if the room is invalid or expired.
```APIDOC
## validateMeeting({ roomId, token })
### Description
Calls `GET /v2/rooms/validate/:roomId` to confirm a room is valid before joining. Returns the `meetingId` on success or an error string if the room does not exist or is expired.
### Parameters
#### Path Parameters
- **roomId** (string) - Required - The ID of the meeting room to validate.
#### Request Body Parameters
- **token** (string) - Required - The authentication token for the VideoSDK API.
### Request Example
```javascript
const token = await getToken();
const { meetingId, err } = await validateMeeting({ roomId: "abc-1234-xyz", token });
if (meetingId) {
// Proceed to join
setToken(token);
setMeetingId(meetingId);
onClickStartMeeting();
} else {
toast(`${err}`, { position: "bottom-left", autoClose: 4000 });
}
```
### Response
#### Success Response
- **meetingId** (string) - The validated meeting room ID.
- **err** (null) - Indicates no error occurred.
#### Error Response (Status Code 400)
- **meetingId** (null) - Indicates the room is invalid.
- **err** (string) - A message describing the validation error (e.g., room not found or expired).
### Source Code (src/api.js)
```javascript
const API_BASE_URL = "https://api.videosdk.live";
export const validateMeeting = async ({ roomId, token }) => {
const url = `${API_BASE_URL}/v2/rooms/validate/${roomId}`;
const options = {
method: "GET",
headers: { Authorization: token, "Content-Type": "application/json" },
};
const response = await fetch(url, options);
if (response.status === 400) {
const data = await response.text();
return { meetingId: null, err: data };
}
const data = await response.json();
return data.roomId
? { meetingId: data.roomId, err: null }
: { meetingId: null, err: data.error };
};
```
```
--------------------------------
### Display Screen Share with PresenterView
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Component to render the active presenter's screen share stream. It plays system audio separately and shows a 'Stop Presenting' button for the local presenter. Ensure VideoPlayer is imported.
```jsx
import { useMeeting, useParticipant, VideoPlayer } from "@videosdk.live/react-sdk";
export function PresenterView({ height }) {
const { presenterId, toggleScreenShare } = useMeeting();
// PresenterAudioPlayer: plays screen share audio for remote presenter
const { isLocal, screenShareAudioStream, screenShareOn } = useParticipant(presenterId);
useEffect(() => {
if (!isLocal && audioPlayer.current && screenShareOn && screenShareAudioStream) {
const mediaStream = new MediaStream();
mediaStream.addTrack(screenShareAudioStream.track);
audioPlayer.current.srcObject = mediaStream;
audioPlayer.current.play().catch(console.error);
}
}, [screenShareAudioStream, screenShareOn, isLocal]);
return (
{/* Screen share video */}
{/* "STOP PRESENTING" overlay shown only to the local presenter */}
{isLocal && (
)}
);
}
```
--------------------------------
### usePubSub(topic)
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Enables broadcast messaging between all meeting participants over a named topic. Used for in-meeting chat and raise-hand notifications.
```APIDOC
## usePubSub(topic)
### Description
Enables broadcast messaging between all meeting participants over a named topic. Used for in-meeting chat and raise-hand notifications.
### Parameters
#### Path Parameters
- **topic** (string) - Required - The name of the topic for publish/subscribe messaging.
### Methods
- **publish(message, options?)** - Publishes a message to the specified topic.
- **message** (any) - The message content to publish.
- **options** (object) - Optional configuration for publishing.
- **persist** (boolean) - If true, the message history will be kept.
### Return Values
- **messages** (array) - An array of received messages for the topic. Each message object has the following structure: `{ senderId, senderName, message, timestamp }`.
### Event Handlers
- **onMessageReceived(callback)** - A callback function that is invoked when a new message is received on the topic.
- The callback receives an object with message details: `{ senderId, senderName, message, timestamp }`.
### Request Example
```javascript
// --- Sending a chat message ---
import { usePubSub } from "@videosdk.live/react-sdk";
const ChatInput = () => {
const { publish } = usePubSub("CHAT");
const [message, setMessage] = useState("");
const sendMessage = () => {
const text = message.trim();
if (text.length > 0) {
publish(text, { persist: true }); // persist: true keeps message history
setMessage("");
}
};
// ...
};
// --- Receiving all chat messages ---
const ChatMessages = () => {
const { messages } = usePubSub("CHAT");
// messages: [{ senderId, senderName, message, timestamp }, ...]
return messages.map(({ senderId, senderName, message, timestamp }) => (
{senderName}: {message}
));
};
// --- Raise Hand notification ---
// Publishing (in BottomBar.js):
const { publish: publishHand } = usePubSub("RAISE_HAND");
publishHand("Raise Hand"); // broadcast to all participants
// Subscribing (in MeetingContainer.js):
usePubSub("RAISE_HAND", {
onMessageReceived: ({ senderId, senderName }) => {
new Audio("https://static.videosdk.live/prebuilt/notification.mp3").play();
toast(`${senderName} raised hand 🖐🏼`);
participantRaisedHand(senderId); // update context state
},
});
```
```
--------------------------------
### Measure Network Speed with getNetworkStats
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Use this utility function to measure real-time upload and download bandwidth. It's useful for pre-call network status checks. Handle potential 'no Network' or 'timeout' errors.
```javascript
import { getNetworkStats } from "@videosdk.live/react-sdk";
const getNetworkStatistics = async () => {
try {
const options = { timeoutDuration: 45000 }; // 45-second timeout
const networkStats = await getNetworkStats(options);
console.log(networkStats.downloadSpeed); // e.g. "12.34" (MBPS)
console.log(networkStats.uploadSpeed); // e.g. "8.56" (MBPS)
} catch (ex) {
if (ex === "Not able to get NetworkStats due to no Network") {
// Show offline warning UI
}
if (ex === "Not able to get NetworkStats due to timeout") {
// Show timeout warning UI
}
}
};
```
--------------------------------
### MeetingAppContext for Shared State Management
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
This React context and hook provide a way to share application-level UI state across components without prop drilling. It manages device selection, sidebar visibility, raised hands, and PiP mode. Use `MeetingAppProvider` to wrap your application and `useMeetingAppContext` in any child component to access shared state.
```jsx
// src/MeetingAppContextDef.js
import { createContext, useContext, useState, useEffect, useRef } from "react";
export const MeetingAppContext = createContext();
export const useMeetingAppContext = () => useContext(MeetingAppContext);
export const MeetingAppProvider = ({ children }) => {
const [selectedMic, setSelectedMic] = useState({ id: null, label: null });
const [selectedWebcam, setSelectedWebcam] = useState({ id: null, label: null });
const [selectedSpeaker, setSelectedSpeaker] = useState({ id: null, label: null });
const [raisedHandsParticipants, setRaisedHandsParticipants] = useState([]);
const [sideBarMode, setSideBarMode] = useState(null); // "CHAT" | "PARTICIPANTS" | null
const [pipMode, setPipMode] = useState(false);
const useRaisedHandParticipants = () => {
const raisedHandsParticipantsRef = useRef();
const participantRaisedHand = (participantId) => {
const list = [...raisedHandsParticipantsRef.current];
const newItem = { participantId, raisedHandOn: Date.now() };
const idx = list.findIndex(({ participantId: pID }) => pID === participantId);
if (idx === -1) list.push(newItem);
else list[idx] = newItem;
setRaisedHandsParticipants(list);
};
// Auto-clear raised hands after 15 seconds
useEffect(() => {
const interval = setInterval(() => {
const now = Date.now();
setRaisedHandsParticipants((prev) =>
prev.filter(({ raisedHandOn }) => raisedHandOn + 15000 > now)
);
}, 1000);
return () => clearInterval(interval);
}, []);
return { participantRaisedHand };
};
return (
{children}
);
};
// Consuming in any child component:
const { sideBarMode, setSideBarMode, selectedMic } = useMeetingAppContext();
setSideBarMode("CHAT"); // open chat panel
```
--------------------------------
### useParticipant(participantId)
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Subscribes to a single participant's streams, media state, and provides methods to retrieve real-time WebRTC quality statistics.
```APIDOC
## useParticipant(participantId)
### Description
Subscribes to a single participant's streams, media state, and provides methods to retrieve real-time WebRTC quality statistics.
### Parameters
#### Path Parameters
- **participantId** (string) - Required - The unique identifier for the participant.
### Return Values
- **webcamOn** (boolean) - Indicates if the participant's webcam is on.
- **micOn** (boolean) - Indicates if the participant's microphone is on.
- **displayName** (string) - The display name of the participant.
- **isLocal** (boolean) - Indicates if the participant is the local user.
- **isActiveSpeaker** (boolean) - Indicates if the participant is currently the active speaker.
- **micStream** (MediaStream object) - The MediaStream object for the participant's audio.
- **webcamStream** (MediaStream object) - The MediaStream object for the participant's video.
- **screenShareStream** (MediaStream object) - The MediaStream object for the participant's screen share.
- **mode** (string) - The current media mode of the participant ('SEND_AND_RECV', 'RECV_ONLY', 'SEND_ONLY').
### Methods
- **getVideoStats()** - async () => stats[] - Retrieves real-time video statistics.
- **getAudioStats()** - async () => stats[] - Retrieves real-time audio statistics.
- **getShareStats()** - async () => stats[] - Retrieves real-time screen share statistics.
### Request Example
```javascript
import { useParticipant, VideoPlayer } from "@videosdk.live/react-sdk";
function ParticipantVideoSection({ participantId }) {
const {
webcamOn,
micOn,
displayName,
isLocal,
isActiveSpeaker,
micStream,
webcamStream,
screenShareStream,
getVideoStats,
getAudioStats,
getShareStats,
mode,
} = useParticipant(participantId);
// Render video stream using SDK's VideoPlayer component
return webcamOn ? (
) : (
{displayName?.charAt(0).toUpperCase()}
);
}
// Retrieve WebRTC stats every 500ms:
const statsIntervalId = setInterval(async () => {
const videoStats = await getVideoStats();
// videoStats[0]: { rtt, jitter, packetsLost, totalPackets, bitrate,
// size: { width, height, framerate }, codec,
// currentSpatialLayer, currentTemporalLayer }
}, 500);
```
```
--------------------------------
### usePubSub Hook for Real-time Messaging
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
This hook enables broadcast messaging between all meeting participants over a named topic, suitable for in-meeting chat or notifications. Use 'publish' to send messages and 'messages' to receive them. Configuration options for 'onMessageReceived' are available for custom handling.
```javascript
import { usePubSub } from "@videosdk.live/react-sdk";
// --- Sending a chat message ---
const ChatInput = () => {
const { publish } = usePubSub("CHAT");
const [message, setMessage] = useState("");
const sendMessage = () => {
const text = message.trim();
if (text.length > 0) {
publish(text, { persist: true }); // persist: true keeps message history
setMessage("");
}
};
// ...
};
// --- Receiving all chat messages ---
const ChatMessages = () => {
const { messages } = usePubSub("CHAT");
// messages: [{ senderId, senderName, message, timestamp }, ...]
return messages.map(({ senderId, senderName, message, timestamp }) => (
{senderName}: {message}
));
};
// --- Raise Hand notification ---
// Publishing (in BottomBar.js):
const { publish: publishHand } = usePubSub("RAISE_HAND");
publishHand("Raise Hand"); // broadcast to all participants
// Subscribing (in MeetingContainer.js):
usePubSub("RAISE_HAND", {
onMessageReceived: ({ senderId, senderName }) => {
new Audio("https://static.videosdk.live/prebuilt/notification.mp3").play();
toast(`${senderName} raised hand 🖐🏼`);
participantRaisedHand(senderId); // update context state
},
});
```
--------------------------------
### ParticipantPanel Component for Participant List
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Lists all meeting participants, sorted by raised-hand status with raised hands appearing first. Displays mic/webcam status and a raised-hand indicator for each participant. Uses `useMeetingAppContext` for `raisedHandsParticipants` and `useMeeting` for `participants`. Requires `useMemo` for sorting.
```jsx
// src/components/sidebar/ParticipantPanel.js
import { useMeeting, useParticipant } from "@videosdk.live/react-sdk";
import { useMeetingAppContext } from "../../MeetingAppContextDef";
export function ParticipantPanel({ panelHeight }) {
const { raisedHandsParticipants } = useMeetingAppContext();
const { participants } = useMeeting();
// Sort: raised-hand participants first (newest raise at top), rest below
const sortedList = useMemo(() => {
const ids = [...participants.keys()];
const notRaised = ids.filter(
(id) => !raisedHandsParticipants.find(({ participantId }) => participantId === id)
);
const raisedSorted = [...raisedHandsParticipants].sort((a, b) => b.raisedHandOn - a.raisedHandOn);
return [
...raisedSorted.map(({ participantId }) => ({ participantId, raisedHand: true })),
...notRaised.map((id) => ({ participantId: id, raisedHand: false })),
];
}, [raisedHandsParticipants, participants]);
return (
);
}
```
--------------------------------
### useIsRecording()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
A custom hook that returns a boolean indicating if a recording is currently active or stopping. It derives its state from the `recordingState` provided by the `useMeeting` hook.
```APIDOC
## useIsRecording()
### Description
Custom hook that derives a simple boolean from the SDK's `recordingState` enum. Returns `true` when a recording is actively running or in the process of stopping.
### Usage
```javascript
import { useIsRecording } from "@videosdk.live/react-sdk";
const isRecording = useIsRecording();
// Use isRecording to conditionally render UI or trigger actions
if (isRecording) {
// Show stop recording button
} else {
// Show start recording button
}
```
### Returns
- `boolean`: `true` if recording is started or stopping, `false` otherwise.
```
--------------------------------
### getNetworkStats()
Source: https://context7.com/videosdk-live/videosdk-rtc-react-sdk-example/llms.txt
Measure upload/download speed. SDK utility function used in the pre-call `NetworkStats` component to display real-time upload and download bandwidth to the user before joining.
```APIDOC
## getNetworkStats()
### Description
Measures the user's upload and download network speed. This utility function is useful for displaying real-time bandwidth information before joining a meeting.
### Parameters
- `options` (object, optional): Configuration options for the network stats measurement.
- `timeoutDuration` (number, optional): The duration in milliseconds to attempt the network speed test. Defaults to 45000 (45 seconds).
### Returns
- An object containing `downloadSpeed` and `uploadSpeed` in MBPS.
### Usage Example
```javascript
const options = { timeoutDuration: 45000 }; // 45-second timeout
const networkStats = await getNetworkStats(options);
console.log(networkStats.downloadSpeed); // e.g. "12.34" (MBPS)
console.log(networkStats.uploadSpeed); // e.g. "8.56" (MBPS)
```
### Error Handling
- Throws an error if network stats cannot be determined due to network unavailability or timeout.
- `"Not able to get NetworkStats due to no Network"`
- `"Not able to get NetworkStats due to timeout"`
```