Multi-Host Live Streaming

Create engaging live streams with multiple hosts, like podcasts or panel discussions

Overview

Multi-host streaming allows multiple people to broadcast simultaneously to a large audience. This is perfect for podcast-style shows, panel discussions, interviews, or any scenario where you need multiple speakers broadcasting to viewers. Unlike traditional video calls, multi-host streams have distinct roles: hosts who can publish audio/video, and viewers who can only watch.

Multiple Publishers

Up to 10 hosts can broadcast simultaneously

Unlimited Viewers

Broadcast to thousands of viewers at once

Dynamic Roles

Promote viewers to hosts on the fly

Common Use Cases

Live Podcast Shows

Stream your podcast live with multiple co-hosts. Viewers can watch in real-time and you can invite guests to join as temporary hosts during the show.

Panel Discussions

Host expert panels with 3-5 speakers discussing a topic. Each panelist appears on screen while thousands can watch and learn.

Interview Shows

Conduct live interviews where the host and guest both appear on stream. Easily bring on new guests by promoting viewers to host status.

How Multi-Host Streaming Works

Multi-host streaming uses a publish-subscribe model with role-based permissions:

1. Role Management

Participants are assigned one of two roles:

Host (Publisher)
  • Can publish audio and video
  • Appears in the stream to all viewers
  • Can send real-time messages
  • Limited to 10 concurrent hosts
Viewer (Subscriber)
  • Can only watch and listen
  • Cannot publish audio/video
  • Can send messages (if enabled)
  • Unlimited concurrent viewers

2. Media Publishing

When a host publishes their audio/video, it's transmitted to BaxCloud's media servers. These servers mix the audio from all hosts and distribute the combined stream to viewers. Viewers receive a low-latency stream (typically 1-3 seconds delay) containing all active hosts.

3. Dynamic Role Switching

The main host (room owner) can promote viewers to host status in real-time. When promoted, the viewer's client immediately starts publishing their media, and they appear on the stream to all viewers within seconds. Similarly, hosts can be demoted back to viewer status.

4. Layout & Composition

You control how hosts are displayed to viewers. Common layouts include grid view (equal tiles), speaker view (active speaker prominent), or custom layouts. The SDK provides layout templates, or you can build your own using CSS/UI frameworks.

Step-by-Step Implementation

Build a multi-host streaming experience

1

Create a Room with Host Role

Initialize as a host who can publish

When creating a multi-host stream, the first host creates the room:

1import { BaxCloudClient } from '@baxcloud/react-sdk';
2
3const createMultiHostStream = async () => {
4  const client = new BaxCloudClient({
5    projectId: 'your-project-id',
6    apiKey: 'your-api-key',
7  });
8
9  // Join as host (publisher)
10  await client.connect({
11    roomName: 'podcast-episode-42',
12    liveType: 'live_streaming',
13    participant: {
14      userId: 'host-1',
15      name: 'Main Host',
16      avatarUrl: 'https://example.com/avatar.jpg',
17      isHost: true,
18    },
19  });
20
21  // Enable camera and microphone
22  await client.enableCamera();
23  await client.enableMicrophone();
24
25  console.log('Stream created, you are live!');
26};
💡

Host vs Viewer

Set isHost: true to join as a host (publisher). Set isHost: falseto join as a viewer (subscriber). Only the room creator and promoted users should be hosts.
2

Join as a Viewer

Allow viewers to watch the stream

Viewers join the same room but with isHost: false:

1const joinAsViewer = async () => {
2  const client = new BaxCloudClient({
3    projectId: 'your-project-id',
4    apiKey: 'your-api-key',
5  });
6
7  // Join as viewer (subscriber)
8  await client.connect({
9    roomName: 'podcast-episode-42',
10    liveType: 'live_streaming',
11    participant: {
12      userId: 'viewer-123',
13      name: 'John Doe',
14      avatarUrl: 'https://example.com/avatar.jpg',
15      isHost: false,
16    },
17  });
18
19  console.log('Joined as viewer');
20};
💡

Viewer Experience

Viewers cannot publish their own media. They only receive streams from hosts. This keeps bandwidth requirements low for viewers and ensures streams scale to thousands of concurrent viewers.
3

Add Additional Hosts

Invite co-hosts to join the stream

Other hosts can join using the same room name with isHost: true:

1const joinAsCoHost = async () => {
2  const client = new BaxCloudClient({
3    projectId: 'your-project-id',
4    apiKey: 'your-api-key',
5  });
6
7  await client.connect({
8    roomName: 'podcast-episode-42',
9    liveType: 'live_streaming',
10    participant: {
11      userId: 'host-2',
12      name: 'Co-Host Jane',
13      avatarUrl: 'https://example.com/avatar.jpg',
14      isHost: true,
15    },
16  });
17
18  // Enable media
19  await client.enableCamera();
20  await client.enableMicrophone();
21
22  console.log('Joined as co-host');
23};
4

Promote Viewers to Co-Hosts

Dynamically add hosts during the stream

The main host can promote viewers to co-host status in real-time:

1import { BaxCloudRoomController } from '@baxcloud/react-sdk';
2
3// Main host promotes a viewer to co-host
4const controller = BaxCloudRoomController.instance;
5
6const promoteToCoHost = async (userId: string) => {
7  try {
8    await controller.promoteToCoHost(userId);
9    console.log(`Promoted ${userId} to co-host`);
10  } catch (error) {
11    console.error('Failed to promote viewer:', error);
12  }
13};
14
15// Listen for co-host promotion events
16controller.onCoHostPromoted((user) => {
17  console.log(`${user.name} has been promoted to co-host!`);
18    
19  // If this is the current user, enable media
20  if (user.userId === currentUserId) {
21    client.enableCamera();
22    client.enableMicrophone();
23  }
24});
25
26// UI for promoting viewers
27function ViewerList() {
28  const participants = controller.getParticipants();
29  const viewers = participants.filter(p => !p.isHost && !controller.getCoHosts().includes(p.userId));
30
31  return (
32    <div>
33      <h3>Viewers</h3>
34      {viewers.map(viewer => (
35        <div key={viewer.userId}>
36          <span>{viewer.name}</span>
37          <button onClick={() => promoteToCoHost(viewer.userId)}>
38            Invite to Stage
39          </button>
40        </div>
41      ))}
42    </div>
43  );
44}
⚠️

