> ## Documentation Index
> Fetch the complete documentation index at: https://red5.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Red5 Conference SDK — Multi-Party Video Conferencing

> Build multi-party video conferencing with the Red5 Conference SDK. Covers room join flow, media controls, virtual backgrounds, local recording, and chat.

The Red5 Pro Conference SDK is a JavaScript toolkit for building multi-party video conferencing applications on Red5 Cloud and Red5 Pro. It manages room lifecycle, WHIP/WHEP media publishing and subscribing, WebRTC statistics monitoring, and interactive features including virtual backgrounds, local recording, screen sharing, and PubNub-powered chat — all from a single `ConferenceClient` object.

## Installation

```bash theme={null}
npm install red5pro-conference-sdk
```

## Key concepts

* **Room** — a named session identified by a `roomId`. Multiple users join the same room to exchange audio and video.
* **Participant** — a user in the room, identified by a `userId`. Each participant can publish audio/video (role: `publisher`) or receive only (role: `subscriber`).
* **Media tracks** — participants publish their local `MediaStream` via WHIP, and subscribe to each other's streams via WHEP. You receive a `MediaStream` for each subscribed participant to attach to a `<video>` element.

## Joining a room

<Steps>
  <Step title="Create a ConferenceClient">
    Pass your server details and optional PubNub keys for chat.

    ```javascript theme={null}
    import { ConferenceClient, ConferenceEvents } from 'red5pro-conference-sdk';

    const client = new ConferenceClient({
      host: 'your-red5-pro-host',
      nodeGroup: 'your-node-group',
      iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
      pubnubPublishKey: 'your-pubnub-publish-key',
      pubnubSubscribeKey: 'your-pubnub-subscribe-key',
    });
    ```
  </Step>

  <Step title="Subscribe to new participants">
    Listen for `NEW_PARTICIPANT` and subscribe automatically so you receive their video as soon as they join.

    ```javascript theme={null}
    client.addEventListener(ConferenceEvents.NEW_PARTICIPANT, async (e) => {
      const user = e.detail;
      try {
        const info = await client.subscribe(user);
        if (info?.mediaStream) {
          const videoEl = document.createElement('video');
          videoEl.srcObject = info.mediaStream;
          videoEl.autoplay = true;
          document.getElementById('participants').appendChild(videoEl);
        }
      } catch (err) {
        console.error('Subscribe failed', err);
      }
    });
    ```
  </Step>

  <Step title="Acquire local media and join">
    ```javascript theme={null}
    const localStream = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true,
    });

    await client.join(
      'my-room-id',   // roomId
      'user-123',     // userId
      'auth-token',   // token from your backend
      'publisher',    // role: 'publisher' or 'subscriber'
      localStream,    // MediaStream
      true,           // videoEnabled
      true            // audioEnabled
    );

    console.log('Joined room successfully');
    ```
  </Step>

  <Step title="Leave the room">
    ```javascript theme={null}
    await client.leave();
    ```
  </Step>
</Steps>

## Media controls

Mute and unmute your local audio and video without leaving the room.

```javascript theme={null}
// Mute/unmute audio
await client.muteAudio();
await client.unmuteAudio();

// Mute/unmute video
await client.muteVideo();
await client.unmuteVideo();

// Listen for state changes
client.addEventListener(ConferenceEvents.AUDIO_MUTED, () => {
  console.log('Audio is muted');
});
```

**Switch device without dropping the connection:**

```javascript theme={null}
// Switch to a different camera
await client.switchVideoDeviceWithTrackReplacement(newCameraDeviceId);

// Switch to a different microphone
await client.switchAudioDeviceWithTrackReplacement(newMicDeviceId);
```

## Screen sharing

```javascript theme={null}
// Start sharing your screen
await client.startScreenShare({
  includeAudio: true,
  metaData: { type: 'presentation' },
});

// Stop sharing
await client.stopScreenShare();
```

## Virtual backgrounds

Virtual backgrounds use `@mediapipe/selfie_segmentation` to replace or blur the area behind your camera feed.

<Steps>
  <Step title="Initialize the background processor">
    ```javascript theme={null}
    await client.initializeVirtualBackground();
    ```
  </Step>

  <Step title="Apply a background">
    ```javascript theme={null}
    // Blur background
    await client.enableVirtualBackground('blur', { blurAmount: 10 });

    // Image replacement
    await client.enableVirtualBackground('image', {
      imageUrl: 'path/to/background.jpg',
    });
    ```
  </Step>

  <Step title="Remove the background">
    ```javascript theme={null}
    await client.disableVirtualBackground();
    ```
  </Step>
