

# Enabling Multiple Hosts on an Amazon IVS Stream
<a name="multiple-hosts"></a>

Amazon Interactive Video Service (IVS) enables developers to build applications that combine video and audio from multiple broadcasters (also referred to as *hosts*) into one live stream.

Use cases include:
+ Guest spots – Broadcasters can invite viewers into the broadcast. This opens the door to collaborative content like karaoke and Q&A.
+ Versus (VS) mode – Broadcasters are matched with each other to compete (e.g., in a singing competition).
+ Group broadcasts – Multiple speakers can converse with each other in front of a large audience.

To add multiple broadcasters to a live stream, you need to use both IVS Real-Time Streaming and IVS Low-Latency Streaming. IVS Real-Time Streaming is used to combine video and audio streams; Low-Latency Streaming, to broadcast the combined stream to viewers.

Real-Time Streaming provides a resource called a stage, a virtual space where broadcasters (hosts) can exchange audio and video in real time. You can then broadcast a stage to channels to reach a larger audience, and you can build applications where audience members can be brought "on stage" to contribute to the live conversation.

For more information about IVS Real-Time Streaming, see:
+ [IVS Real-Time Streaming User Guide](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/what-is.html)
  + The IVS Broadcast SDKs incorporate real-time functionality. See the Guides for those SDKs: [Web](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/broadcast-web.html), [Android](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/broadcast-android.html), and [iOS](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/broadcast-ios.html), especially the sections on "Publishing and Subscribing." 
+  [IVS Real-Time Streaming API Reference](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/Welcome.html)

# Getting Started with Multiple Hosts in IVS
<a name="multiple-hosts-getting-started"></a>

This document takes you through the steps involved in getting started using multiple hosts in Amazon IVS.

## Console Instructions
<a name="multiple-hosts-setup-console"></a>

To create a new stage and a participant token for it, follow these steps:

