视频组件

组件概述

视频直播的核心控件(LiveCoreView)提供了 开播前画面预览、开启视频直播、关闭视频直播,观众观看直播、停止观看直播、主播和观众在直播间内连线,主播跨房和其他主播连线等丰富的 API。您可以使用我们的核心控件半小时内快速搭建视频直播的主流程。然后在其之上添加我们别的直播类组件或者添加您自己的业务 UI 视图。

环境准备

Android
iOS
Android 5.0(SDK API Level 21)及以上版本。
Gradle 7.0 及以上的版本。
Android 5.0 及以上的手机设备。
Xcode 15 及以上。
iOS 13.0 及以上。
CocoaPods 环境安装,点击查看

步骤1:开通服务

请参见 开通服务(TUILiveKit),领取体验版或者开通付费版。

步骤2:集成与配置

Android
iOS
1. 在 app 目录下找到build.gradle.kts(或build.gradle)文件,并在其中增加如下代码,加入对 LiveCoreView 组件的依赖:
build.gradle.kts
build.gradle
api("io.trtc.uikit:live-stream-core:latest.release")
api 'io.trtc.uikit:live-stream-core:latest.release'
2. 由于我们在 SDK 内部使用了Java 的反射特性,需要将 SDK 中的部分类加入不混淆名单,因此需要您在proguard-rules.pro文件中添加如下代码:
-keep class com.tencent.** { *; }
-keep class com.trtc.uikit.livekit.livestreamcore.** { *; }
-keep class com.google.gson.** { *;}
3. 在 app 目录下找到AndroidManifest.xml 文件,在 application 节点中添加 tools:replace="android:allowBackup" 和android:allowBackup="false",覆盖组件内的设置,使用自己的设置。
// app/src/main/AndroidManifest.xml
<application
...
// 添加如下配置覆盖 依赖的 sdk 中的配置
android:allowBackup="false"
tools:replace="android:allowBackup">=
使用 CocoaPods 导入组件,如果您遇到问题,请先参见 环境准备。导入组件具体骤如下:
1. 请在您的 Podfile 文件中添加 pod 'LiveStreamCore' 依赖。
Swift
target 'xxxx' do
...
...
pod 'LiveStreamCore'
end
如果您没有Podfile 文件,首先终端cdxxxx.xcodeproj目录,然后通过以下命令创建:
pod init
2. 在终端中,首先cdPodfile目录下,然后执行以下命令,安装组件。
pod install
如果无法安装 SeatGridView 最新版本,可以先删除Podfile.lockPods。然后执行以下命令更新本地的 CocoaPods 仓库列表。
pod repo update
之后执行以下命令,更新组件库的 Pod 版本。
pod update
3. 可以先编译运行一下,如果遇到问题,请参见 常见问题。问题如果依然无法解决,可以先去跑一下我们的 Example工 程。您在接入和使用过程中遇到的任何问题,欢迎给我们 反馈

步骤3:登录

Android
iOS
在您的项目中添加如下代码,它的作用是通过调用 TUICore 中的相关接口完成 TUI 组件的登录。这一步骤至关重要,只有在成功登录之后,您才能正常使用 LiveCoreView 提供的各项功能。
Kotlin
Java
TUIRoomEngine.login(applicationContext,
1400000001, // 请替换为步骤一取到的 SDKAppID
"denny", // 请替换为您的 UserID
"xxxxxxxxxxx", // 您可以在控制台中计算一个 UserSig 并填在这个位置
object : TUIRoomDefine.ActionCallback() {
override fun onSuccess() {
Log.i(TAG, "login success")
}

override fun onError(errorCode: Int, errorMessage: String) {
Log.e(TAG, "login failed, errorCode: $errorCode msg:$errorMessage")
}
})
TUIRoomEngine.login(context,
1400000001, // 请替换为步骤一取到的 SDKAppID
"denny", // 请替换为您的 UserID
"xxxxxxxxxxx", // 您可以在控制台中计算一个 UserSig 并填在这个位置
new TUIRoomDefine.ActionCallback() {
@Override
public void onSuccess() {
Log.i(TAG, "login success");
}

@Override
public void onError(TUICommonDefine.Error error, String message) {
Log.e(TAG, "login failed, errorCode: " + errorCode + " msg:" + errorMessage);
}
});
在您的项目中添加如下代码,它的作用是通过调用 RTCRoomEngine 中的登录相关接口完成 TUI 组件的登录。这一步骤至关重要,只有在成功登录之后,您才能正常使用 SeatGridView 提供的各项功能。
swift
//
// AppDelegate.swift
//

