Audience Connection

This document mainly introduces how to use the RTC Room Engine SDK to implement the audience co-guest feature.
RTC Room Engine supports the following seat management capabilities:

Prerequisites

Before using the RTC RoomEngine SDK, you need to call the SDK login to ensure the subsequent features work properly.

User Guide

Note:
When using seat management, you need to ensure that you have started broadcasting or entered the live room.

Response Configuration for Taking Seat

iOS
Android
When you are the host, you can call the updateRoomSeatModeByAdmin API to achieve this by passing the seat mode parameter seatMode.
seatMode is an enumeration of type TUISeatMode.
Enumeration value types
Meaning
freeToTake
Request to speak does not require host approval and can be done directly.
applyToTake
Request to speak requires host approval before speaking.
When you are the host, you can call the updateRoomSeatModeByAdmin API to achieve this by passing the seat mode parameter seatMode.
seatMode is an enumeration of type SeatMode.
Enumeration value types
Meaning
FREE_TO_TAKE
Request to speak does not require host approval and can be done directly.
APPLY_TO_TAKE
Request to speak requires host approval before speaking.
Taking the update of response configuration for taking seat as an example:
iOS
Android
import RTCRoomEngine

let seatMode: TUISeatMode = .applyToTake // Here, choose the apply-to-take mode. If you need to choose the free-to-take mode, change it to .freeToTake
TUIRoomEngine.sharedInstance().updateRoomSeatModeByAdmin(seatMode) {
// Successfully set response configuration for speaking
} onError: { code, message in
// Failed to set response configuration for speaking
}
TUIRoomDefine.SeatMode seatMode = TUIRoomDefine.SeatMode.APPLY_TO_TAKE; // Here, choose the apply-to-take mode. If you need to choose the free-to-take mode, change it to .freeToTake
TUIRoomEngine.sharedInstance().updateRoomSeatModeByAdmin(seatMode, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Successfully set response configuration for speaking
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to set response configuration for speaking
}
});

Get Seat List

You can call the getSeatList API to get the current seat list information.
iOS
Android
import RTCRoomEngine

TUIRoomEngine.sharedInstance().getSeatList { seatList in
// Successfully got the microphone position list
} onError: { code, messagea in
// Failed to get the microphone position list
}
TUIRoomEngine.sharedInstance().getSeatList(new TUIRoomDefine.GetSeatListCallback() {
@Override
public void onSuccess(List<TUIRoomDefine.SeatInfo> list) {
// Successfully got the microphone position list
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to get the microphone position list
}
});

Get Seat Application List

You can call the getSeatApplicationList API to get the current seat applications information.
iOS
Android
import RTCRoomEngine

TUIRoomEngine.sharedInstance().getSeatApplicationList { applications in
// Successfully got the request to speak list
} onError: { code, message in
// Failed to get the request to speak list
}
TUIRoomEngine.sharedInstance().getSeatApplicationList(new TUIRoomDefine.RequestListCallback() {
@Override
public void onSuccess(List<TUIRoomDefine.Request> list) {
// Successfully got the request to speak list
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to get the request to speak list
}
});

Take Seat

When you are not on the seat, you can call the takeSeat API to request to take seat by passing two parameters: the index of the desired seat and the timeout duration.
For example, to take seat on seat 1:
iOS
Android
import RTCRoomEngine

let index = 1 // Please replace this with the seat number you want to apply for (context: code line content)
let timeout = 30 // Please replace this with the timeout duration for your speaking request, in seconds. If set to 0, the SDK will not perform timeout detection or trigger timeout callbacks.
TUIRoomEngine.sharedInstance().takeSeat(index, timeout: TimeInterval(timeout)) { requestId, userId in
// Speaking request accepted
} onRejected: { requestId, userId, message in
// Speaking request rejected
} onCancelled: { requestId, userId in
// Speaking request canceled
} onTimeout: { requestId, userId in
// Speaking request timed out
} onError: { requestId, userId, code, message in
// Speaking request error
}
int index = 1; // Please replace this with the seat number you want to apply for (context: code line content)
int timeout = 30; // Replace this with the timeout duration for requesting to speak, in seconds. If set to 0, the SDK will not perform timeout detection or trigger timeout callbacks
TUIRoomEngine.sharedInstance().takeSeat(index, timeout, new TUIRoomDefine.RequestCallback() {
@Override
public void onAccepted(String requestId, String userId) {
// Speaking request accepted
}
@Override
public void onRejected(String requestId, String userId, String message) {
// Speaking request rejected
}
@Override
public void onCancelled(String requestId, String userId) {
// Speaking request canceled
}
@Override
public void onTimeout(String requestId, String userId) {
// Speaking request timed out
}

@Override
public void onError(String requestId, String userId, TUICommonDefine.Error error, String message) {
// Speaking request error
}
});
When you are the host, if you become an observer of the RTC Room Engine SDK through the addObserver API, you will receive the onRequestReceived callback when someone requests to speak. You can accept or reject the request through the responseRemoteRequest API.
iOS
Android
func onRequestReceived(request: TUIRequest) {
if request.requestAction == .takeSeat {
let agreeToTakeSeat = true // If you want to reject the speaking request, set this to false
TUIRoomEngine.sharedInstance().responseRemoteRequest(request.requestId, agree: agreeToTakeSeat) {
// Handle seat request successfully
} onError: { code, message in
// Handle seat request failed
}
}
}
public void onRequestReceived(TUIRoomDefine.Request request) {
if (TUIRoomDefine.RequestAction.REQUEST_TO_TAKE_SEAT == request.requestAction) {
boolean agreeToTakeSeat = true; // If you want to reject the speaking request, set this to false
TUIRoomEngine.sharedInstance().responseRemoteRequest(request.requestId, agreeToTakeSeat, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Handle seat request successfully
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Handle seat request failed
}
});
}
}

