LiveCoreView

Component Overview

Core Controls for Video Live Streaming (LiveCoreView) provides rich APIs such as preview before broadcasting, starting video live streaming, stopping video live streaming, allowing the audience to watch live streams, stopping watching live streams, connecting anchors and audience in the live streaming room, and cross-room connection with other anchors. You can use our core controls to rapidly deploy the main process of video live streaming within half an hour. Then you can add other live streaming components on top of it or add your own business UI views.

Environment Preparation

Android
iOS
Android 5.0 (SDK API Level 21) and above versions.
Gradle 7.0 and above versions.
Mobile devices running Android 5.0 or higher.
Xcode 15 and above.
iOS 13.0 and above.
CocoaPods environment installation. Click to view.

Step 1: activate the service

See Activate Service (TUILiveKit) to claim a trial version or activate a paid edition.

Step Two: Integration and Configuration

Android
iOS
1. In the app directory, find the build.gradle.kts (or build.gradle) file and add the following code in it to add a dependency on the LiveCoreView component:
build.gradle.kts
build.gradle
api("io.trtc.uikit:live-stream-core:latest.release")
api 'io.trtc.uikit:live-stream-core:latest.release'
2. Since we use Java's reflection features internally in the SDK, some classes in the SDK need to be added to the non-obfuscation list. Therefore, you need to add the following code in the proguard-rules.pro file:
-keep class com.tencent.** { *; }
-keep class com.trtc.uikit.livekit.livestreamcore.** { *; }
-keep class com.google.gson.** { *;}
3. In the app directory, find the AndroidManifest.xml file. In the application node, add tools:replace="android:allowBackup" and android:allowBackup="false". Override the settings within the component and use your own settings.
// app/src/main/AndroidManifest.xml
<application
...
// Add the following configuration to override the configuration in the dependent sdk.
android:allowBackup="false"
tools:replace="android:allowBackup">=
Use CocoaPods to import components. If you encounter problems, please first refer to Environment Preparation. The specific steps for importing components are as follows:
1. Add the pod 'LiveStreamCore' dependency in your Podfile.
Swift
target 'xxxx' do
...
...
pod 'LiveStreamCore'
end
If you don't have a Podfile file, first use the terminal to cd to the xxxx.xcodeproj directory, then create it through the following command:
pod init
2. In the terminal, first cd to the Podfile directory, then execute the following commands to install components.
pod install
If the latest version of SeatGridView cannot be installed, first delete Podfile.lock and Pods. Then execute the following commands to update the local CocoaPods repository list.
pod repo update
Then execute the following commands to update the Pod version of the component library.
pod update
3. Compile and run first. If you encounter problems, please see Common Issues. If the problem is still unresolved, you can try running our Example project. For any issues you encounter during integration and use, feel free to provide feedback.

Step 3: Logging In

Android
iOS
Add the following code in your project. It enables logging in to the TUI component by calling relevant APIs in TUICore. This step is crucial. Only after a successful login can you properly use the various features provided by LiveCoreView.
Kotlin
Java
TUIRoomEngine.login(applicationContext,
1400000001, // Replace with the SDKAppID obtained in step 1
"denny" // Replace with your UserID
"xxxxxxxxxxx", // You can calculate a UserSig in the console and fill it in this position
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, // Replace with the SDKAppID obtained in step 1
"denny" // Replace with your UserID
"xxxxxxxxxxx", // You can calculate a UserSig in the console and fill it in this position
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);
}
});
Add the following code to your project. It enables you to log in to the TUI component by calling the login-related APIs in RTCRoomEngine. This step is crucial. Only after successful log-in can you normally use the features provided by SeatGridView.
swift
//
// AppDelegate.swift
//

import RTCRoomEngine

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
TUIRoomEngine.login(sdkAppId: 1400000001, // Replace with the SDKAppID obtained in step 1
userId: "denny", // Replace with your UserID
userSig: "xxxxxxxxxxx") { // You can calculate a UserSig in the console and fill it in this position
print("login success")
} onError: { code, message in
print("login failed, code: \(code), error: \(message ?? "nil")")
}
return true
}
Parameter Description
Here is a detailed introduction to several key parameters needed in the login function:
Parameters
Type
Overview
SDKAppID
int
In the final step of step 1, you have already obtained it. It is not necessary to elaborate here.
UserID
String
Current user's ID, string type, only allow to include English letters (a-z and A-Z), digits (0-9), hyphen and underscore.
userSig
String
Use the SecretKey obtained in step 3 of Step 1 to encrypt information such as SDKAppID and UserID to get a UserSig. It is an authentication token used by Tencent Cloud to verify whether the current user can use the TRTC service. You can generate a temporary available UserSig through the auxiliary tool in the console. For more information, see how to calculate and use UserSig.
Notes:
Development environment: If you are in the local development and debugging stage, you can use the local GenerateTestUserSig.genTestSig function to generate userSig. In this method, the SDKSecretKey can be easily decompiled and reverse - engineered. Once your key is leaked, an attacker can steal your Tencent Cloud traffic.
Production environment: If your project is to be launched, use the server-side generation of UserSig.