import RTCRoomEngine

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
TUIRoomEngine.login(sdkAppId: 1400000001, // 请替换为步骤一取到的 SDKAppID
userId: "denny", // 请替换为您的 UserID
userSig: "xxxxxxxxxxx") { // 您可以在控制台中计算一个 UserSig 并填在这个位置
print("login success")
} onError: { code, message in
print("login failed, code: \(code), error: \(message ?? "nil")")
}
return true
}
参数说明
这里详细介绍一下 login 函数中所需要用到的几个关键参数:
参数
类型
说明
SDKAppID
int
步骤1 中的的第3步中获取。
UserID
String
当前用户的 ID,字符串类型,只允许包含英文字母(a-z 和 A-Z)、数字(0-9)、连词符和下划线。
userSig
String
使用 步骤1 的第3步中获取的 SecretKey 对 SDKAppID、UserID 等信息进行加密,就可以得到 UserSig,它是一个鉴权用的票据,用于腾讯云识别当前用户是否能够使用 TRTC 的服务。您可以通过控制台中的 辅助工具 生成一个临时可用的 UserSig。更多信息请参见 如何计算及使用 UserSig
说明:
开发环境:如果您正在本地开发调试阶段,可以采用本地 GenerateTestUserSig.genTestSig函数生成 userSig。该方法中 SDKSecretKey 很容易被反编译逆向破解,一旦您的密钥泄露,攻击者就可以盗用您的腾讯云流量。
生产环境:如果您的项目要发布上线,请采用 服务端生成 UserSig 的方式。

步骤4:使用核心控件实现直播功能

主播开始直播和观众观看直播效果预览:
主播开开启直播
观众观看直播








主播预览和开播

创建核心控件
Android
iOS
您可以在您实现推流的 Activity 中通过 java 代码或者 xml 方式加载我们的核心控件,其中代码方式示例如下(XML 方式也类似):
kotlin
java
val livecoreView = LiveCoreView(this)
LiveCoreView liveCoreView = new LiveCoreView(this);
swift
import LiveStreamCore

let liveCoreView = LiveCoreView()
开启直播预览:本地摄像头预览,并未真正开启直播间。
Android
iOS
kotlin
java
livecoreView.startCamera(true, null)
liveCoreView.startCamera(true, null);
swift
import LiveStreamCore

liveCoreView.startCamera(useFrontCamera: true{
} onError: { code, message in
}
主播开启直播间:开启一个直播间,并将本地摄像头采集的数据和麦克风采集的数据推流到直播间。
Android
iOS
kotlin
java
val roomInfo = TUIRoomDefine.RoomInfo()
roomInfo.roomId = "123456"
livecoreView.startLiveStream(roomInfo, null)

livecoreView.startMicrophone(null)
TUIRoomDefine.RoomInfo roomInfo = new TUIRoomDefine.RoomInfo();
roomInfo.roomId = "roomId_123456";
livecoreView.startLiveStream(roomInfo, null);

livecoreView.startMicrophone(null);
swift
import LiveStreamCore
import RTCRoomEngine

let roomInfo = TUIRoomInfo()
roomInfo.roomId = "123456"
roomInfo.seatMode = .applyToTake

liveCoreView.startLiveStream(roomInfo: roomInfo) { roomInfo in
} onError: { code, message in
}

liveCoreView.startMicrophone {
} onError: { code, message in
}

观众观看

创建核心控件
Android
iOS
您可以在您实现推流的 Activity 中通过 java 代码或者 xml 方式加载我们的核心控件,其中代码方式示例如下(XML 方式也类似):
kotlin
java
val livecoreView = LiveCoreView(this)
LiveCoreView liveCoreView = new LiveCoreView(this);
swift
import LiveStreamCore

let liveCoreView = LiveCoreView()
观众加入直播间:观众进入直播间,并拉取直播间主播的视频流和音频流。
Android
iOS
kotlin
java
livecoreView.joinLiveStream("roomId_123456", null)
livecoreView.joinLiveStream("roomId_123456", null);
swift
import LiveStreamCore

liveCoreView.joinLiveStream(roomId: "roomId_123456") { roomInfo in
} onError: { code, message in
}

观众连麦

观众连麦效果预览:
单人连麦
多人连麦






您可以调用如下 API 函数,实现观众连麦功能。以观众 B 申请和主播 A 连麦为例实现如下。
说明:
以下是由 LiveCoreView 提供的主动调用方法。
所有的回调方法是指 LiveCoreView 设置的 ConnectionObserver 对象中的回调方法。

观众发送连麦请求

观众 B 给主播 A 发送连麦请求。
Android
iOS
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: 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) {
}];