Leave Seat

When you are already on the seat, you can actively leave the seat by calling the leaveSeat API.
iOS
Android
import RTCRoomEngine

TUIRoomEngine.sharedInstance().leaveSeat {
// Left the seat successfully
} onError: { code, message in
// Failed to leave the seat
}
TUIRoomEngine.sharedInstance().leaveSeat(new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Left the seat successfully
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to leave the seat
}
});

Move Seat

When you are already on a seat, you can move a seat by calling the moveToSeat API, passing the parameter: the index of the seat you want to move to.
For example, to move to seat 2:
iOS
Android
import RTCRoomEngine

let targetIndex = 2
TUIRoomEngine.sharedInstance().moveToSeat(targetSeatIndex: targetIndex) {
// Successfully moved the seat
} onError: { code, message in
// Failed to move the seat
}
int targetIndex = 2;
TUIRoomEngine.sharedInstance().moveToSeat(targetIndex, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Successfully moved the seat
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to move the seat
}
});

Kick off seat

When you are the host, you can remove a user from a seat by calling the kickUserOffSeatByAdmin API, passing the parameter: the user ID of the user you want to remove.
For example, to remove the user with seat user ID 100001:
iOS
Android
import RTCRoomEngine

let targetIndex = -1 // Please set this value to -1, other values are meaningless
let userId = "100001" // Please replace it with the user you want to remove
TUIRoomEngine.sharedInstance().kickUserOffSeatByAdmin(targetIndex, userId: userId) {
// Successfully removed a speaker
} onError: { code, messagae in
// Failed to remove a speaker
}
int targetIndex = -1; // Please set this value to -1, other values are meaningless
String userId = "100001"; // Please replace it with the user you want to remove
TUIRoomEngine.sharedInstance().kickUserOffSeatByAdmin(targetIndex, userId, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Successfully removed a speaker
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to remove a speaker
}
});

Invite to Take Seat

When you are the host, you can call the takeUserOnSeatByAdmin API, passing three parameters: the mic seat index you want to operate, the user ID of the user you want to invite, and the timeout duration.
For example, to invite the user with user ID 100002 to mic seat 4:
iOS
Android
import RTCRoomEngine

let targetIndex = 4
let timeout = 30 // Please replace this with the timeout duration for your speaking request, in seconds. If set to 0, the SDK will not perform timeout detection or trigger timeout callbacks.
let targetUserId = "100002" // Please replace this with the user ID of the host you want to remove from the mic.
TUIRoomEngine.sharedInstance().takeUserOnSeatByAdmin(tartgetIndex,
userId: targetUserId,
timeout: TimeInterval(timeout)) { requestId, userId in
// Speaking invitation accepted
} onRejected: { requestId, userId, message in
// Speaking invitation rejected
} onCancelled: { requestId, userId in
// Seat-taking invitation timed out
} onTimeout: { requestId, userId in
// Speaking invitation canceled
} onError: { requestId, userId, code, message in
// Speaking invitation error
}
int targetIndex = 4;
int timeout = 30; // Replace this with the timeout duration for requesting to speak, in seconds. If set to 0, the SDK will not perform timeout detection or trigger timeout callbacks
String targetUserId = "100002"; // Please replace this with the user ID of the host you want to remove from the mic.
TUIRoomEngine.sharedInstance().takeUserOnSeatByAdmin(targetIndex, targetUserId, timeout, new TUIRoomDefine.RequestCallback() {
@Override
public void onAccepted(String requestId, String userId) {
// Speaking invitation accepted
}
@Override
public void onRejected(String requestId, String userId, String message) {
// Speaking invitation rejected
}
@Override
public void onCancelled(String requestId, String userId) {
// Seat-taking invitation timed out
}
@Override
public void onTimeout(String requestId, String userId) {
// Speaking invitation canceled
}
@Override
public void onError(String requestId, String userId, TUICommonDefine.Error error, String message) {
// Speaking invitation error
}
});
If you become an observer of the addObserver API in the RTC Room Engine SDK, you will receive the onRequestReceived callback when someone invites you to speak. You can call responseRemoteRequest to accept/reject the speaking invitation.
iOS
Android
func onRequestReceived(request: TUIRequest) {
if request.requestAction == .remoteUserOnSeat {
let agreeToTakeSeat = true // If you want to reject the speaking invitation, set this to false
TUIRoomEngine.sharedInstance().responseRemoteRequest(request.requestId,
agree: agreeToTakeSeat) {
// Handle seat invitation successfully
} onError: { code, message in
// Handle seat invitation failed
}
}
}
public void onRequestReceived(TUIRoomDefine.Request request) {
if (TUIRoomDefine.RequestAction.REQUEST_REMOTE_USER_ON_SEAT == request.requestAction) {
boolean agreeToTakeSeat = true; // If you want to reject the seat invitation, set this to false
TUIRoomEngine.sharedInstance().responseRemoteRequest(request.requestId, agreeToTakeSeat, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Handle seat invitation successfully
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Handle seat invitation failed
}
});
}
}

