本场景需要集成火山引擎的RTC SDK 以及SUD MGP 互动小游戏接入平台,您需要在 RTC 的控制台开通服务,并下载对应的SUD MGP 的SDK,相应开通指南如下:
详细细节请参见 RTC服务开通指南
/** * 加入RTC房间并初始化参数 * @param token 加入 RTC 房间的 token * @param roomId 加入 RTC 房间的 id * @param userId 加入 RTC 房间的 用户id */ public static void joinRoom(String token, String roomId, String uid) { MLog.d("joinChannel", "token:" + token + " roomId:" + roomId + " uid:" + uid); leaveRoom(); if (mRTCVideo == null) { return; } mRTCRoom = mRTCVideo.createRTCRoom(roomId); mRTCRoom.setRTCRoomEventHandler(mRTCRoomEventHandler); UserInfo userInfo = new UserInfo(uid, null); RTCRoomConfig roomConfig = new RTCRoomConfig(ChannelProfile.CHANNEL_PROFILE_COMMUNICATION, true, true, true); mRTCRoom.joinRoom(token, userInfo, roomConfig); } /** * 初始化SudMGP sdk * * @param activity 游戏所在页面 * @param gameId 游戏id * @param code 令牌 */ private void initSdk(FragmentActivity activity, long gameId, String code) { String appId = getAppId(); String appKey = getAppKey(); // 初始化sdk SudMGP.initSDK(activity, appId, appKey, isTestEnv(), new ISudListenerInitSDK() { @Override public void onSuccess() { loadGame(activity, code, gameId); } @Override public void onFailure(int errCode, String errMsg) { if (isTestEnv()) { Toast.makeText(activity, "initSDK onFailure:" + errMsg + "(" + errCode + ")", Toast.LENGTH_LONG).show(); } delayLoadGame(activity, gameId); } }); } /** * 加载游戏 * APP和游戏的相互调用 * ISudFSTAPP:APP调用游戏的接口 * ISudFSMMG:游戏调APP的响应回调 * * @param activity 游戏所在页面 * @param code 登录令牌 * @param gameId 游戏id */ private void loadGame(FragmentActivity activity, String code, long gameId) { if (activity.isDestroyed() || !isRunning || gameId != playingGameId) { return; } // 给装饰类设置回调 sudFSMMGDecorator.setSudFSMMGListener(this); // 调用游戏sdk加载游戏 ISudFSTAPP iSudFSTAPP = SudMGP.loadMG(activity, getUserId(), gameRoomId, code, gameId, getLanguageCode(), sudFSMMGDecorator); // 如果返回空,则代表参数问题或者非主线程 if (iSudFSTAPP == null) { Toast.makeText(activity, "loadMG params error", Toast.LENGTH_LONG).show(); delayLoadGame(activity, gameId); return; } // APP调用游戏接口的装饰类设置 sudFSTAPPDecorator.setISudFSTAPP(iSudFSTAPP); // 获取游戏视图,将其抛回Activity进行展示 // Activity调用:gameContainer.addView(view, FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); gameView = iSudFSTAPP.getGameView(); onAddGameView(gameView); } /** * 处理游戏视图信息(游戏安全区) * 文档:https://docs.sud.tech/zh-CN/app/Client/API/ISudFSMMG/onGetGameViewInfo.html */ public void processOnGetGameViewInfo(View gameView, ISudFSMStateHandle handle) { //拿到游戏View的宽高 int gameViewWidth = gameView.getMeasuredWidth(); int gameViewHeight = gameView.getMeasuredHeight(); if (gameViewWidth > 0 && gameViewHeight > 0) { notifyGameViewInfo(handle, gameViewWidth, gameViewHeight); return; } //如果游戏View未加载完成,则监听加载完成时回调 gameView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { gameView.getViewTreeObserver().removeOnGlobalLayoutListener(this); int width = gameView.getMeasuredWidth(); int height = gameView.getMeasuredHeight(); notifyGameViewInfo(handle, width, height); } }); } /** 通知游戏,游戏视图信息 */ private void notifyGameViewInfo(ISudFSMStateHandle handle, int gameViewWidth, int gameViewHeight) { GameViewInfoModel gameViewInfoModel = new GameViewInfoModel(); gameViewInfoModel.ret_code = 0; // 游戏View大小 gameViewInfoModel.view_size.width = gameViewWidth; gameViewInfoModel.view_size.height = gameViewHeight; // 游戏安全操作区域 getGameRect(gameViewInfoModel); // 给游戏侧进行返回 String json = SudJsonUtils.toJson(gameViewInfoModel); handle.success(json); }
/** * 观众举手 */ public void onCSRaiseHandsMicEvent(RaiseHandsMicEvent event) { mChatRoomAdapter.updateRaiseHandStatus(event.userId); mIsSomeoneRaiseHand = true; updateUI(); } /** * 主动邀请上麦 */ public void onCSInviteMicEvent(InviteMicEvent event) { if (!GameRoomDataManger.isSelf(event.userId)) { return; } if (mDialog != null) { mDialog.dismiss(); } if (TextUtils.equals(event.userId, mUserId)) { CommonDialog dialog = new CommonDialog(this); dialog.setMessage("主播邀请您上麦"); dialog.setPositiveListener(v -> { GameRoomRtmClient rtmClient = GameRoomRtcManager.getRtmClient(); if (rtmClient != null) { rtmClient.confirmBecomeSpeaker(); } dialog.dismiss(); }); dialog.setNegativeListener(v -> dialog.dismiss()); dialog.show(); mDialog = dialog; } } /** * 收到上麦邀请 */ public void onCSInviteMicEvent(InviteMicEvent event) { if (!GameRoomDataManger.isSelf(event.userId)) { return; } if (mDialog != null) { mDialog.dismiss(); } if (TextUtils.equals(event.userId, mUserId)) { CommonDialog dialog = new CommonDialog(this); dialog.setMessage("主播邀请您上麦"); dialog.setPositiveListener(v -> { GameRoomRtmClient rtmClient = GameRoomRtcManager.getRtmClient(); if (rtmClient != null) { rtmClient.confirmBecomeSpeaker(); } dialog.dismiss(); }); dialog.setNegativeListener(v -> dialog.dismiss()); dialog.show(); mDialog = dialog; } } /** * 成功上麦通知 */ public void onCSMicOnEvent(MicOnEvent event) { if (TextUtils.equals(event.user.userId, mUserId)) { if (!hasAudioPermission()) { SafeToast.show("麦克风权限已关闭,请至设备设置页开启"); requestPermissions(Manifest.permission.RECORD_AUDIO); } showToast("您已经成功上麦", true); mIsSpeaker = true; mIsRaiseHand = false; switchMic(true); } mChatRoomAdapter.onUserRoleChange(event.user.userId, true); updateUI(); } /** * 下麦通知 */ public void onCSMicOffEvent(MicOffEvent event) { if (TextUtils.equals(event.userId, mUserId)) { showToast("您已回到听众席", true); mIsSpeaker = false; switchMic(false); } mChatRoomAdapter.onUserRoleChange(event.userId, false); updateUI(); }
功能点 | API |
---|---|
创建 RTCVideo 对象 | createRTCVideo |
创建 RTCRoom 对象 | createRTCRoom |
设置用户可见性 | setUserVisibility |
开启本地音频采集 | startAudioCapture |
加入RTC房间 | joinRoom |
离开房间 | leaveRoom |
关闭内部音频采集 | stopAudioCapture |
销毁 RTCRoom 对象 | destroy |
功能点 | 回调 |
---|---|
本地用户加入 RTC 房间回调 | onRoomStateChanged |
远端可见用户加入房间 | onUserJoined |