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 liveStreamtoken: Optional authentication token for the destination liveStream. Passnilto use the current liveStream's tokenkinds: Optional array ofStreamKindto 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
- Guest Appearances: Allow popular hosts to make guest appearances in other streams without leaving their audience
- Cross-Stream Competitions: Create "battles" or competitions between hosts in different streams
- Multi-Location Broadcasting: Connect hosts from different physical locations into a shared experience
- Expert Commentary: Bring in subject matter experts to comment on events in another stream
Troubleshooting
Common Issues
-
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
-
Media Not Visible After Acceptance
- Verify network connectivity
- Check that appropriate media kinds were specified
- Ensure the host has enabled their camera/microphone
-
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

