Skip to main content
Version: 4.x.x

Relay Media(PK Host) - iOS

Overview​

The Relay Media feature enables hosts to relay their media (audio, video, screen share) to one or multiple other live streams. This creates cross-stream interactions similar to "PK battles" or collaborative broadcasts.

This feature allows audiences in one live stream to view and hear hosts from another live stream without changing rooms.

Key Concepts​

  • Media Relay: The process of transmitting a host's audio/video from one live stream to another
  • Source Room: The original live stream where the host is broadcasting
  • Destination Room: The target live stream(s) where the host's media will be relayed
  • Relay Kinds: The types of media that can be relayed (video, audio, screen share, etc.)

Sequence Diagram​

Implementation Guide​

1. Requesting Media Relay​

requestMediaRelay()​

Parameters:

  • destinationRoomId: ID of the target liveStream
  • token: Optional authentication token for the destination liveStream. Pass nil to use the current liveStream's token
  • kinds : Optional array of StreamKind to relay. If you leave it out (nil), audio, video and share are all relayed. Supported values:
    • .VIDEO: Camera video
    • .AUDIO: Microphone audio
    • .SHARE: Screen share video

requestMediaRelay() is async throws, so call it with try await after you join the live stream. If the request fails, for example because destinationRoomId is empty or you have not joined yet, it throws a VideoSDKError.

@IBAction func requestRelayBtn(_ sender: UIButton) {
Task {
do {
try await room?.requestMediaRelay(destinationRoomId: "abc123", token: "YOUR_TOKEN_HERE", kinds: [.AUDIO, .VIDEO])
} catch {
print("Failed to request media relay: \(error)")
}
}
}

2. Handling Relay Requests (Destination Room)​

In the destination liveStream, hosts (participants with SEND_AND_RECV mode) will receive relay requests:

extension LiveStreamViewController: RoomEventListener {

func onMediaRelayRequestReceived(participantId: String, roomId: String, displayName: String, accept: @escaping () -> Void, reject: @escaping () -> Void) {

guard let viewController = getTopViewController() else {
return
}

let alert = UIAlertController(
title: "Media Relay Request",
message: "\(displayName) requested a media relay from \(roomId). Allow?",
preferredStyle: .alert
)

let acceptAction = UIAlertAction(title: "Accept", style: .default) { _ in
accept()
}

let declineAction = UIAlertAction(title: "Decline", style: .destructive) { _ in
reject()
}

alert.addAction(acceptAction)
alert.addAction(declineAction)

DispatchQueue.main.async {
viewController.present(alert, animated: true)
}

}
}

3. Handling Request Responses (Source Room)​

In the source liveStream, track the response to your relay requests:


extension LiveStreamViewController: RoomEventListener {

func onMediaRelayRequestResponse(decision: RelayDecision?, decidedBy: String, roomId: String) {
print("onMediaRelayRequestResponse: \(String(describing: decision)), \(decidedBy), \(roomId)")
}

}

4. Tracking Active Relays​

When a relay successfully starts:

extension LiveStreamViewController: RoomEventListener {

func onMediaRelayStarted(roomId: String) {
print("onMediaRelayStarted: \(roomId)")
}

}

5. Stopping Media Relay​

To stop an ongoing relay:

stopMediaRelay()​

Parameters:

  • destinationRoomId (String): ID of the liveStream where the relay should stop

stopMediaRelay() is also async throws, so call it with try await.

@IBAction func stopMediaRelayBtn(_ sender: UIButton) {
Task {
do {
try await room?.stopMediaRelay(destinationRoomId: "abc123")
} catch {
print("Failed to stop media relay: \(error)")
}
}
}

6. Handling Relay Stop Events​

When a relay stops for any reason. reason is nil when the server sends none:


extension LiveStreamViewController: RoomEventListener {

func onMediaRelayStopped(roomId: String, reason: String?) {
print("onMediaRelayStopped: \(roomId), reason: \(reason ?? "none")")
}

}

Use Cases​

  1. Guest Appearances: Allow popular hosts to make guest appearances in other streams without leaving their audience
  2. Cross-Stream Competitions: Create "battles" or competitions between hosts in different streams
  3. Multi-Location Broadcasting: Connect hosts from different physical locations into a shared experience
  4. Expert Commentary: Bring in subject matter experts to comment on events in another stream

Troubleshooting​

Common Issues​

  1. Relay Request Not Received

    • Verify both rooms are active
    • Check that destination liveStream ID is correct
    • Ensure the token has proper permissions
    • Check whether requestMediaRelay() threw an error
  2. Media Not Visible After Acceptance

    • Verify network connectivity
    • Check that appropriate media kinds were specified
    • Ensure the host has enabled their camera/microphone
  3. Unexpected Relay Termination

    • Check for network connectivity issues
    • Verify that both rooms remain active
    • Listen for onMediaRelayStopped(roomId:reason:) to know when a relay ends

API Reference​

Got a Question? Ask us on discord