🎉

ライブ配信アプリにホストPK機能を追加する方法 | Androidチュートリアル

に公開

多くの人気ライブ配信プラットフォームでは、「PK」(「Player Kill」または「対戦バトル」の略)機能を導入しており、配信者同士が視聴者からのギフト数を競い、最も多くのギフトを獲得した側が勝利となります。場合によっては、ファンからの最後の数秒の大型ギフトによって、ほぼ決まっていた勝敗が覆ることもあり、視聴者にとっては非常にスリリングな体験となります。プラットフォームにとっては、PK機能は配信者に高度な権限を付与し、エンゲージメントを高める重要な仕組みです。

本記事では、PK機能をAndroidライブ配信アプリに統合する方法を解説します。

1.png

Tencent RTCのTUILiveKitコンポーネントを使用した既存のライブ配信環境をベースに進めます。

カスタム機能

カスタムバトル待機カウントダウンスタイル

バトル待機カウントダウンを独自にカスタマイズしたい場合は、以下のパスのコードを参照して変更してください。

// File location: tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/anchor/component/livestreaming/battle/

├── BattleCountdownBackView.java    // バトル待機カウントダウン背景スタイル
└── BattleCountdownView.java        // バトル待機カウントダウン前景スタイル

カスタム定義デュアルバトルスコアスタイル

デュアルバトルスコアを独自にカスタマイズしたい場合は、以下のパスのコードを参照して変更してください。

// File location: tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/common/battle/SingleBattleScoreView.java

public class SingleBattleScoreView extends FrameLayout {
    ...
}

カスタム定義マルチバトルスコアスタイル

マルチバトルスコアを独自にカスタマイズしたい場合は、以下のパスのコードを参照して変更してください。

// File location: tuilivekit/src/main/java/com/trtc/uikit/livekit/view/liveroom/view/common/battle/BattleMemberInfoView.java

public class BattleMemberInfoView extends FrameLayout {
    ...
}

カスタム定義バトルスコア結果スタイル

バトルスコア結果表示を独自にカスタマイズしたい場合は、以下のパスのコードを参照してください。

// File location: 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) {
        // バトル結果表示
    }
}

主要コード

配信者バトル

TUILiveKit の配信者バトル機能は主に BattleService に基づいており、store.serviceCenter.battleService を通じてバトル管理オブジェクトを取得し、関連するバトルAPIを呼び出すことでバトル機能を実装します。たとえば、配信者Aと配信者B間のやり取りにおいては、下記のシーケンス図を参考にしてください。

2.png

配信者Aがバトルを開始

配信者Aは requestBattle を呼び出してバトルを開始します。config にバトルの最大継続時間を渡し、招待者が承諾/拒否の返答が必要かどうかを指定し、招待する相手である配信者Bの userId をuserIdListに設定、そしてバトル招待待機時間を timeout に設定します。

// File location: 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();
        }
    });
}

配信者Aは、onBattleRequestAccept を介してリクエスト受諾のコールバックを受け取ります。

配信者がバトルリクエストを受信

配信者Bは、onBattleRequestReceived を通じてバトルリクエストのコールバックを受け取り、acceptBattle を呼び出すことでリクエストを受諾します。

// File location: 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);
}
// File location: 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) {

       }
   });
}

配信者A、B、およびルーム内の視聴者は onBattleStarted を通じてバトル開始コールバックを受け取ります。

// File location: 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);
}

配信者がバトルから退出

例として、配信者Bがバトルを退出する場合のシーケンス図は下記を参照してください。

3.png

配信者Bは exitBattle を呼び出すことでバトルを退出します。

// File location: 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) {

        }
    });
}

配信者A、B、およびルーム内の視聴者は onBattleEnded を通じてバトル終了のコールバックと通知を受け取ります。

// File location: 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);
}

これで、ライブ配信アプリに配信者のPK機能を追加できます!詳しい機能については、ドキュメント をご参照ください。

私はSusieと申します。ライター兼メディアサービスのプロダクトマネージャーとして、世界中のスタートアップと協力し、SDKやAPIを活用したリアルタイムコミュニケーションソリューションの構築を支援しています。

アプリにフェイスフィルターやその他の特殊効果機能を実装したい場合は、ぜひお問い合わせください

Discussion