Lock Seat

iOS
Android
When you are the host and want to lock the empty seat at position 5 to prevent others from speaking, or mute the speaker at position 6 and disable the video of the speaker at position 7, you can call the lockSeat API, passing two parameters: the index of the seat to be locked and the lock mode.
The structure of the lock mode (TUISeatLockParams) is as follows:
Property Name
Field Description
Additional Notes
Data Type
Example
lockSeat
Lock Microphone Position
Locking the corresponding seat prevents applications to take that seat.
Boolean value
True when the seat is locked.
lockVideo
Lock the seat camera.
Locking the corresponding seat camera will stop the seat from publishing video streams.
Boolean value
false
lockAudio
Lock the seat microphone.
Locking the corresponding seat camera will stop the seat from publishing audio streams.
Boolean value
True when the seat microphone is locked.
When you are the host and want to lock the empty seat at position 5 to prevent others from speaking, or mute the speaker at position 6 and disable the video of the speaker at position 7, you can call the lockSeat API, passing two parameters: the index of the seat to be locked and the lock mode.
The structure of the lock mode (SeatLockParams) is as follows:
Property Name
Field Description
Additional Notes
Data Type
Example
lockSeat
Lock Microphone Position
Locking the corresponding seat prevents applications to take that seat.
Boolean value
True when the seat is locked.
lockVideo
Lock the seat camera.
Locking the corresponding seat camera will stop the seat from publishing video streams.
Boolean value
false
lockAudio
Lock the seat microphone.
Locking the corresponding seat camera will stop the seat from publishing audio streams.
Boolean value
True when the seat microphone is locked.
You can achieve the above functions by calling the lockSeatByAdmin API:
iOS
Android
import RTCRoomEngine

// Lock a seat.
let lockSeatIndex = 5
let lockSeatParam = TUISeatLockParams()
lockSeatParam.lockSeat = true
TUIRoomEngine.sharedInstance().lockSeatByAdmin(lockSeatIndex,
lockMode: lockSeatParam) {
// Lock the seat successfully
} onError: { code, message in
// Failed to lock the seat
}

// Lock the seat microphone
let lockSeatAudioIndex = 6
let lockSeatAudioParam = TUISeatLockParams()
lockSeatAudioParam.lockAudio = true
TUIRoomEngine.sharedInstance().lockSeatByAdmin(lockSeatAudioIndex,
lockMode: lockSeatAudioParam) {
// Lock the seat microphone successfully
} onError: { code, message in
// Failed to lock the seat microphone
}

// Lock the seat camera
let lockSeatVideoIndex = 7
let lockSeatVideoParam = TUISeatLockParams()
lockSeatAudioParam.lockVideo = true
TUIRoomEngine.sharedInstance().lockSeatByAdmin(lockSeatVideoIndex,
lockMode: lockSeatAudioParam) {
// Lock seat camera successfully
} onError: { code, message in
// Lock seat camera failed
}
// Lock a seat.
int lockSeatIndex = 5;
TUIRoomDefine.SeatLockParams lockSeatParam = new TUIRoomDefine.SeatLockParams();
lockSeatParam.lockSeat = true;
TUIRoomEngine.sharedInstance().lockSeatByAdmin(lockSeatIndex, lockSeatParam, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Lock the seat successfully
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to lock the seat
}
});