Step 4: Implement Live Streaming Functionality Using Core Controls

The anchor starts live streaming and the audience views the live broadcast effects preview
Anchor starts live streaming
Audience watches live.








Anchor Previews and Goes Live

Create core controls
Android
iOS
You can load our core control in the Activity where you implement streaming, either through java code or the xml method. The following is an example of the code method (the xml method is similar).
kotlin
java
val livecoreView = LiveCoreView(this)
LiveCoreView liveCoreView = new LiveCoreView(this);
swift
import LiveStreamCore

let liveCoreView = LiveCoreView()
Enable live preview: Local camera preview, and the live streaming room has not truly been launched.
Android
iOS
kotlin
java
livecoreView.startCamera(true, null)
liveCoreView.startCamera(true, null);
swift
import LiveStreamCore

liveCoreView.startCamera(useFrontCamera: true) {
} onError: { code, message in
}
Anchor opens live room: Open a live room and stream data collected by the local camera and microphone to the live room.
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
}

Audience Viewing

Create core controls
Android
iOS
You can load our core control in the Activity where you implement streaming, either through java code or the xml method. The following is an example of the code method (the xml method is similar).
kotlin
java
val livecoreView = LiveCoreView(this)
LiveCoreView liveCoreView = new LiveCoreView(this);
swift
import LiveStreamCore

let liveCoreView = LiveCoreView()
Audience Joins Live Room: The audience enters the live room and pulls the video stream and audio stream of the live stream host.
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
}

Audience Co-Broadcasting

Effect Preview of Audience Co-Broadcasting
Single-Person Co-Broadcasting
Multi-Person Microphone Connection






You can call the following API functions to implement the audience mic connection feature. Take Audience B's application for co-broadcasting with Anchor A as an example, the implementation is as follows.
Notes:
The following are proactive invocation methods provided by LiveCoreView.
All callback methods refer to the callback methods in the ConnectionObserver object set by LiveCoreView.

Audience Sending Microphone Connection Request

