Audience Connection

功能介绍

观众连麦功能‌是一种实时互动交流方式,通过观众连麦功能,主播可以与多达9个观众进行实时互动,无论是解答问题、分享经验还是进行娱乐互动,都能极大地提升观众的参与感满意度。这种直接的互动和交流为商业化运营提供了更加便捷和高效的渠道,同时也为观众提供了更加个性化和定制化的购物体验。观众连麦功能适用于多个场景,包括电商直播、娱乐直播、在线教学等。
单人连麦
多人连麦







使用说明

说明:
此说明介绍在TUILiveKit中的观众连麦功能使用说明,如您未使用TUILIveKit而直接使用了LIveCoreViewRTCRoomEngine,可忽略此步骤,直接跳转至接入流程或相应的API文档。

观众发起连麦申请

点击连麦请求按钮
选择连麦方式
发送连麦请求,等待主播同意
主播同意后,连麦成功













主播处理观众连麦请求

收到观众的连麦请求
点击连麦用户,打开连麦面板
点击同意后,连麦成功










接入流程

观众连麦流程

TUILiveKit 观众连麦功能 主要是通过 LiveCoreView 实现(除Flutter),您可以调用如下 API 函数,实现观众连麦功能。以观众 B 申请和主播 A 连麦为例实现如下。
说明:
以下是由 LiveCoreView 提供的主动调用方法。
所有的回调方法是指 LiveCoreView 设置的 ConnectionObserver 对象中的回调方法。
在Flutter TUILiveKit中,观众连麦功能直接通过RTCRoomEngine实现。以下所有Flutter相关内容在是TUILiveKit中,调用由RTCRoomEngine提供的方法以实现对应功能供您参考。

观众发送连麦请求

