本场景需要集成火山引擎的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);
}
Java

/**
* 观众举手
*/
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();
}
Java| 功能点 | API |
|---|---|
| 创建 RTCVideo 对象 | createRTCVideo |
| 创建 RTCRoom 对象 | createRTCRoom |
| 设置用户可见性 | setUserVisibility |
| 开启本地音频采集 | startAudioCapture |
| 加入RTC房间 | joinRoom |
| 离开房间 | leaveRoom |
| 关闭内部音频采集 | stopAudioCapture |
| 销毁 RTCRoom 对象 | destroy |
| 功能点 | 回调 |
|---|---|
| 本地用户加入 RTC 房间回调 | onRoomStateChanged |
| 远端可见用户加入房间 | onUserJoined |