</Steps>

Available background types:

| Type                                 | Description              |
| ------------------------------------ | ------------------------ |
| `VirtualBackgroundTypes.NONE`        | No background processing |
| `VirtualBackgroundTypes.BLUR`        | Strong blur              |
| `VirtualBackgroundTypes.SLIGHT_BLUR` | Light blur               |
| `VirtualBackgroundTypes.IMAGE`       | Image replacement        |
| `VirtualBackgroundTypes.COLOR`       | Solid color replacement  |

## Local recording

Record participant streams directly in the browser. The recording is stored locally and downloaded as a ZIP file.

```javascript theme={null}
// Download the local recording
await client.downloadLocalRecording('my-conference-2026-05-21');

// Or get a ZIP blob to handle yourself
const zipBlob = await client.generateLocalRecordingZip();
```

## Chat

Send and receive text messages within the room using PubNub. Pass your PubNub keys in the `ConferenceClient` config.

```javascript theme={null}
// Listen for incoming messages
client.addEventListener(ConferenceEvents.CHAT_MESSAGE, (e) => {
  const message = e.detail;
  console.log('New message:', message.text);
});

// Send a message
client.sendChatMessage('Hello everyone!');
```

## Configuration reference

| Property                  | Type             | Default     | Description                          |
| ------------------------- | ---------------- | ----------- | ------------------------------------ |
| `host`                    | `string`         | Required    | Red5 Pro server address              |
| `nodeGroup`               | `string`         | `undefined` | Target node group for scaling        |
| `iceServers`              | `RTCIceServer[]` | `undefined` | STUN/TURN server configurations      |
| `reconnectionEnabled`     | `boolean`        | `false`     | Enable automatic reconnection        |
| `maxVideoBitrateKbps`     | `number`         | `undefined` | Maximum video bitrate for publishing |
| `statsPollingInterval`    | `number`         | `undefined` | WebRTC stats polling interval in ms  |
| `pubnubPublishKey`        | `string`         | `undefined` | PubNub key for chat                  |
| `pubnubSubscribeKey`      | `string`         | `undefined` | PubNub key for chat                  |
| `enableNoiseCancellation` | `boolean`        | `false`     | Enable RNNoise noise suppression     |

## API reference highlights

<AccordionGroup>
  <Accordion title="Room management">
    | Method                                                                       | Returns            | Description                    |
    | ---------------------------------------------------------------------------- | ------------------ | ------------------------------ |
    | `join(roomId, userId, token, role, mediaStream, videoEnabled, audioEnabled)` | `Promise<boolean>` | Join a conference room         |
    | `leave()`                                                                    | `Promise<void>`    | Leave the conference room      |
    | `getRoomUsers()`                                                             | `Object`           | Get all current room users     |
    | `getIsJoined()`                                                              | `boolean`          | `true` if currently in a room  |
    | `getIsPublishing()`                                                          | `boolean`          | `true` if currently publishing |
  </Accordion>

  <Accordion title="Subscribing">
    | Method                        | Returns                                      | Description                         |
    | ----------------------------- | -------------------------------------------- | ----------------------------------- |
    | `subscribe(user: User)`       | `Promise<{ subscriber, user, mediaStream }>` | Subscribe to a participant's stream |
    | `unsubscribe(userId: string)` | `Promise<void>`                              | Stop subscribing to a participant   |
  </Accordion>

  <Accordion title="Events">
    | Event                         | Description                              |
    | ----------------------------- | ---------------------------------------- |
    | `USER_PUBLISHED`              | Local client published successfully      |
    | `NEW_PARTICIPANT`             | A new participant joined the room        |
    | `PARTICIPANT_DISCONNECTED`    | A participant left the room              |
    | `SUBSCRIBE_SUCCESS`           | Successfully subscribed to a participant |
    | `ROOM_STATE_UPDATE`           | Room users, roles, or states changed     |
    | `CHAT_MESSAGE`                | A chat message was received              |
    | `ISSUES_DETECTED`             | Network or WebRTC issues detected        |
    | `VIDEO_MUTED` / `AUDIO_MUTED` | Video or audio muted successfully        |
  </Accordion>
</AccordionGroup>

<Tip>
  Use the Backend SDK to generate the `token` parameter you pass to `client.join()`. This keeps your master credentials on the server and gives you control over user roles and token expiration.
</Tip>