观众 B 给主播 A 发送连麦请求。
Android
iOS
Flutter
Kotlin
Java
val userId = "anchorUserId"; // 修改为房主的UserId,传入空字符串时默认为房主UserId
val timeout = 60;
liveCoreView.requestIntraRoomConnection(userId, 10, null)
String userId = "anchorUserId"; // 修改为房主的UserId,传入空字符串时默认为房主UserId
int timeout = 60;
liveCoreView.requestIntraRoomConnection(userId, timeout, true, null);
Swift
OC
let timeout = 60
let userId = "anchorUserId" // 修改为房主的UserId,传入空字符串时默认为房主UserId
liveCoreView.requestIntraRoomConnection(userId: "", timeOut: timeOut, openCamera: true) {
} onError: { code, message in
}
NSInteger timeout = 60;
NSString userId = "anchorUserId" // 修改为房主的UserId,传入空字符串时默认为房主UserId
[liveCoreView requestIntraRoomConnection:""
timeOut:timeout
onSuccess:^(void) {
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];
Dart
// 文件位置:Flutter/lib/service/impl/room_engine_service.dart

@override
TUIRequest takeSeat(int seatIndex, int timeout, TUIRequestCallback? requestCallback) {
return roomEngine.takeSeat(seatIndex, timeout, requestCallback);
}

主播端收到连麦请求

主播 A 会在 onUserConnectionRequest 回调方法中收到 观众B 的连麦请求。
Android
iOS
Flutter
Kotlin
Java
override fun onUserConnectionRequest(inviterUser: UserInfo) {
Log.i(TAG, "收到观众连线请求:${inviterUser.userId}")
}
@Override
public void onUserConnectionRequest(LiveStreamDefine.LiveUser inviterUser) {
Log.i(TAG, "收到观众连线请求:" + inviterUser.userId);
}
Swift
OC
func onUserConnectionRequest(inviterUser: TUIUserInfo) {
print("收到观众连线请求:\(inviterUser.userId)")
}
- (void)onUserConnectionRequest:(TUIUserInfo *)inviterUser {
NSLog(@"收到观众连线请求:%@", hostUser.userId);
}
在Flutter中,主播 A 会在RTCRoomEngineonRequestReceived回调中收到观众 B 的连麦请求。
Dart
// 文件位置:Flutter/lib/manager/observer/live_observer.dart

super.onRequestReceived = (request) {
LiveKitLogger.info("$tag onRequestReceived:[request:$request");
liveController.seatController.onRequestReceived(request);
};

主播响应连麦请求

主播 A 收到观众的连麦请求后,可以调用 respondIntraRoomConnection 响应观众 B 是否同意连麦。
Android
iOS
Flutter
Kotlin
Java
// 主播同意连麦
liveCoreView.respondIntraRoomConnection(audienceBUserId, true, null)
// 主播同意连麦
liveCoreView.respondIntraRoomConnection(userId, true, null);

// 主播拒绝连麦
liveCoreView.respondIntraRoomConnection(userId, false, null);
Swift
OC
// 主播同意连麦
liveCoreView.respondIntraRoomConnection(userId: audienceBUserId, isAccepted: true) {
} onError: { code, message in
}
// 主播同意连麦
[liveCoreView respondIntraRoomConnection:audienceBUserId
isAccepted:YES
onSuccess:^(void) {
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];
Dart
// 文件位置:Flutter/lib/service/impl/room_engine_service.dart

mTUIRoomEngine.responseRemoteRequest(requestId, true, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {}

@Override
public void onError(TUICommonDefine.Error error, String message) {}
});

观众收到主播响应回调

主播 A 同意观众 B 连麦请求后, 观众 B 会通过 onUserConnectionAccepted 回调收到主播 A 同意连麦的回调。
Android
iOS
Flutter
Kotlin
Java
override fun onUserConnectionAccepted(inviterUser: UserInfo) {
Log.i(TAG, "观众同意连线:${inviterUser.userId}")
}
@Override
public void onUserConnectionAccepted(LiveStreamDefine.LiveUser liveUser) {
Log.i(TAG, "观众同意连线:" + liveUser.userId);
}

@Override
public void onUserConnectionRejected(LiveStreamDefine.LiveUser liveUser) {
Log.i(TAG, "观众拒绝连线:" + liveUser.userId);
}
Swift
OC
func onUserConnectionAccepted(userId: String) {
print("观众同意连线:\(userId)")
}
- (void)onUserConnectionAccepted:(NSString *)userId {
NSLog(@"观众同意连线:%@", userId);
}
在Flutter中,观众收到主播响应连麦申请的回调由takeSeat接口中的requestCallback给出。具体示例可以参考以下代码:
// 文件位置:Flutter/lib/manager/controller/seat_controller.dart

TUIRequest request = liveService.takeSeat(
index,
timeout,
TUIRequestCallback(
onAccepted: (String requestId, String userId) { // 连麦申请被同意
},
onRejected: (String requestId, String userId, String message) { // 连麦申请被拒绝
},
onCancelled: (String requestId, String userId) { // 连麦申请取消
},
onTimeout: (String requestId, String userId) { // 连麦申请超时
},
onError: (String requestId, String userId, TUIError error, String message) { // 错误回调
},
));

连麦用户列表发生变化的回调

主播 A 同意观众 B 连麦请求后, LiveCoreView 会同时给主播 A 和观众 B 发送连麦用户发生变化。
Android
iOS
Flutter
Kotlin
Java
override fun onConnectedUsersUpdated(inviterUser: UserInfo) {
Log.i(TAG, "连麦用户列表发生变化")
}
@Override
public void onConnectedUsersUpdated(List<UserInfo> userList, List<UserInfo> joinList, List<UserInfo> leaveList) {
Log.i(TAG, "连麦用户列表发生变化");
}
Swift
OC
func onConnectedUsersUpdated(userList: [TUIUserInfo], joinList: [TUIUserInfo], leaveList: [TUIUserInfo]) {
print("连麦用户列表发生变化")
}
- (void)onConnectedUsersUpdated:(NSArray<TUIUserInfo *> *)userList
joinList:(NSArray<TUIUserInfo *> *)joinList
leaveList:(NSArray<TUIUserInfo *> *)leaveList {
NSLog(@"连麦用户列表发生变化"); // 如果需要,您可以在这里处理 userList、joinList 和 leaveList
}
// 文件位置:Flutter/lib/manager/observer/live_observer.dart

super.onSeatListChanged = (seatList, seatedList, leftList) {
LiveKitLogger.info(
"$tag($hashCode) onSeatListChanged:[seatList:$seatList ,seatedList:$seatedList,leftList:$leftList]");
liveController.target?.seatController.onSeatListChanged(seatList, seatedList, leftList);
};

断开连麦流程

观众连麦成功后,主播挂断观众的连麦

观众 B 和主播 A 连麦成功后,主播 A 断开和观众 B 的连麦。
Android
iOS
Flutter
Kotlin
Java
val userId = "audienceBUserId"
liveCoreView.disconnectUser(userId, null)
String userId = "audienceUserId";
liveCoreView.disconnectUser(userId, null);
Swift
OC
let userId = "audienceBUserId"
liveCoreView.disconnectUser(userId: userId) {
} onError: { code, message in
}
NSString *userId = @"audienceBUserId";
[liveCoreView disconnectUser:userId
onSuccess:^{
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];
Dart
// 文件位置:Flutter/lib/service/impl/room_engine_service.dart

mLiveService.kickUserOffSeatByAdmin(0, userId, new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {}

@Override
public void onError(TUICommonDefine.Error error, String message) {}
});

观众收到主播断开连麦的回调

主播 A 断开和观众 B 的连麦请求后,观众 B 会收到 onUserConnectionTerminated 回调。
Android
iOS
Flutter
Kotlin
Java
override fun onUserConnectionTerminated(inviterUser: UserInfo) {
Log.i(TAG, "主播关闭连线")
}
@Override
public void onUserConnectionTerminated() {
Log.i(TAG, "主播关闭连线");
}
Swift
OC
func onUserConnectionTerminated() {
print("主播关闭连线")
}
- (void)onUserConnectionTerminated {
NSLog(@"主播关闭连线");
}
Flutter中,主播 A 断开和观众 B 的连麦请求后,观众 B 会收到在RTCRoomEngineonKickedOffSeat回调。
// 文件位置:Flutter/lib/manager/observer/live_observer.dart

super.onKickedOffSeat = (seatIndex, userInfo) {
LiveKitLogger.info("$tag($hashCode) onKickedOffSeat:[seatIndex:$seatIndex,userInfo:$userInfo");
liveController.target?.seatController.onKickedOffSeat(seatIndex, userInfo);
};

观众连麦成功后,观众结束连麦

观众 B 和主播 A 连麦成功后,观众 B 主动断开连麦可以调用 terminateIntraRoomConnection。
Android
iOS
Flutter
Kotlin
Java
liveCoreView.terminateIntraRoomConnection()
liveCoreView.terminateIntraRoomConnection();
Swift
OC
liveCoreView.terminateIntraRoomConnection()
[liveCoreView terminateIntraRoomConnection]
Dart
// 文件位置:Flutter/lib/service/impl/room_engine_service.dart

mLiveService.leaveSeat(new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {}

@Override
public void onError(TUICommonDefine.Error error, String message) {}
});