1. Open the [Amazon IVS console](https://console.aws.amazon.com/ivs).

   (You can also access the Amazon IVS console through the [AWS Management Console](https://console.aws.amazon.com).)

1. On the left navigation pane, select **Stages**, then select **Create stage**. The **Create stage** window appears.  
![\[Use the Create stage window to create a new stage and a participant token for it.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Create_Stage_Console_IPR.png)

1. Optionally enter a **Stage name**. Select **Create stage** to create the stage. The stage details page appears, for the new stage.

1. Select **Create a participant token**.

1. In the **Create a participant token** dialog, enter a User ID and select **Create a participant token**. The token appears at the top of the **Participant tokens** table. Click the "Copy token" icon (to the left of the participant token) to copy the token.

## CLI Instructions
<a name="multiple-hosts-setup-cli"></a>

Using the AWS CLI is an advanced option and requires that you first download and configure the CLI on your machine. For details, see the [AWS Command Line Interface User Guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html).

Now you can use the CLI to create and manage resources. The stage API is under the ivs-realtime namespace. For example, to create a stage:

```
aws ivs-realtime create-stage --name "test-stage"
```

The response is:

```
{
   "stage": {
      "arn": "arn:aws:ivs:us-west-2:376666121854:stage/VSWjvX5XOkU3",
      "name": "test-stage"
   }
}
```

To create a participant token for that stage:

```
aws ivs-realtime create-participant-token --stage-arn arn:aws:ivs:us-west-2:376666121854:stage/VSWjvX5XOkU3
```

The response is:

```
{
   "participant": {
      "participantId": "jFpWmveENolS",
      "expirationTime": "2022-08-26T19:17:00+00:00",
      "token": "eyJhbGciOiJLTVMiLCJ0eXAiOiJKV1QifQ.eyJleHAiOjE2NjE1NDE0MjAsImp0aSI6ImpGcFdtdmVFTm9sUyIsInJlc291cmNlIjoiYXJuOmF3czppdnM6dXMtd2VzdC0yOjM3NjY2NjEyMTg1NDpzdGFnZS9NbzhPUWJ0RGpS123JldmVudHNfdXJsIjoid3NzOi8vdXMtd2VzdC0yLmV2ZW50cy5saXZlLXZpZGVvLm5ldCIsIndoaXBfdXJsIjoiaHR0cHM6Ly82NmY3NjVhYzgzNzcuZ2xvYmFsLndoaXAubGl2ZS12aWRlby5uZXQiLCJjYXBhYmlsaXRpZXMiOnsiYWxsb3dfcHVibGlzaCI6dHJ1ZSwiYWxsb3dfc3Vic2NyaWJlIjp0cnVlfX0.MGQCMGm9affqE3B2MAb_DSpEm0XEv25hfNNhYn5Um4U37FTpmdc3QzQKTKGF90swHqVrDgIwcHHHIDY3c9eanHyQmcKskR1hobD0Q9QK_GQETMQS54S-TaKjllW9Qac6c5xBrdAk"
   }
}
```

# Broadcasting a Stage: Client-Side versus Server-Side Composition
<a name="multiple-hosts-broadcasting-client-vs-server"></a>

When developers want to broadcast a stage to an IVS channel, they have two choices:
+ With *client-side composition*, a host connects to a stage, downloads videos from other hosts, combines them into one stream, and broadcasts the mixed stream to an IVS channel. This approach allows for a high degree of layout flexibility: the app developer can control the look of the composition using the mixer API. However, client-side composition requires more client CPU resources to create the composition and more bandwidth to broadcast it. Also, if the host broadcasting the stage has network issues, they may impact the live stream for viewers.

  Client-side composition is the preferred choice when users need a highly personalized view of the broadcast content, such as incorporating overlays and customizing elements that aren't compatible with server-side composition.
+ With *server-side composition*, clients offload the composition and broadcasting of an IVS stage to a cloud service. Server-side composition and RTMP broadcast to a channel are invoked through IVS control-plane operations in the stage’s home region. Server-side composition offers numerous benefits, making it an attractive choice for users seeking efficient and reliable live streaming.
  + **Reduced client load** — With server-side composition, the burden of combining audio and video sources is shifted from individual client devices to the server itself. Server-side composition eliminates the need for client devices to use their CPU and network resources for compositing the view and transmitting it to IVS.
  + **Resilience** — By centralizing the composition process on the server, the broadcast becomes more robust. Even if a publisher device experiences technical limitations or network fluctuations, the server can adapt and provide a smoother stream to all the audience.
  + **Bandwidth efficiency** — Since the server handles the composition, stage publishers do not have to spend extra bandwidth broadcasting the video to an IVS channel.

For more information, see [Server-Side Composition](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/server-side-composition.html) in the *IVS Real-Time User Guide*.

# Demo of Multiple Hosts in IVS
<a name="multiple-hosts-demo"></a>

Scenario: Alice (A) is broadcasting to her Amazon IVS channel and wants to invite Bob (B) on stage as a guest. (In a real broadcast, A and B would be images of Alice and Bob.)

![\[Demo Scenario: Alice (A) is broadcasting to her Amazon IVS channel and wants to invite Bob (B) on stage as a guest.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Demo_Intro.png)


## 1. Create a Stage
<a name="multiple-hosts-demo-create-stage"></a>

Here is a [CreateStage](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_CreateStage.html) request using the Amazon IVS Stage API:

```
POST /CreateStage HTTP/1.1
Content-type: application/json
{
   "name": "string",
   "participantTokenConfigurations": [
      {
         "userId": "9529828585",
         "attributes": {"displayName": "Alice"}
      },
      {
         "userId": "4875935192",
         "attributes": {"displayName": "Bob"}
      }
   ]
}
```

You can pre-create participant tokens when you create a stage, as is done here. You also can create tokens for an existing stage, by calling [CreateParticipantToken](https://docs.aws.amazon.com//ivs/latest/RealTimeAPIReference/API_CreateParticipantToken.html). For each participant, you can pass in a custom `userId` and set of `attributes`. (**Important**: The `attributes` and `userId` request fields are exposed to all stage participants. These should not be used for personally identifying, confidential, or sensitive information.)

Here is the network response to the request above:

```
HTTP/1.1 200
Content-type: application/json
{
   "stage": {
      "arn": "arn:aws:ivs:us-west-2:123456789012:stage/abcdABCDefgh",
      "name": "alice-stage"
   },
   "participantTokens": [
      {
         "participantId": "e94e506e-f7...",
         "token": "eyJhbGci0iJ...",
         "userId": "9529828585",
         "attributes": {"displayName" : "Alice"},
         "expirationTime": number
      },
      {
         "participantId": "b5c6a79a-6e...",
         "token": "eyJhbGci0iJ...",
         "userId": "4875935192",
         "attributes": {"displayName" : "Bob"},
         "expirationTime": number
      }
   ]
}
```

## 2. Distribute Participant Tokens
<a name="multiple-hosts-demo-distribute-tokens"></a>

The client now has a token for Alice (A) and Bob (B). By default, tokens are valid for 1 hour; optionally you can pass in a custom `duration` when you create the stage. Tokens can be used to join a stage. 

![\[How to distribute tokens from your server to each client (e.g., via a WebSocket channel). We do not provide this functionality.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Demo_Distribute_Participant_Token_crop.png)


You will need a way to distribute tokens from your server to each client (e.g., via a WebSocket channel). We do not provide this functionality.

## 3. Join the Stage
<a name="multiple-hosts-demo-join-stage"></a>

Participants can join the stage via the Amazon IVS Broadcast SDK on Android or iOS. You can configure the video quality of each participant. Here we show Alice joining the stage first.

Here is an architecture overview:

![\[Participants can join the stage via the Amazon Broadcast SDK on Android or iOS. Here we show Alice joining the stage first.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Demo_Join_the_Stage_crop.png)


And here is an Android code sample for joining the stage. The code snippet below would run on Alice's device. In the `join()` call, Alice joins the stage. The figure above shows the result of this code execution: Alice has joined the stage and is publishing to it (in addition to broadcasting to her channel, which she started doing in step 1).

```
// Create streams with the front camera and first microphone.
var deviceDiscovery = DeviceDiscovery(context)
var devices : List<Device> = deviceDiscovery.listLocalDevices()
var publishStreams = ArrayList<LocalStageStream>()

// Configure video quality if desired
var videoConfiguration = StageVideoConfiguration()

// Create front camera stream
var frontCamera = devices.find { it.descriptor.type == Device.Descriptor.DeviceType.Camera && it.descriptor.position == Device.Descriptor.Position.FRONT }
var cameraStream = ImageLocalStageStream(frontCamera, videoConfiguration)
publishStreams.add(cameraStream)

// Create first microphone stream
var microphone = devices.find { it.descriptor.type == Device.Descriptor.DeviceType.Microphone }
var microphoneStream = AudioLocalStageStream(microphone)
publishStreams.add(microphoneStream)

// A basic Stage.Strategy implementation that indicates the user always wants to publish and subscribe to other participants.
// Provides the front camera and first microphone as publish streams.

override fun shouldPublishFromParticipant(stage: Stage, participantInfo: ParticipantInfo) : Boolean {
   return true
}

override fun shouldSubscribeToParticipant(stage: Stage, participantInfo: ParticipantInfo) : Stage.SubscribeType {
   return Stage.SubscribeType.AUDIO_VIDEO
}

override fun stageStreamsToPublishForParticipant(stage: Stage, participantInfo: ParticipantInfo): List<LocalStageStream> {
   return publishStreams
}

// Create Stage using the strategy and join
var stage = Stage(context, token, strategy)

try {
   stage.join()
} catch (exception: BroadcastException) {
   // handle join exception
}
```

## 4. Broadcast the Stage
<a name="multiple-hosts-demo-broadcast-stage"></a>

### Client-Side Composition
<a name="demo-broadcast-stage-client-side"></a>

![\[Broadcasting the stage: client-side composition.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Demo_Broadcast_the_Stage_Client_Side_Composition_1_crop.png)


Here is an Android code sample for broadcasting the stage:

```
var broadcastSession = BroadcastSession(context, broadcastListener, configuration, null)

// StageRenderer interface method to be notified when remote streams are available
override fun onStreamsAdded(stage: Stage, participantInfo: ParticipantInfo, streams: List<StageStream>) {

   var id = participantInfo.participantId
	
   // Create mixer slot for remote participant
   var slot = BroadcastConfiguration.Mixer.Slot.with { s ->
      s.name = id
      // Set other properties as desired
      ...
      s
   }

   broadcastSession.mixer.addSlot(slot)

   // Attach remote stream devices, bind to mixer slot
   streams.forEach { stream ->
      broadcastSession.attachDevice(stream.getDevice())
      broadcastSession.mixer.bind(stream.getDevice(), id)
   }
}

// Start broadcasting
try {
   broadcastSession.start(IVS_RTMPS_URL, IVS_STREAM_KEY)
} catch (exception: BroadcastException) {
   // handle exception
}
```

The Android and iOS Amazon IVS Broadcast SDKs have callbacks triggered by the status of participants (e.g., `onStreamsAdded` and `onStreamsRemoved`), to simplify building a dynamic UI. This is shown in the first part of the code sample: when Bob’s video and audio are available, Alice is notified via an `onStreamsAdded` callback.

Alice can then add Bob’s video and audio to the mixer, to be included in the RTMP broadcast for the wider audience of her channel. This is shown in the remainder of the code sample.

Now Alice is broadcasting to multiple viewers, via the Amazon IVS Android Broadcast SDK. Here is what this looks like architecturally:

![\[Broadcasting the stage: client-side composition. Alice is broadcasting to multiple viewers.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Demo_Broadcast_the_Stage_Client_Side_Composition_2_crop.png)


### Server-Side Composition
<a name="demo-broadcast-stage-server-side"></a>

For comparison, here is how [server-side composition](multiple-hosts-broadcasting-client-vs-server.md) works. (For details, see [Server-Side Composition](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/server-side-composition.html) in the *IVS Real-Time User Guide*.)

![\[Broadcasting the stage: server-side composition.\]](http://docs.aws.amazon.com/ivs/latest/LowLatencyUserGuide/images/Demo_Broadcast_the_Stage_Server_Side_Composition.png)