// Lock the seat microphone
int lockSeatAudioIndex = 6;
TUIRoomDefine.SeatLockParams lockSeatAudioParam = new TUIRoomDefine.SeatLockParams();
lockSeatAudioParam.lockAudio = true;
TUIRoomEngine.sharedInstance().lockSeatByAdmin(lockSeatAudioIndex, lockSeatAudioParam, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Lock the seat microphone successfully
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Failed to lock the seat microphone
}
});

// Lock the seat camera
int lockSeatVideoIndex = 7;
TUIRoomDefine.SeatLockParams lockSeatVideoParam = new TUIRoomDefine.SeatLockParams();
lockSeatAudioParam.lockVideo = true;
TUIRoomEngine.sharedInstance().lockSeatByAdmin(lockSeatVideoIndex, lockSeatAudioParam, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
// Lock seat camera successfully
}
@Override
public void onError(TUICommonDefine.Error error, String message) {
// Lock seat camera failed
}
});

Listening to Callbacks

iOS
Android
You can become an observer of the RTC Room Engine SDK by calling addObserver to listen for seat-related callbacks.
Take CoGuestController as an example to become an observer:
import RTCRoomEngine

class CoGuestController: NSObject, TUIRoomObserver { // Please replace it with your business class, this is just an example
override init() {
super.init()
TUIRoomEngine.sharedInstance().addObserver(self)
}
deinit {
TUIRoomEngine.sharedInstance().removeObserver(self)
}
// Triggered when the room mic mode changes
func onRoomSeatModeChanged(roomId: String, seatMode: TUISeatMode) {
// Room seat mode changed, current mode: seatMode
}
// Triggered when the mic list changes
func onSeatListChanged(seatList: [TUISeatInfo], seated seatedList: [TUISeatInfo], left leftList: [TUISeatInfo]) {
// Microphone position list changed, latest user list on mic: seatList, newly seated user list: seatedList, newly left user list: leftList
}
// Triggered when a request from another user is received
func onRequestReceived(request: TUIRequest) {
switch request.requestAction {
case .takeSeat:
// Received a seat request from request.userName
case .remoteUserOnSeat:
// Received a seat invitation from request.userName
default:
break
}
}
// Triggered when another user cancels the request
func onRequestCancelled(request: TUIRequest, operateUser: TUIUserInfo) {
switch request.requestAction {
case .takeSeat:
// Seat request from request.userName was canceled
case .remoteUserOnSeat:
// Seat invitation from request.userName was canceled
default:
break
}
}

// Triggered when the request is handled by another admin/room owner
func onRequestProcessed(request: TUIRequest, operateUser: TUIUserInfo) {
switch request.requestAction {
case .takeSeat:
// Seat request from request.userName was handled by operateUser.userName
case .remoteUserOnSeat:
// Seat invitation from request.userName was handled by operateUser.userName
default:
break
}
}
}
You can become an observer of the RTC Room Engine SDK by calling addObserver to listen for seat-related callbacks.
Take CoGuestObserver as an example to become an observer:
class CoGuestObserver extends TUIRoomObserver { // Please replace it with your business class, this is just an example

CoGuestObserver() {
TUIRoomEngine.sharedInstance().addObserver(this);
}

// Triggered when the room mic mode changes
@Override
public void onRoomSeatModeChanged(String roomId, TUIRoomDefine.SeatMode seatMode) {
// Room seat mode changed, current mode: seatMode
}
// Triggered when the mic list changes
@Override
public void onSeatListChanged(List<TUIRoomDefine.SeatInfo> seatList, List<TUIRoomDefine.SeatInfo> seatedList,
List<TUIRoomDefine.SeatInfo> leftList) {
// Microphone position list changed, latest user list on mic: seatList, newly seated user list: seatedList, newly left user list: leftList
}
// Triggered when a request from another user is received
@Override
public void onRequestReceived(TUIRoomDefine.Request request) {
switch (request.requestAction) {
case REQUEST_TO_TAKE_SEAT:
// Received a seat request from request.userName
case REQUEST_REMOTE_USER_ON_SEAT:
// Received a seat invitation from request.userName
default:
break;
}
}
// Triggered when another user cancels the request
@Override
public void onRequestCancelled(TUIRoomDefine.Request request, TUIRoomDefine.UserInfo operateUser) {
switch (request.requestAction) {
case REQUEST_TO_TAKE_SEAT:
// Seat request from request.userName was canceled
case REQUEST_REMOTE_USER_ON_SEAT:
// Seat invitation from request.userName was canceled
default:
break;
}
}

// Triggered when the request is handled by another admin/room owner
@Override
public void onRequestProcessed(TUIRoomDefine.Request request, TUIRoomDefine.UserInfo operateUser) {
switch (request.requestAction) {
case REQUEST_TO_TAKE_SEAT:
// Seat request from request.userName was handled by operateUser.userName
case REQUEST_REMOTE_USER_ON_SEAT:
// Seat invitation from request.userName was handled by operateUser.userName
default:
break;
}
}
}