# Cross-channel media stream relay (/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

Some special use-cases require cross-channel media stream forwarding functionality. Video SDK enables you to relay the media stream of a host, from a source channel, to multiple target channels simultaneously. This functionality allows you to realize the following interactions:

* The hosts publish and receive each other's audio and video streams while engaging in *cross-channel* real-time interaction.

* The audience receive all audio and video streams from hosts and watch multiple hosts interact at the same time.

Due to its real-time and interactive nature, this feature enriches live broadcasts and game-play, It is especially suitable for live scenes such as co-hosting PK and online choir. It provides the audience with a better viewing experience, while bringing more traffic and revenue to the hosts.


      
<CalloutContainer type="info">
  <CalloutDescription>
    Cross-channel media stream relay is included in Agora's policy of [10,000 free minutes](/en/api-reference/faq/account/billing_free) every month. For usage beyond the free quota, please refer to [Pricing](/en/realtime-media/interactive-live-streaming/reference/pricing).
  </CalloutDescription>
</CalloutContainer>

## Prerequisites

* Ensure that you have implemented the [SDK quickstart](../../quickstart.mdx) in your project.
* Contact [technical support](https://agora-ticket.agora.io/) to activate the cross-channel media stream relay feature.

## Implement cross-channel media stream relay

The following figure shows the workflow you implement to facilitate cross-channel media stream relay:

![CrossChannelMediaStreamForwarding](https://assets-docs.agora.io/images/video-sdk/cross-channel-forwarding.svg)

To implement cross-channel media stream relay in your app, take the following steps:

1. Start cross-channel media stream relay

After joining a channel, call `startOrUpdateChannelMediaRelay` to configure the source and target channel information and start forwarding a media stream.

```java
// Configure source channel information
ChannelMediaInfo srcChannelInfo = new ChannelMediaInfo(et_channel.getText().toString(), null, myUid);
ChannelMediaRelayConfiguration mediaRelayConfiguration = new ChannelMediaRelayConfiguration();
mediaRelayConfiguration.setSrcChannelInfo(srcChannelInfo);
// Configure target channel information
ChannelMediaInfo destChannelInfo = new ChannelMediaInfo(destChannelName, null, myUid);
mediaRelayConfiguration.setDestChannelInfo(destChannelName, destChannelInfo);
// Start cross-channel media stream relay
engine.startOrUpdateChannelMediaRelay(mediaRelayConfiguration);
```

<CalloutContainer type="info">
  <CalloutDescription>
    * Best practice is to set the UID of the source channel to `0`, allowing the SDK to assign a random UID.
      * The source channel token in `srcChannelInfo` should be different from the one used when joining the source channel. Generate a new token using the source channel name and `uid = 0`.
      * For the destination channel, set the uid to `0`, to allow the SDK to assign a random `uid`, or specify a `uid`, ensuring that it is different from all UIDs in the target channel.
  </CalloutDescription>
</CalloutContainer>

2. Update media stream relay channels

To forward the stream to multiple target channels or exit the current forwarding channel after staring channel media relay, call `startOrUpdateChannelMediaRelay` again to add or remove target channels for forwarding.

<CalloutContainer type="info">
  <CalloutDescription>
    The updated configuration completely **replaces** the previous configuration.
  </CalloutDescription>
</CalloutContainer>

3. Pause or resume media stream relay

To pause forwarding the media stream to all target channels, call `pauseAllChannelMediaRelay`.

```java
engine.pauseAllChannelMediaRelay();
isPaused = true;
pause.setText(R.string.resume);
```

To resume forwarding the media stream to all target channels, call `resumeAllChannelMediaRelay`.

```java
engine.resumeAllChannelMediaRelay();
isPaused = false;
pause.setText(R.string.pause);
```

4. Stop cross-channel media stream relay

To stop forwarding the media stream, call `stopChannelMediaRelay`. When forwarding stops, the host exits all target channels.

```java
engine.stopChannelMediaRelay();
et_channel_ex.setEnabled(true);
pause.setEnabled(false);
join_ex.setText(getString(R.string.join));
mediaRelaying = false;
```

<CalloutContainer type="info">
  <CalloutDescription>
    If this method fails, call `leaveChannel` to leave the channel and stop cross-channel media stream relay.
  </CalloutDescription>
</CalloutContainer>

5. Monitor cross-channel media stream status

During cross-channel media stream relay, the SDK reports changes in the status of media stream relay through the `onChannelMediaRelayStateChanged` callback. Implement the relevant business logic based on the [status codes](#status-codes).

```java
public void onChannelMediaRelayStateChanged(int state, int code) {
  switch (state) {
    case RELAY_STATE_CONNECTING:
      mediaRelaying = true;
      handler.post(() -> {
        et_channel_ex.setEnabled(false);
        join_ex.setEnabled(true);
        join_ex.setText(getText(R.string.stop));
        showLongToast("channel media Relay connected.");
      });
      break;
    case RELAY_STATE_FAILURE:
      mediaRelaying = false;
      handler.post(() -> {
        showLongToast(String.format("channel media Relay failed at error code: %d", code));
      });
    default:
      break;
  }
}
```

### Development considerations

* In live broadcast use cases, only users with the role of host can call `startOrUpdateChannelMediaRelay` to initiate cross-channel media stream forwarding.

* Call `startOrUpdateChannelMediaRelay` **after** successfully joining a channel; otherwise, the method call fails.

* Within a single channel, multiple hosts can forward media streams. Each host can forward a media stream to up to six target channels.

* This feature does not support String-type `uid`. To use cross-channel co-hosting, you must also use an int-type `uid` in regular co-hosting. Otherwise, cross-channel co-hosting will not work.

## Reference

This section contains content that completes the information on this page, or points you to documentation that explains other aspects to this product.

### Status codes

The main media stream forwarding states and their corresponding status codes are as follows:

| Media stream forwarding status                                                                                                                                                                                                                                                | status code                                |
| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------- |
| The source channel starts transmitting data to the target channel.                                                                                                                                                                                                            | `RELAY_STATE_RUNNING`(2) and `RELAY_OK`(0) |
| Cross-channel media stream forwarding encounters an exception. You can troubleshoot based on the [error code](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_irtcengineeventhandler.html#callback_irtcengineeventhandler_onchannelmediarelaystatechanged__code). | `RELAY_STATE_FAILURE`(3)                   |
| Media stream forwarding has stopped.                                                                                                                                                                                                                                          | `RELAY_STATE_IDLE`(0) and `RELAY_OK`(0)    |

### Sample project

Agora provides an open-source [HostAcrossChannels](https://github.com/AgoraIO/API-Examples/blob/main/Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/HostAcrossChannel.java) sample project for your reference. Download the project or view the source code for a more detailed example.

### API reference

* [`startOrUpdateChannelMediaRelay`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_irtcengine.html#api_irtcengine_startorupdatechannelmediarelay)
* [`stopChannelMediaRelay`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_irtcengine.html#api_irtcengine_stopchannelmediarelay)
* [`pauseAllChannelMediaRelay`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_irtcengine.html#api_irtcengine_pauseallchannelmediarelay)
* [`resumeAllChannelMediaRelay`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_irtcengine.html#api_irtcengine_resumeallchannelmediarelay)
* [`onChannelMediaRelayStateChanged`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_irtcengineeventhandler.html#callback_irtcengineeventhandler_onchannelmediarelaystatechanged)
* [`ChannelMediaRelayConfiguration`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_channelmediarelayconfiguration.html)
* [`ChannelMediaInfo`](https://api-ref.agora.io/en/video-sdk/android/4.x/API/class_channelmediainfo.html)

    
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  


## Platform-specific versions
- [Android](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/android.md)
- [iOS](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/ios.md)
- [macOS](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/macos.md)
- [Web](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/web.md)
- [Windows](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/windows.md)
- [Electron](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/electron.md)
- [Flutter](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/flutter.md)
- [React Native](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/react-native.md)
- [Unity](/en/realtime-media/interactive-live-streaming/build/connect-across-channels/cross-channel-media-relay/unity.md)