Audience B sends a microphone connection request to Anchor A.
Android
iOS
Kotlin
Java
val userId = "anchorUserId"; // Change to the room owner's UserId. When an empty string is input, it defaults to the room owner's UserId.
val timeout = 60;
liveCoreView.requestIntraRoomConnection(userId, 10, null)
String userId = "anchorUserId"; // Change to the room owner's UserId. When an empty string is input, it defaults to the room owner's UserId.
int timeout = 60;
liveCoreView.requestIntraRoomConnection(userId, timeout, true, null);
Swift
OC
let timeout = 60
let userId = "anchorUserId" // Change to the room owner's UserId. When an empty string is input, it defaults to the room owner's UserId.
liveCoreView.requestIntraRoomConnection(userId: userId, timeOut: timeOut, openCamera: true) {
} onError: { code, message in
}
NSInteger timeout = 60;
NSString userId = "anchorUserId"; // Change to the room owner's UserId. When an empty string is input, it defaults to the room owner's UserId.
[liveCoreView requestIntraRoomConnection:""
timeOut:timeout
onSuccess:^(void) {
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];

Anchor Receiving Mic Connection Request

Anchor A will receive Audience B's mic connection request in the onUserConnectionRequest callback method.
Android
iOS
Kotlin
Java
override fun onUserConnectionRequest(inviterUser: UserInfo) {
Log.i(TAG, "Received connection request from audience: ${inviterUser.userId}")
}
@Override
public void onUserConnectionRequest(LiveStreamDefine.LiveUser inviterUser) {
Log.i(TAG, "Received connection request from audience: " + inviterUser.userId)
}
Swift
OC
func onUserConnectionRequest(inviterUser: TUIUserInfo) {
print("Received connection request from audience: \(inviterUser.userId)")
}
- (void)onUserConnectionRequest:(TUIUserInfo *)inviterUser {
NSLog(@"Received connection request from audience: %@", hostUser.userId);
}

Anchor Responding to Mic Connection Request

After Anchor A receives the mic connection request from the audience, they can call respondIntraRoomConnection to respond whether Audience B is agreed to the mic connection.
Android
iOS
Kotlin
Java
// Host agrees to connect mic
liveCoreView.respondIntraRoomConnection(audienceBUserId, true, null)
// Host agrees to connect mic
liveCoreView.respondIntraRoomConnection(userId, true, null);

// Anchor rejects mic connection
liveCoreView.respondIntraRoomConnection(userId, false, null);
Swift
OC
// Host agrees to connect mic
liveCoreView.respondIntraRoomConnection(userId: audienceBUserId, isAccepted: true) {
} onError: { code, message in
}
// Host agrees to connect mic
[liveCoreView respondIntraRoomConnection:audienceBUserId
isAccepted:YES
onSuccess:^(void) {
} onError:^(NSInteger code, NSString * _Nonnull message) {
}];

Audience Received Broadcaster Response Callback

After Anchor A agrees to Audience B's mic connection request, Audience B will receive a callback confirming the agreement through the onUserConnectionAccepted callback.
Android
iOS
Kotlin
Java
override fun onUserConnectionAccepted(inviterUser: UserInfo) {
Log.i(TAG, "Audience agreed to connection: ${inviterUser.userId}")
}
@Override
public void onUserConnectionAccepted(LiveStreamDefine.LiveUser liveUser) {
Log.i(TAG, "Audience agreed to connection: " + liveUser.userId)
}

@Override
public void onUserConnectionRejected(LiveStreamDefine.LiveUser liveUser) {
Log.i(TAG, "Audience rejected connection: " + liveUser.userId)
}
Swift
OC
func onUserConnectionAccepted(userId: String) {
print("Audience agreed to connection: \(userId)")
}
- (void)onUserConnectionAccepted:(NSString *)userId {
NSLog(@"Audience agreed to connection: %@", userId);
}

Callback for Changes in the List of Mic-Connected Users

After Anchor A agrees to Audience B's mic connection request, LiveCoreView will simultaneously send notifications about changes in the list of co-broadcasting users to both Anchor A and Audience B.
Android
iOS
Kotlin
Java
override fun onConnectedUsersUpdated(inviterUser: UserInfo) {
Log.i(TAG, "Changes in the list of mic-connected users")
}
@Override
public void onConnectedUsersUpdated(List<UserInfo> userList, List<UserInfo> joinList, List<UserInfo> leaveList) {
Log.i(TAG, "Changes in the list of mic-connected users");
}
Swift
OC
func onConnectedUsersUpdated(userList: [TUIUserInfo], joinList: [TUIUserInfo], leaveList: [TUIUserInfo]) {
print("Changes in the list of mic-connected users")
}
- (void)onConnectedUsersUpdated:(NSArray<TUIUserInfo *> *)userList
joinList:(NSArray<TUIUserInfo *> *)joinList
leaveList:(NSArray<TUIUserInfo *> *)leaveList {
NSLog(@"Changes in the list of mic-connected users"); // If necessary, you can handle userList, joinList and leaveList here
}
During a mic connection, to disconnect, you can call the following APIs.

Audience Mic Connection Successful. Anchor Hangs Up the Audience'S Mic Connection

Upon success of the microphone connection between Audience B and Anchor A, Anchor A disconnects the microphone connection with Audience B.
Android
iOS
New Options
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) {
}];


Audience Receives Callback of Anchor Disconnecting Mic Connection

After Anchor A disconnects the mic connection request with Audience B, Audience B will receive the onUserConnectionTerminated callback.
Android
iOS
Kotlin
Java
override fun onUserConnectionTerminated(inviterUser: UserInfo) {
Log.i(TAG, "Anchor closed the connection")
}
@Override
public void onUserConnectionTerminated() {
Log.i(TAG, "Anchor closes the connection");
}
Swift
OC
func onUserConnectionTerminated() {
print("Anchor closed the connection")
}
- (void)onUserConnectionTerminated {
NSLog(@"Anchor closed the connection");
}

Audience Mic Connection Successful. Audience Ends Mic Connection