主播收到观众断开连线的回调

当观众 B 主动断开连麦时,主播会收到 onUserConnectionExited 回调。
Android
iOS
Flutter
Kotlin
Java
override fun onUserConnectionExited(inviterUser: LiveStreamDefine.LiveUser) {
Log.i(TAG, "观众退出连线")
}
@Override
public void onUserConnectionExited(UserInfo liveUser) {
Log.i(TAG, "观众退出连线:${liveUser.userId}");
}
Swift
OC
func onUserConnectionExited(userInfo: TUIUserInfo) {
print("观众退出连线")
}
- (void)onUserConnectionExited:(TUIUserInfo *)userInfo {
NSLog(@"观众退出连线");
}
Flutter中,您可以在onSeatListChanged回调给出的leftList中,查看断开连麦的观众。
// 文件位置:Flutter/lib/manager/observer/live_observer.dart

super.onSeatListChanged = (seatList, seatedList, leftList) {
LiveKitLogger.info(
"$tag($hashCode) onSeatListChanged:[seatList:$seatList ,seatedList:$seatedList,leftList:$leftList]");
liveController.target?.seatController.onSeatListChanged(seatList, seatedList, leftList);
};
说明:
连线功能是基于 LiveCoreView 实现,若您需要扩展连线功能,可参见 LiveCoreView 文档。

观众连麦时序图