Permission Required

Only the room creator or users with admin permissions can promote/demote participants. Regular hosts cannot change other users' roles.
5

Demote Co-Hosts to Viewers

Remove co-hosts from the stream

Co-hosts can be demoted back to viewer status:

1import { BaxCloudRoomController } from '@baxcloud/react-sdk';
2
3const controller = BaxCloudRoomController.instance;
4
5// Demote a co-host to viewer
6const demoteFromCoHost = async (userId: string) => {
7  try {
8    await controller.demoteFromCoHost(userId);
9    console.log(`Demoted ${userId} from co-host`);
10  } catch (error) {
11    console.error('Failed to demote co-host:', error);
12  }
13};
14
15// Listen for co-host demotion
16controller.onCoHostDemoted((user) => {
17  console.log(`${user.name} has been demoted from co-host`);
18    
19  // If this is the current user, disable media
20  if (user.userId === currentUserId) {
21    client.disableCamera();
22    client.disableMicrophone();
23  }
24});
25
26// UI for managing co-hosts
27function CoHostList() {
28  const coHosts = controller.getCoHosts();
29  const participants = controller.getParticipants();
30
31  return (
32    <div>
33      <h3>Co-Hosts</h3>
34      {coHosts.map(coHostId => {
35        const coHost = participants.find(p => p.userId === coHostId);
36        return (
37          <div key={coHostId}>
38            <span>{coHost?.name}</span>
39            <button onClick={() => demoteFromCoHost(coHostId)}>
40              Remove from Stage
41            </button>
42        </div>
43        );
44      })}
45    </div>
46  );
47}
6

Manage Audio Levels

Monitor and control participant audio

Monitor audio levels and manage microphone controls for participants:

1import { BaxCloudRoomController } from '@baxcloud/react-sdk';
2
3const controller = BaxCloudRoomController.instance;
4
5// Get all participants
6const participants = controller.getParticipants();
7
8// Toggle microphone for local participant
9const toggleMicrophone = async () => {
10  if (controller.isMicrophoneEnabled()) {
11    await controller.disableMicrophone();
12  } else {
13    await controller.enableMicrophone();
14  }
15};
16
17// Monitor participants
18participants.forEach(participant => {
19  console.log(`Participant: ${participant.name}, Is Host: ${participant.isHost}`);
20});
💡

Audio Best Practices

For multi-host streams, ensure all hosts use headphones to prevent echo. Monitor participant audio levels and provide visual feedback. Coordinate with hosts to prevent multiple people speaking simultaneously.
7

Display Hosts to Viewers

Render multiple host video streams

Display multiple host video streams in your UI. Layout management is handled on the client side:

1import { BaxCloudRoomController } from '@baxcloud/react-sdk';
2
3const controller = BaxCloudRoomController.instance;
4
5// Get all participants (hosts)
6const participants = controller.getParticipants();
7const hosts = participants.filter(p => p.isHost);
8
9// Grid layout example
10function HostGrid() {
11  return (
12    <div className="grid grid-cols-3 gap-4">
13      {hosts.map(host => (
14        <div key={host.userId} className="host-video">
15          <video
16            // Attach video track from room
17            autoPlay
18            playsInline
19          />
20          <div className="host-name">{host.name}</div>
21        </div>
22      ))}
23    </div>
24  );
25}

Best Practices

Limit concurrent hosts

While you can have up to 10 hosts, 2-4 hosts provides the best experience. Too many hosts can be overwhelming for viewers and increase bandwidth requirements.

Use speaker view for discussions

For dynamic conversations, speaker view automatically highlights whoever is talking, making it easier for viewers to follow the discussion.

Provide clear role indicators

Show badges or icons to distinguish hosts from viewers in your UI. This helps participants understand their capabilities and permissions.

Test audio levels before going live

Have all hosts join a test room first to check audio levels, eliminate echo, and verify everyone sounds clear before starting the public stream.

Implement a green room

Create a separate "backstage" area where hosts can prepare before joining the live stream. This lets them test equipment and coordinate without viewers watching.

Monitor viewer engagement

Track viewer count, watch time, and engagement metrics. Use this data to optimize show format, timing, and content.

Troubleshooting

Viewer Can't See All Hosts

  • Check that hosts have successfully published their tracks
  • Verify viewer's network can handle multiple video streams
  • Ensure layout configuration includes all active hosts
  • Check browser console for subscription errors

Promoted User Can't Publish

  • Verify camera/microphone permissions are granted
  • Check that role update event was received
  • Ensure user calls enableCamera/unmuteMicrophone after promotion
  • Verify room hasn't reached host limit (10 hosts max)

Audio Echo Between Hosts

  • Ensure all hosts use headphones, not speakers
  • Enable echo cancellation in audio config
  • Check that hosts aren't in the same physical room
  • Verify each host only has one client instance running

Hosts Out of Sync

  • This is normal - slight delays (1-2 seconds) are expected
  • For synchronized actions, use real-time messaging
  • Consider using countdown timers for coordinated events
  • Avoid hosts trying to talk simultaneously