主播端收到连麦请求

主播 A 会在 onUserConnectionRequest 回调方法中收到观众 B 的连麦请求。
Android
iOS
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);
}

主播响应连麦请求

主播 A 收到观众的连麦请求后,可以调用 respondIntraRoomConnection 响应观众 B 是否同意连麦。
Android
iOS
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) {
}];

观众收到主播响应回调

主播 A 同意观众 B 连麦请求后, 观众 B 会通过 onUserConnectionAccepted 回调收到主播 A 同意连麦的回调。
Android
iOS
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);
}

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

主播 A 同意观众 B 连麦请求后, LiveCoreView 会同时给主播 A 和观众 B 发送连麦用户发生变化。
Android
iOS
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
}
当连麦过程中,需要断开连麦,可调用如下 API。

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

观众 B 和主播 A 连麦成功后,主播 A 断开和观众 B 的连麦。
Android
iOS
新选项
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) {
}];


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

主播 A 断开和观众 B 的连麦请求后,观众 B 会收到 onUserConnectionTerminated 回调。
Android
iOS
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(@"主播关闭连线");
}

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

观众 B 和主播 A 连麦成功后,观众 B 主动断开连麦可以调用 terminateIntraRoomConnection。
Android
iOS
Kotlin
Java
liveCoreView.terminateIntraRoomConnection()
liveCoreView.terminateIntraRoomConnection();
Swift
OC
liveCoreView.terminateIntraRoomConnection()
[liveCoreView terminateIntraRoomConnection]

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

当观众 B 主动断开连麦时,主播会收到 onUserConnectionExited 回调。
Android
iOS
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(@"观众退出连线");
}

主播连线

主播连线效果预览:
双主播连线
多主播连线






您可以按如下 API 来完成主播连线功能。这里以主播 A 与主播 B 连线为例实现如下。
说明:
以下是由 LiveCoreView 提供的主动调用方法。
所有的回调方法是指 LiveCoreView 设置的 ConnectionObserver 对象中的回调方法。

主播 A 发起连线

主播 A 通过调用 requestCrossRoomConnection 发起连线,在参数 roomId 中传入需要连线的主播 B 房间 id。
Android
iOS
Kotlin
java
val roomId = "anchorBRoomId"
mLiveViewList.requestCrossRoomConnection(roomId, 10, null)
String roomId = "anchorBRoomId";
mLiveViewList.requestCrossRoomConnection(roomId, 10, null);
Swift
OC
let roomId = "anchorRoomId"

liveCoreView.requestCrossRoomConnection(roomId: roomId, timeOut: 60) {
} onError: { code, message in
}
NSString *roomId = @"anchorRoomId";