Upon successful mic connection between Audience B and Anchor A, Audience B can proactively disconnect by calling terminateIntraRoomConnection.
Android
iOS
Kotlin
Java
liveCoreView.terminateIntraRoomConnection()
liveCoreView.terminateIntraRoomConnection();
Swift
OC
liveCoreView.terminateIntraRoomConnection()
[liveCoreView terminateIntraRoomConnection]

Anchor Receives Callback of Audience Disconnecting Mic Connection

When Audience B proactively disconnects the mic, the anchor will receive the onUserConnectionExited callback.
Android
iOS
Kotlin
Java
override fun onUserConnectionExited(inviterUser: LiveStreamDefine.LiveUser) {
Log.i(TAG, "Audience exited the connection")
}
@Override
public void onUserConnectionExited(UserInfo liveUser) {
Log.i(TAG, "Audience exited the connection: ${liveUser.userId}");
}
Swift
OC
func onUserConnectionExited(userInfo: TUIUserInfo) {
print("Audience exited the connection")
}
- (void)onUserConnectionExited:(TUIUserInfo *)userInfo {
NSLog(@"Audience exited the connection");
}

Anchor Connection

Effect preview of anchor connection
Dual-Anchor Connection
Multi-Anchor Connection






You can use the following API to implement the anchor connection feature. Here is an example of implementing the connection between Anchor A and Anchor B.
Notes:
The following are proactive invocation methods provided by LiveCoreView.
All callback methods refer to the callback methods in the ConnectionObserver object set by LiveCoreView.

Anchor a Initiating Connection

Anchor A initiates a connecting line by calling requestCrossRoomConnection, and inputs the room id of anchor B, who needs to be connected, in the parameter roomId.
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) {
}];
Anchor A can receive the request acceptance callback through onCrossRoomConnectionAccepted.

Anchor B Received a Connection Request

Anchor B receives the connection request callback through onCrossRoomConnectionRequest.
Android
iOS
Kotlin
java
override fun onCrossRoomConnectionRequest(inviterUser: UserInfo) {
Log.i(TAG, "Received room connection request from anchor A: ${inviterUser.userId}")
}
@Override
public void onCrossRoomConnectionRequest(LiveStreamDefine.RoomInfo roomInfo) {
Log.i(TAG, "Received room connection request from anchor A: " + roomInfo.roomId);
}
Swift
OC
func onCrossRoomConnectionRequest(hostUser: TUIConnectionUser) {
print("Received room connection request from anchor A: \(hostUser.userId)")
}
- (void)onCrossRoomConnectionRequest:(TUIConnectionUser *)hostUser {
NSLog(@"Received room connection request from anchor A: %@", hostUser.userId);
}
Anchor B responds to the connection request by calling respondToCrossRoomConnection.
Android
iOS
Kotlin
java
liveCoreView.respondToCrossRoomConnection(roomId, true, null)
// Grant connection request
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) {
}];
Anchor A, Anchor B, and the audience in the room receive the onConnectedRoomsUpdated callback and are notified that the list of accepted connections has changed.
Android
iOS
Kotlin
java
override fun onConnectedRoomsUpdated(inviterUser: UserInfo) {
Log.i(TAG, "Anchor connection room list updated")
}
@Override
public void onConnectedRoomsUpdated(List<LiveStreamDefine.RoomInfo> roomList) {
Log.i(TAG, "Anchor connection room list updated");
}
Swift
OC
func onConnectedRoomsUpdated(hostUserList: [TUIConnectionUser]) {
print("Anchor connection room list updated")
}
- (void)onConnectedRoomsUpdated:(NSArray<TUIConnectionUser *> *)hostUserList {
NSLog(@"Anchor connection room list updated");
}

Exiting Connection Process

Anchor B calls terminateIntraRoomConnection to exit the connection.
Android
iOS
kotlin
java
public void disconnect(TUIRoomDefine.ActionCallback callback) {
mTUILiveConnectionManager.disconnect(callback);
}
liveCoreView.terminateIntraRoomConnection()
Swift
OC
liveCoreView.terminateCrossRoomConnection()
[liveCoreView terminateCrossRoomConnection];

Setting Connection Layout

Custom layout connecting line effect preview
Anchor Connection - Nine-Grid Layout
Anchor Connecting - Floating Window Layout
Anchor Connecting - Custom Layout













You can quickly set the layout between you and the connected host or between you and the mic-connecting audience in the following ways.
Android
iOS
kotlin
java
// Set grid layout
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.GRID_LAYOUT, "")

// Set floating window layout
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FLOAT_LAYOUT, "")

