> ## Documentation Index
> Fetch the complete documentation index at: https://www.cometchat.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Presenter Mode

> CometChat Calling SDK v4 - Stable Release - Presenter Mode for React Native

<Info>
  **Quick Reference** - Start a presentation session:

  ```javascript theme={null}
  let presenterSettings = new CometChatCalls.PresenterSettingsBuilder()
    .setIsPresenter(true) // false for viewer
    .enableDefaultLayout(true)
    .setCallEventListener(callListener)
    .build();

  // <CometChatCalls.PresenterComponent presenterSettings={presenterSettings} callToken={callToken} />
  ```
</Info>

<Note>
  **Available via:** SDK | UI Kits
</Note>

## Overview

The Presenter Mode feature allows developers to create a calling service experience in which:

1. There are one or more users who are presenting their video, audio and/or screen (Maximum 5)
2. Viewers who are consumers of that presentation (they cannot send their audio, video or screen streams out)
3. The total number of presenters and viewers can go up to 100
4. Features such as mute/unmute audio, show/hide camera capture, recording, etc. will be enabled only for the Presenter
5. Other call participants act like passive viewers in the call

### About this guide

This guide demonstrates how to start a presentation into a React Native application. Before you begin, we strongly recommend you read the [calling setup guide](/calls/v4/react-native/setup).

Before starting a call session you have to [generate a call token](/calls/v4/react-native/call-session#generate-call-token).

### Start Presentation Session

The `PresentationSettings` class allows you to set the various parameters for the Presentation Mode. Use the `PresentationSettingsBuilder` class to configure it.

Set the User Type with `setIsPresenter(true/false)` — there are 2 types: `Presenter` & `Participant`.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    let presenterSettings = new CometChatCalls.PresenterSettingsBuilder()
      .setIsPresenter(isPresenter)
      .enableDefaultLayout(defaultLayout)
      .setCallEventListener(callListener)
      .build();

    return (
      <View style={{flex:1}}>
        <CometChatCalls.PresenterComponent presenterSettings={presenterSettings} callToken={callToken} />
      </View>
    );
    ```
  </Tab>
</Tabs>

## Listeners

Listeners can be added in two ways: using `.setCallEventListener(listeners)` in `PresenterSettingsBuilder`, or using `CometChatCalls.addCallEventListener(name, callListener)`.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    useEffect(() => {
      CometChatCalls.addCallEventListener("UNIQUE_ID", {
        onUserJoined: (user) => console.log("user joined:", user),
        onUserLeft: (user) => console.log("user left:", user),
        onUserListUpdated: (userList) => console.log("user list:", userList),
        onCallEnded: () => console.log("Call ended"),
        onCallEndButtonPressed: () => console.log("End Call button pressed"),
        onError: (error) => console.log("Call Error: ", error),
        onAudioModesUpdated: (audioModes) => console.log("audio modes:", audioModes),
        onUserMuted: (event) => console.log("user muted:", event),
      });
      return () => CometChatCalls.removeCallEventListener("UNIQUE_ID");
    }, []);
    ```
  </Tab>
</Tabs>

<Warning>
  Always remove call event listeners when the component unmounts using `CometChatCalls.removeCallEventListener(listenerId)`.
</Warning>

### Events

| Callback Method                                 | Description                                                                   |
| ----------------------------------------------- | ----------------------------------------------------------------------------- |
| onCallEnded()                                   | Called when the call is successfully ended.                                   |
| onCallEndButtonPressed()                        | Called when the user presses the end call button.                             |
| onUserJoined(user: RTCUser)                     | Called when any other user joins the call.                                    |
| onUserLeft(user: RTCUser)                       | Called when a user leaves the call.                                           |
| onUserListUpdated(users: Array\<RTCUser>)       | Triggered every time a participant joins or leaves the call.                  |
| onAudioModesUpdated(devices: Array\<AudioMode>) | Triggered if any new audio output source is available or becomes unavailable. |
| onUserMuted(muteObj: RTCMutedUser)              | Triggered when a user is muted in the ongoing call.                           |
| onRecordingStarted(user: RTCUser)               | Triggered when a recording starts.                                            |
| onRecordingStopped(user: RTCUser)               | Triggered when a recording stops.                                             |
| onError(e: CometChatException)                  | Called when there is some error in establishing the call.                     |

## Settings

The `PresentationSettings` class customization options:

| Parameter                                                 | Description                                                                        |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `setIsPresenter(isPresenter: boolean)`                    | If `true` user joins as presenter. If `false` user joins as viewer.                |
| `enableDefaultLayout(defaultLayout: boolean)`             | Enables/disables the default layout. **Default: true**                             |
| `showEndCallButton(showEndCallButton: boolean)`           | Shows/hides the EndCallButton. **Default: true**                                   |
| `showMuteAudioButton(showMuteAudioButton: boolean)`       | Shows/hides the MuteAudioButton. **Default: true**                                 |
| `showSwitchCameraButton(showSwitchCameraButton: boolean)` | Shows/hides the SwitchCameraButton. **Default: true**                              |
| `showAudioModeButton(showAudioModeButton: boolean)`       | Shows/hides the AudioModeButton. **Default: true**                                 |
| `setIsAudioOnlyCall(audioOnly: boolean)`                  | If `true`, audio-only call. **Default: false**                                     |
| `startWithAudioMuted(audioMuted: boolean)`                | Starts with audio muted. **Default: false**                                        |
| `startWithVideoMuted(videoMuted: boolean)`                | Starts with video paused. **Default: false**                                       |
| `setDefaultAudioMode(audioMode: string)`                  | Sets initial audio mode. Options: `SPEAKER`, `EARPIECE`, `BLUETOOTH`, `HEADPHONES` |

<AccordionGroup>
  <Accordion title="Best Practices">
    * Always explicitly set `setIsPresenter(true)` for presenters and `setIsPresenter(false)` for viewers
    * Limit presenters to 5 — enforce this in your logic before calling `setIsPresenter(true)`
    * Clean up listeners on component unmount
    * Generate call tokens just before use
  </Accordion>

  <Accordion title="Troubleshooting">
    * **Viewer can send audio/video:** Verify `setIsPresenter(false)` is set for viewer participants
    * **Presentation UI does not render:** Ensure the component is wrapped in a `View` with `flex: 1` or explicit dimensions
    * **Listeners not firing:** Check that the listener is registered before the session starts
    * **Maximum participant limit reached:** Presenter Mode supports up to 100 total participants
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Call Session" icon="video" href="/calls/v4/react-native/call-session">
    Start and manage standard call sessions with full configuration options
  </Card>

  <Card title="Recording" icon="circle-dot" href="/calls/v4/react-native/recording">
    Record presentation sessions for playback and compliance
  </Card>

  <Card title="Video View Customisation" icon="sliders" href="/calls/v4/react-native/video-view-customisation">
    Customize the main video container and participant tiles
  </Card>

  <Card title="Calls SDK Setup" icon="gear" href="/calls/v4/react-native/setup">
    Install dependencies, configure permissions, and initialize the Calls SDK
  </Card>
</CardGroup>