[liveCoreView requestCrossRoomConnection:roomId
timeOut:60
onSuccess:^(void) {
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];
主播 A 可通过 onCrossRoomConnectionAccepted 接收请求同意回调。

主播 B 收到连线请求

主播 B 通过 onCrossRoomConnectionRequest 接收连线请求回调。
Android
iOS
Kotlin
java
override fun onCrossRoomConnectionRequest(inviterUser: UserInfo) {
Log.i(TAG, "收到主播A连线房间请求:${inviterUser.userId}")
}
@Override
public void onCrossRoomConnectionRequest(LiveStreamDefine.RoomInfo roomInfo) {
Log.i(TAG, "收到主播A连线房间请求:" + roomInfo.roomId);
}
Swift
OC
func onCrossRoomConnectionRequest(hostUser: TUIConnectionUser) {
print("收到主播A连线房间请求:\(hostUser.userId)")
}
- (void)onCrossRoomConnectionRequest:(TUIConnectionUser *)hostUser {
NSLog(@"收到主播A连线房间请求:%@", hostUser.userId);
}
主播 B 通过调用 respondToCrossRoomConnection 响应连线请求。
Android
iOS
Kotlin
java
liveCoreView.respondToCrossRoomConnection(roomId, true, null)
// 同意连线请求
liveCoreView.respondToCrossRoomConnection(roomId, true, null);
Swift
OC
liveCoreView.respondToCrossRoomConnection(roomId: roomId, isAccepted: true) {
} onError: { code, message in
}
[liveCoreView respondToCrossRoomConnection:roomId
isAccepted:true
onSuccess:^(void) {
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];
主播 A, B以及房间内观众收到 onConnectedRoomsUpdated 回调,收到接收连线列表发生变化通知。
Android
iOS
Kotlin
java
override fun onConnectedRoomsUpdated(inviterUser: UserInfo) {
Log.i(TAG, "主播连线房间列表更新")
}
@Override
public void onConnectedRoomsUpdated(List<LiveStreamDefine.RoomInfo> roomList) {
Log.i(TAG, "主播连线房间列表更新");
}
Swift
OC
func onConnectedRoomsUpdated(hostUserList: [TUIConnectionUser]) {
print("主播连线房间列表更新")
}
- (void)onConnectedRoomsUpdated:(NSArray<TUIConnectionUser *> *)hostUserList {
NSLog(@"主播连线房间列表更新");
}

退出连线流程

主播 B 调用 terminateIntraRoomConnection 退出连线。
Android
iOS
kotlin
java
public void disconnect(TUIRoomDefine.ActionCallback callback) {
mTUILiveConnectionManager.disconnect(callback);
}
liveCoreView.terminateIntraRoomConnection()
Swift
OC
liveCoreView.terminateCrossRoomConnection()
[liveCoreView terminateCrossRoomConnection];

设置连线布局

自定义布局连线效果预览
主播连线中-九宫格布局
主播连线中-浮窗布局
主播连线中-自定义布局













您可以通过以下方式快速设置您与连线主播或您与连麦观众的布局。
Android
iOS
kotlin
java
// 设置宫格布局
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.GRID_LAYOUT, "")

// 设置浮窗布局
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FLOAT_LAYOUT, "")

// 设置自定义布局
var layoutJson = ""
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FREE_LAYOUT, layoutJson)
// 设置宫格布局
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.GRID_LAYOUT, "");

// 设置浮窗布局
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FLOAT_LAYOUT, "");

// 设置自定义布局
String layoutJson = "";
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FREE_LAYOUT, layoutJson);
swift
import LiveStreamCore

// 设置宫格布局
liveCoreView.setLayoutMode(layoutMode: .gridLayout)

// 设置浮窗布局
liveCoreView.setLayoutMode(layoutMode: .floatLayout)

// 设置自定义布局
let layoutJson = ""
liveCoreView.setLayoutMode(layoutMode: .freeLayout, layoutJson: layoutJson)
说明:
自定义布局 layoutJson 是一个 json 格式的字符串,详细内容请查看 自定义布局 json

自定义布局 json

自定义布局的 json 结构说明如下:
{
"1": { // 视频视图的数量
"backgroundColor": "#000000", // 画布的背景颜色,采用 RGB 十六进制格式
"viewInfoList": [{ // 每个视频视图的布局信息和背景颜色
"x": 0, // 水平偏移与屏幕宽度的比例,取值范围 [0, 1]
"y": 0, // 垂直偏移与屏幕宽度的比例,取值范围 [0, 1]
"width": 1, // 视频视图的宽度与屏幕宽度的比例,取值范围 [0, 1]
"height": -1, // 视频视图的高度与屏幕宽度的比例,取值范围 [0, 1] 或 -1;-1 表示视图高度与屏幕高度相同
"zOrder": 0, // 视频视图的层级顺序,数值越大,视图越靠上
"backgroundColor": "#000000" // 当前视频视图的背景颜色,采用 RGB 十六进制格式
}]
}
}

主播 PK

LiveCoreView 提供了主播 PK 相关的 API , 由于每种 PK 玩法的 UI 都不一样,所以LiveCoreView 只提供 API ,您需要自己完成 UI 效果的实现。
主播 PK 效果预览:
双主播PK
多主播PK






说明:
PK 功能依赖于连线功能,所以您需要在主播连线的情况下才能发起 PK请求
以下主动调用 api 是由 LiveCoreView 提供。
所有的回调方法是指 LiveCoreView 设置的 BattleObserver 对象中的回调方法。
您可以按如下 API 来完成主播PK功能。这里以主播 A 与主播 B PK为例实现如下。