// Set custom layout
var layoutJson = ""
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FREE_LAYOUT, layoutJson)
// Set grid layout
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.GRID_LAYOUT, "");

// Set floating window layout
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FLOAT_LAYOUT, "");

// Set custom layout
String layoutJson = "";
mLiveStreamListView.setLayoutMode(LiveCoreViewDefine.LayoutMode.FREE_LAYOUT, layoutJson);
swift
import LiveStreamCore

// Set grid layout
liveCoreView.setLayoutMode(layoutMode: .gridLayout)

// Set floating window layout
liveCoreView.setLayoutMode(layoutMode: .floatLayout)

// Set custom layout
let layoutJson = ""
liveCoreView.setLayoutMode(layoutMode: .freeLayout, layoutJson: layoutJson)
Notes:
Custom layout. The layoutJson is a string in json format. For details, view Custom Layout JSON.

Custom Layout Json

The structure description of the custom layout's json is as follows:
{
"1": { // Number of video views
"backgroundColor": "#000000", // Background color of the canvas, in RGB hexadecimal format
"viewInfoList": [{ // Layout information and background color of each video view
"x": 0, // Horizontal offset ratio to screen width, in the range of [0, 1]
"y": 0, // Vertical offset ratio to screen width, in the range of [0, 1]
"width": 1, // Width ratio of video view to screen width, in the range of [0, 1]
"height": -1, // Height ratio of video view to screen width, value ranges from [0, 1] or -1; -1 indicates the view height is the same as the screen height

Anchor PK

LiveCoreView provides APIs related to anchor PK. Since the UI for each PK play mode is different, LiveCoreView only provides APIs, and you need to implement the UI effect yourself.
Anchor PK Effect Preview
Dual-Anchor PK
Multi-Anchor PK






Notes:
The PK feature depends on the connection feature, so you need to be in an anchor connection scenario to initiate a PK request.
The following proactive invocation APIs are provided by LiveCoreView.
All callback methods refer to the callback methods in the BattleObserver object set by LiveCoreView.
You can use the following API to implement the anchor PK feature. Here, taking the PK between Anchor A and Anchor B as an example, the implementation is as follows.

Anchor a Initiating PK

Anchor A initiates a PK by calling requestBattle.
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
}
Anchor A can receive the PK acceptance callback through onBattleRequestAccept.

Anchor B Receives Battle Request

Anchor B receives the PK request callback through onBattleRequestReceived.
Android
iOS
Kotlin
java
override fun onBattleRequestReceived(battleId: String, inviterUser: BattleUser, invitee: BattleUser) {
Log.i(TAG, "Received anchor A's PK request:: $battleId")
}
@Override
public void onBattleRequestReceived(String battleId, BattleUser inviter, BattleUser invitee) {
Log.i(TAG, "Received anchor A's PK request: " + battleId)
}
Swift
extension ViewController: BattleObserver { //Replace with your actual class name
func onBattleRequestReceived(battleId: String, inviter: TUIBattleUser, invitee: TUIBattleUser) {
}
}
Anchor B responds to the PK request by calling respondToBattle.
Android
iOS
Kotlin
java
// Accept PK request
val battleId = "battleId"
liveCoreView.respondToBattle(battleId, true, null)
// Accept PK request
String battleId = "battleId";
liveCoreView.respondToBattle(battleId, true, null);
Swift
liveCoreView.respondToBattle(battleId: manager.battleState.battleId, isAccepted: false, onSuccess: { [weak self] in
}, onError: { _, _ in
})
Anchor A, Anchor B, and the audience in the room receive onBattleStarted, receiving the PK start notification.
Android
iOS
Kotlin
java
override fun onBattleStarted(battleInfo: BattleInfo) {
Log.i(TAG, "PK start callback")
}
@Override
public void onBattleStarted(BattleInfo battleInfo) {
Log.i(TAG, "Anchor connection room list updated")
}
Swift
extension ViewController: BattleObserver { //Replace with your actual class name
func onBattleStarted(battleInfo: TUIBattleInfo)) {
}
}

Exiting the PK Process

Natural end: When the PK time ends, you will receive the onBattleEnded callback.
Actively stop: Audience B calls terminateBattle and will exit the PK. Audience A will receive onUserExitBattle.
Android
iOS
kotlin
java
mLiveCoreView.terminateBattle(battleId, null)
mLiveCoreView.terminateBattle(battleId, null);
Swift
liveCoreView.terminateBattle(battleId: manager.battleState.battleId) {
} onError: { _, _ in
}