tencent cloud

文档反馈

主播 PK(TUILiveKit)

最后更新时间:2024-12-19 16:44:26
    说明:
    PK 上新,限时免费体验。

    功能介绍

    PK 功能是一种激烈而富有趣味的实时互动方式,专为主播和观众设计。它允许来自不同房间的主播进行实时对抗,增加了直播的竞争性和观赏性。TUILiveKit 的 PK 功能支持多达9位主播同时参与对战,为主播提供了一个展示才华、比拼魅力的平台,同时也为观众带来了紧张刺激的观看体验。无论是才艺比拼、知识问答还是游戏竞技,PK 功能都能为主播和观众创造更多的互动机会,激发观众的参与热情提升直播的趣味性和吸引力,从而为双方带来更多的惊喜和价值,推动直播内容的多样化发展。
    双人 PK 中
    双人 PK 结果
    多人 PK 中
    多人 PK 结果
    
    
    
    
    
    
    
    
    
    
    
    

    使用说明

    说明:
    在您准备发起 PK 或接受 PK 前,请确保您处于连线状态中。

    主播发起 PK

    点击 PK 按钮
    停止 PK 等待
    断开 PK
    
    
    
    
    
    
    
    
    

    主播接收 PK

    主播收到 PK 邀请
    主播接受 PK
    
    
    
    
    
    

    功能定制

    自定义 PK 等待倒计时样式

    如您需要自定义 PK 等待倒计时样式 ,请参考以下路径更改:
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/anchor/component/livestreaming/battle/
    
    ├── BattleCountdownBackView.java // PK 等待倒计时背景样式
    └── BattleCountdownView.java // PK 等待倒计时前景样式
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/View
    
    View
    ├── BattleCountDownBackgroundView.swift // PK 等待倒计时背景样式
    └── BattleCountDownView.swift // PK 等待倒计时前景样式

    自定义双人 PK 比分样式

    如您需要自定义双人 PK 比分样式 ,请参考以下路径更改:
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/common/battle/SingleBattleScoreView.java
    
    public class SingleBattleScoreView extends FrameLayout {
    ...
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/View/SingleBattleScoreView.swift
    
    class SingleBattleScoreView: UIView {
    ...
    func constructViewHierarchy() {
    // 视图层级构建
    }
    
    func activateConstraints() {
    // 视图layout布局
    }
    }

    自定义多人 PK 比分样式

    如您需要自定义多人 PK 比分样式 ,请参考以下路径更改:
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/common/battle/BattleMemberInfoView.java
    
    public class BattleMemberInfoView extends FrameLayout {
    ...
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/View/BattleMemberInfoView.swift
    
    class BattleMemberInfoView: UIView {
    ...
    func constructViewHierarchy() {
    // 视图层级构建
    }
    
    func activateConstraints() {
    // 视图layout布局
    }
    }

    自定义 PK 比分结果样式

    如您需要自定义 PK 比分结果样式 ,请参考以下路径更改:
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/common/battle/BattleInfoView.java
    
    public class BattleInfoView extends BasicView {
    ...
    private void showBattleResult(int type) {
    // PK结果展示
    }
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/View/BattleInfoView.swift
    
    class BattleInfoView: UIView {
    ...
    func showBattleResult(store: LiveStore) {
    // PK结果展示
    }
    }

    关键代码

    主播 PK

    TUILiveKit 主播 PK 功能主要是基于 LiveService 实现的,在LiveService中,您可通过 mTUIRoomEngine.getLiveBattleManager() 获取到 PK 管理类对象,进而调用 PK 相关 API 函数,实现 PK 功能。以主播 A 和主播 B 的 PK 为例,具体交互时序可参考下图。
    
    
    
    说明:
    邀请多人参加 PK 时,若被邀请方中有人接受了 PK,则仅 PK 发起方和 PK 邀请接受方和对应房间内观众会收到 onBattleStarted 回调。

    主播 A 发起 PK

    主播 A 通过调用requestBattle发起 PK,在参数 config中传入 PK 最大时长、是否需要邀请方回复同意/拒绝,在参数 userIdList中传入主播 B 的 userId,在参数 timeout 中传入 PK 邀请等待时长。
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/manager/controller/BattleController.java
    
    public void requestBattle(List<String> roomIdList, int timeout) {
    TUILiveBattleManager.BattleConfig config = new TUILiveBattleManager.BattleConfig();
    config.duration = BattleState.BATTLE_DURATION;
    config.needResponse = mBattleState.mNeedResponse;
    config.extensionInfo = "";
    mLiveService.requestBattle(config, roomIdList, timeout, new TUILiveBattleManager.BattleRequestCallback() {
    @Override
    public void onSuccess(TUILiveBattleManager.BattleInfo battleInfo,
    Map<String, TUILiveBattleManager.BattleCode> map) {
    mBattleState.mBattleId = battleInfo.battleId;
    mBattleState.mBattleConfig.copy(config);
    List<BattleState.BattleUser> sendRequests = mBattleState.mSentBattleRequests.get();
    for (Map.Entry<String, TUILiveBattleManager.BattleCode> entry : map.entrySet()) {
    String key = entry.getKey();
    TUILiveBattleManager.BattleCode code = entry.getValue();
    if (code == TUILiveBattleManager.BattleCode.SUCCESS) {
    for (ConnectionState.ConnectionUser user : mConnectionState.connectedUsers.get()) {
    if (TextUtils.equals(user.userId, key)) {
    sendRequests.add(new BattleState.BattleUser(user));
    break;
    }
    }
    } else {
    notifyToast(convertCodeToString(entry.getValue()));
    }
    }
    mBattleState.mSentBattleRequests.set(sendRequests);
    }
    
    @Override
    public void onError(TUICommonDefine.Error error, String s) {
    ErrorHandler.onError(error);
    mBattleState.mSentBattleRequests.clear();
    }
    });
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/API/LSBattleService.swift
    
    func requestBattle(config: TUIBattleConfig, userIdList: [String], timeout: TimeInterval) async throws -> (battleInfo: TUIBattleInfo, resultMap: [String : TUIBattleCode]) {
    return try await withCheckedThrowingContinuation { [weak self] continuation in
    guard let self = self else { return }
    battleManager.requestBattle(config: config, userIdList: userIdList, timeout: timeout) { battleInfo, resultMap in
    var battleResult: [String: TUIBattleCode] = [:]
    resultMap.forEach { (key: String, value: NSNumber) in
    battleResult[key] = TUIBattleCode(rawValue: value.intValue) ?? .unknown
    }
    continuation.resume(returning: (battleInfo, battleResult))
    } onError: { err, message in
    let error = InternalError(error: err, message: message)
    continuation.resume(throwing: error)
    }
    }
    }
    主播 A 可通过 onBattleRequestAccept 接收请求同意回调。

    主播收到 PK 请求

    主播 B 通过 onBattleRequestReceived 接收 PK 请求回调。
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/manager/observer/LiveBattleManagerObserver.java
    @Override
    public void onBattleRequestReceived(BattleInfo battleInfo, BattleUser inviter, BattleUser invitee) {
    LiveKitLog.info(mTag + " onBattleRequestReceived:[battleInfo:" + new Gson().toJson(battleInfo)
    + ", inviter:" + new Gson().toJson(inviter) + ", invitee:" + new Gson().toJson(invitee) + "]");
    mBattleController.onBattleRequestReceived(battleInfo, inviter);
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/Module/LSBattleManagerObserver
    func onBattleRequestReceived(battleInfo: TUIBattleInfo, inviter: TUIBattleUser, invitee: TUIBattleUser) {
    manager?.onBattleRequestReceived(battleInfo: battleInfo, inviter: inviter, invitee: invitee)
    }
    主播 B 通过调用 accept 接受 PK 请求。
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/manager/controller/BattleController.java
    public void accept() {
    mLiveService.acceptBattle(mBattleState.mBattleId, new TUIRoomDefine.ActionCallback() {
    @Override
    public void onSuccess() {
    
    }
    
    @Override
    public void onError(TUICommonDefine.Error error, String s) {
    
    }
    });
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/API/LSBattleService.swift
    
    func acceptBattle(battleId: String) async throws {
    return try await withCheckedThrowingContinuation { [weak self] continuation in
    guard let self = self else { return }
    battleManager.acceptBattle(battleId: battleId) {
    continuation.resume()
    } onError: { err, message in
    let error = InternalError(error: err, message: message)
    continuation.resume(throwing: error)
    }
    }
    }
    
    主播 A,B 以及房间内观众可通过 onBattleStarted 接收 PK 开始回调。
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/manager/observer/LiveBattleManagerObserver.java
    @Override
    public void onBattleStarted(BattleInfo battleInfo) {
    LiveKitLog.info(mTag + " onBattleStarted:[battleInfo:" + new Gson().toJson(battleInfo) + "]");
    mBattleController.onBattleStarted(battleInfo);
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/Module/LSBattleManagerObserver
    func onBattleStarted(battleInfo: TUIBattleInfo) {
    manager?.onBattleStarted(battleInfo: battleInfo)
    }

    主播退出 PK

    以主播 B 退出 PK 为例,交互时序可参考下图。
    
    
    
    说明:
    多人PK 时:
    当有主播退出 PK,则其余 PK 中主播和对应房间内观众会收到 onUserExitBattle 回调。
    当 PK 到达预设 PK 时间,则 PK 中主播和对应房间内观众会收到 onBattleEnded 回调。
    当 PK 中主播人数为2,且有主播退出 PK 时, PK 中主播和对应房间内观众会收到 onBattleEnded回调。
    主播 B 调用 exitBattle退出 PK。
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/manager/controller/BattleController.java
    public void exitBattle() {
    mLiveService.exitBattle(mBattleState.mBattleId, new TUIRoomDefine.ActionCallback() {
    @Override
    public void onSuccess() {
    mBattleState.mSentBattleRequests.clear();
    mBattleState.mBattledUsers.clear();
    removeBattleRequestReceived();
    }
    
    @Override
    public void onError(TUICommonDefine.Error error, String s) {
    
    }
    });
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/API/LSBattleService.swift
    func exitBattle(battleId: String) async throws {
    return try await withCheckedThrowingContinuation { [weak self] continuation in
    guard let self = self else { return }
    battleManager.exitBattle(battleId: battleId) {
    continuation.resume()
    } onError: { err, message in
    let error = InternalError(error: err, message: message)
    continuation.resume(throwing: error)
    }
    }
    }
    主播 A,B 以及房间内观众收到 onBattleEnded 回调,收到 PK 结束通知。
    Android
    iOS
    // 文件位置:tuilivekit/src/main/java/com/trtc/uikit/livekit/manager/observer/LiveBattleManagerObserver.java
    @Override
    public void onBattleEnded(BattleInfo battleInfo, BattleStoppedReason reason) {
    LiveKitLog.info(mTag + " onBattleEnded:[battleInfo:"
    + new Gson().toJson(battleInfo) + ", reason:" + reason + "]");
    mBattleController.onBattleEnded(battleInfo);
    }
    // 文件位置:iOS/TUILiveKit/Sources/LiveStream/HostBattle/Module/LSBattleManagerObserver
    
    
    func onBattleEnded(battleInfo: TUIBattleInfo, reason: TUIBattleStoppedReason) {
    manager?.onBattleEnded(battleInfo: battleInfo, reason: reason)
    }
    联系我们

    联系我们,为您的业务提供专属服务。

    技术支持

    如果你想寻求进一步的帮助,通过工单与我们进行联络。我们提供7x24的工单服务。

    7x24 电话支持