主播 A 发起 PK

主播 A 通过调用 requestBattle 发起PK。
Android
iOS
Kotlin
java
val BATTLE_DURATION = 30
val battleConfig = BattleConfig()
battleConfig.duration = BATTLE_DURATION
battleConfig.needResponse = true
battleConfig.extensionInfo = ""

val list: MutableList<String> = ArrayList()
list.add("anchorBUserId")

val BATTLE_REQUEST_TIMEOUT = 10

liveCoreView.requestBattle(battleConfig, list, BATTLE_REQUEST_TIMEOUT,
object : LiveCoreViewDefine.BattleRequestCallback {
override fun onSuccess(battleId: String, requestedUserIdList: List<String>) {}
override fun onError(error: TUICommonDefine.Error, message: String) {}
})
final int BATTLE_DURATION = 30;
TUILiveBattleManager.BattleConfig battleConfig = new TUILiveBattleManager.BattleConfig();
battleConfig.duration = BATTLE_DURATION;
battleConfig.needResponse = true;
battleConfig.extensionInfo = "";

List<String> list = new ArrayList<>();
list.add("anchorBUserId");

final int BATTLE_REQUEST_TIMEOUT = 10;

liveCoreView.requestBattle(battleConfig, list, BATTLE_REQUEST_TIMEOUT,
new LiveCoreViewDefine.BattleRequestCallback() {
@Override
public void onSuccess(String battleId, List<String> requestedUserIdList) {

}


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

}
});
Swift
let roomId = "anchorRoomId"
let config = TUIBattleConfig()
config.duration = battleDuration
config.needResponse = true
config.extensionInfo = ""

let userIdList: [String] = []
let timeout: TimeInterval = 10

liveCoreView.requestBattle(config: config, userIdList: userIdList, timeout: timeout) {
[weak self] (battleId, battleUserList) in
} onError: { _, _ in
}
主播 A 可通过 onBattleRequestAccept 接收 PK 同意回调。

主播 B 收到 PK 请求

主播 B 通过 onBattleRequestReceived 接收 PK 请求回调。
Android
iOS
Kotlin
java
override fun onBattleRequestReceived(battleId: String, inviterUser: BattleUser, invitee: BattleUser) {
Log.i(TAG, "收到主播 A 的 PK 请求::$battleId")
}
@Override
public void onBattleRequestReceived(String battleId, BattleUser inviter, BattleUser invitee) {
Log.i(TAG, "收到主播 A 的 PK 请求:" + battleId);
}
Swift
extension ViewContrller: BattleObserver { //替换为您真实的类名
func onBattleRequestReceived(battleId: String, inviter: TUIBattleUser, invitee: TUIBattleUser) {
}
}
主播 B 通过调用 respondToBattle 响应 PK 请求。
Android
iOS
Kotlin
java
// 同意 PK 请求
val battleId = "battleId"
liveCoreView.respondToBattle(battleId, true, null)
// 同意 PK 请求
String battleId = "battleId";
liveCoreView.respondToBattle(battleId, true, null);
Swift
liveCoreView.respondToBattle(battleId: manager.battleState.battleId, isAccepted: false, onSuccess: { [weak self] in
}, onError: { _, _ in
})
主播 A、B 以及房间内观众收到 onBattleStarted,收到 PK 开始通知。
Android
iOS
Kotlin
java
override fun onBattleStarted(battleInfo: BattleInfo) {
Log.i(TAG, "PK 开始回调")
}
@Override
public void onBattleStarted(BattleInfo battleInfo) {
Log.i(TAG, "主播连线房间列表更新");
}
Swift
extension ViewContrller: BattleObserver { //替换为您真实的类名
func onBattleStarted(battleInfo: TUIBattleInfo)) {
}
}

退出 PK 流程

自然结束:当 PK 时间截止时,会收到 onBattleEnded 回调。
主动停止:主播 B 调用 terminateBattle 自己会退出 PK, 主播 A 会收到 onUserExitBattle
Android
iOS
kotlin
java
mLiveCoreView.terminateBattle(battleId, null)
mLiveCoreView.terminateBattle(battleId, null);
Swift
liveCoreView.terminateBattle(battleId: manager.battleState.battleId) {
} onError: { _, _ in
}